惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
博客园_首页
H
Help Net Security
WordPress大学
WordPress大学
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
B
Blog
I
InfoQ
SecWiki News
SecWiki News
T
Tailwind CSS Blog
Spread Privacy
Spread Privacy
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
Vulnerabilities – Threatpost
N
Netflix TechBlog - Medium
P
Palo Alto Networks Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Vercel News
Vercel News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
Kaspersky official blog
M
MIT News - Artificial intelligence
S
Schneier on Security
T
Threat Research - Cisco Blogs
F
Fortinet All Blogs
Cyberwarzone
Cyberwarzone
Scott Helme
Scott Helme
aimingoo的专栏
aimingoo的专栏
Martin Fowler
Martin Fowler
MyScale Blog
MyScale Blog
The Cloudflare Blog
Recent Announcements
Recent Announcements
Security Latest
Security Latest
G
GRAHAM CLULEY
IT之家
IT之家
Y
Y Combinator Blog
The Last Watchdog
The Last Watchdog
腾讯CDC
Google DeepMind News
Google DeepMind News
V
V2EX
S
Securelist
TaoSecurity Blog
TaoSecurity Blog
B
Blog RSS Feed
S
SegmentFault 最新的问题
博客园 - 叶小钗
P
Proofpoint News Feed
云风的 BLOG
云风的 BLOG
Project Zero
Project Zero
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
F
Full Disclosure

博客园 - eygneph

Valve新员工手册 啪啪英雄上线了 阿聪 创意不值钱 游戏应该是怎样的 GDC China 2011见闻与感悟 iOS 4 X iPhone 4 == INF 不拷贝 "...为他们的产品痴迷,不是有兴趣,不是了解,而是痴迷" 分享:Castle Crasher制作人Tom Fulp的一篇开发日记 中国创业者面临的5个问题 对cocos2d iphone的朝向处理的改进 写在30岁之前 文化部vs新闻出版署 Round 2 关于勇气 生产力、生产工具和生产关系 Master Chief... PIX 千万别装ie8
支持iCloud简记
eygneph · 2012-07-07 · via 博客园 - eygneph

苹果iOS上的iCloud对于应用有几层意义:

1、App可以像以前和iTunes同步时一样,把App数据备份到iCloud上。这部分功能是所谓out-of-box, just works,无需app开发者进行任何支持的。 

2、App开发者可以利用iCloud提供的接口将应用的文档放到云端。这样文档不仅是本地保存,还在云端拥有一份拷贝。在多个设备都使用同一app时,就可以通过iCloud来同步成最新的文档。这方面和代码版本控制软件比较类似。但和上一点不同,app开发者必须使用iCloud API进行支持。

3、这点其实是(2)的扩展。iCloud提供了云端文档存储空间,也就意味着可以和其他app共享文档。所以app开发者可以使用iCloud API将iCloud当作一种网络存储和分享的服务。

这里主要讲一下One Tap Hero里支持的功能(2)。

首先要初始化iCloud的支持。在iOS 5.0之前没有iCloud支持,而用户也可能没有登陆iCloud或者禁用iCloud文档同步。所以这一步必须最先做掉。基本上在[UIApplication applicationDidFinishLaunching: options:]中,加入这些实现即可:

- (void)checkiCloudAvailability

{

   if ([[NSFileManager defaultManager] respondsToSelector:@selector(URLForUbiquityContainerIdentifier:)]) 

   {

       // get the global concurrent queue

       dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

       // get the ubiquity container asynchronously

       dispatch_async(globalQueue, ^{

          NSURL *container = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];

          // update you app on the main thread with the result

          dispatch_async(dispatch_get_main_queue(), ^{

             [self updateWithUbiquityContainer:container];

          });

       });

   }

}

- (void)updateWithUbiquityContainer:(NSURL*)container

{

   if (container)

   {

      // continue with iCloud-specific setup

      NSLog(@"iCloud access at %@", container);

      self.ubiquityContainer = container;

      if (icloud_ready_callback)

      {

        icloud_ready_callback(container);

      }

   }

   else

   {

      // iCloud is not available

      // continue with non-iCloud setup

      NSLog(@"No iCloud access");

      self.ubiquityContainer = nil;

   }

其次我们要适应一下iCloud的文件系统接口。我们不能用传统的fopen或者std::out来操作文件,而是要使用另一套API来操作。这套API为何要这样设计我不清楚,但应该是受到spotlight以及网络搜索引擎的影响。 

最后我们要适应的是几乎全异步的API。由于网络延迟,iCloud API被设计成大量使用ObjC block的形式。这点和Game Center很像。

没有了fopen,我们打开文件的操作就要分为3个步骤:

a、使用NSMetaQuery和NSPredicate找到云端的文件(异步)。

b、在NSNotificationCenter注册NSMetadataQueryDidFinishGatheringNotification和NSMetadataQueryDidUpdateNotification事件监听(异步)

c、在事件监听函数中,使用UIDocument(或自己实现NSFilePresenter)打开或创建文件(异步),打开函数为

-(void) openWithCompletionHandler:^(BOOL success) ();

创建函数其实和存盘函数一样,为

-(void) saveToURL: forSaveOperation: completionHandler:^(BOOL success) ();

但其中forSaveOperation参数必须传UIDocumentSaveForCreating。

创建或打开文件之后,我们对文档的操作就和平常类似,通过重写UIDocument的

- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outError 

- (id)contentsForType:(NSString *)typeName error:(NSError **)outError 

来分别定义文档内容的读、写。而依旧通过UIDocument的public接口

-(void) openWithCompletionHandler:^(BOOL success) () ;

-(void) saveToURL: forSaveOperation: completionHandler:^(BOOL success) ();

来实际调用读、写操作。

到此为止,iCloud文件的创建、打开、读、写都已完成。但尚缺最重要的一步,也是最麻烦的一步——就是异常处理。 

云服务必须处理异常和版本冲突的问题,这是不可避免的。所以iCloud提供了NSNotificationCenter里的UIDocumentStateChangedNotification来处理UIDocument的异常。所以通常我们都在正常查询到文件之后,注册这个事件的处理函数。

在这个处理函数中,我们有2个必须知道的文档状态:UIDocumentStateNormal和UIDocumentStateInConflict

UIDocumentStateInConflict意味着iCloud中有多个冲突的版本,必须通过NSFileVersion把冲突版本的resolved属性都置为YES,iCloud才会转变UIDocumentState。而具体如何解决冲突,则按每个app不同而不同。

UIDocumentStateNormal意味着iCloud文档状态正常。通常情况下,以及解决冲突后,文档都会是UIDocumentStateNormal状态。

至此iCloud的基本支持已完成。下面说一些实现陷阱和遇到的问题。 

1、iCloud本身没有提供DAG模型的版本管理,必须用户自己实现。这点上One Tap Hero没有做,所以在处理同步冲突时,只能merge一些过关数据(如星星、最高分等),而无法同步金币等数值(无版本控制则这类数值的合并无正确的语义)。

2、iCloud在一些情况下很容易卡死,特别是API调用不合理的情况下。解决方法是换文件或reset device。例如在UIDocumentStateNormal时调用[UIDocument saveToURL]这种IO操作,似乎就很容易出现iCloud卡死的情况。这点不知是否会在iOS 6.0中加以改进。