自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

CoreData遇見(jiàn)iCloud的那些坑

移動(dòng)開(kāi)發(fā) iOS
盡管蘋(píng)果把iCloud與CoreData之間的完美配合吹的天花亂墜,但在iOS7之前,想用iCloud同步CoreData數(shù)據(jù)簡(jiǎn)直就是噩夢(mèng),蘋(píng)果自己也承認(rèn)了之前的諸多bug和不穩(wěn)定性,這讓蘋(píng)果不得不重新站出來(lái)說(shuō)他們的工程師已經(jīng)在iOS7中修復(fù)了bug,增強(qiáng)了體驗(yàn),balabala,關(guān)鍵是對(duì)于程序員來(lái)說(shuō),將iCloud集成到CoreData變得無(wú)比簡(jiǎn)單。

盡管蘋(píng)果把iCloud與CoreData之間的***配合吹的天花亂墜,但在iOS7之前,想用iCloud同步CoreData數(shù)據(jù)簡(jiǎn)直就是噩夢(mèng),蘋(píng)果自己也承認(rèn)了之前的諸多bug和不穩(wěn)定性,這讓蘋(píng)果不得不重新站出來(lái)說(shuō)他們的工程師已經(jīng)在iOS7中修復(fù)了bug,增強(qiáng)了體驗(yàn),balabala,關(guān)鍵是對(duì)于程序員來(lái)說(shuō),將iCloud集成到CoreData變得無(wú)比簡(jiǎn)單。

在蘋(píng)果的官方文檔中已經(jīng)把配置工作敘述的很明確了,簡(jiǎn)單地說(shuō)可以總結(jié)為三步:

在iTunes Connect創(chuàng)建App ID,在Xcode中找到項(xiàng)目的Capabilities標(biāo)簽并開(kāi)啟iCloud選項(xiàng)。這會(huì)為你創(chuàng)建一個(gè)默認(rèn)的iCloud容器,名字格式為“com.XXX.yourAppID”

添加NSPersistentStore時(shí)向options參數(shù)傳入一個(gè)持久存儲(chǔ)的名稱(chēng),自己起一個(gè)就行,示例代碼如下:

  1. NSDictionary *storeOptions = 
  2.     @{NSPersistentStoreUbiquitousContentNameKey: @"MyAppCloudStore"}; 
  3. NSPersistentStore *store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType 
  4.                                                      configuration:nil 
  5.                                                                URL:storeURL 
  6.                                                            options:storeOptions 
  7.                                                              error:&error]; 

對(duì)NSPersistentStoreCoordinatorStoresWillChangeNotification,NSPersistentStoreCoordinatorStoresDidChangeNotification和NSPersistentStoreDidImportUbiquitousContentChangesNotification這三個(gè)通知進(jìn)行注冊(cè)以便接收通知后對(duì)數(shù)據(jù)進(jìn)行處理。***用NSNotificationCenter的addObserverForName:object:queue:usingBlock:方法來(lái)使邏輯更加明確,代碼更緊湊。

***貼上Swift實(shí)現(xiàn)persistentStoreCoordinator的代碼:

  1. var persistentStoreCoordinator: NSPersistentStoreCoordinator! { 
  2.    if _persistentStoreCoordinator == nil { 
  3.        let storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("HardChoice.sqlite"
  4.        var error: NSError? = nil 
  5.        _persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) 
  6.          
  7.        // iCloud notification subscriptions 
  8.        let dc = NSNotificationCenter.defaultCenter() 
  9.        dc.addObserverForName(NSPersistentStoreCoordinatorStoresWillChangeNotification, object: self.persistentStoreCoordinator, queue: NSOperationQueue.mainQueue(), usingBlock: { (note) -> Void in 
  10.            self.managedObjectContext.performBlock({ () -> Void in 
  11.                var error: NSError? = nil 
  12.                if self.managedObjectContext.hasChanges { 
  13.                    if !self.managedObjectContext.save(&error) { 
  14.                        println(error?.description) 
  15.                    } 
  16.                } 
  17.                self.managedObjectContext.reset() 
  18.            }) 
  19.        }) 
  20.        dc.addObserverForName(NSPersistentStoreCoordinatorStoresDidChangeNotification, object: self.persistentStoreCoordinator, queue: NSOperationQueue.mainQueue(), usingBlock: { (note) -> Void in 
  21.            self.managedObjectContext.performBlock({ () -> Void in 
  22.                var error: NSError? = nil 
  23.                if self.managedObjectContext.hasChanges { 
  24.                    if !self.managedObjectContext.save(&error) { 
  25.                        println(error?.description) 
  26.                    } 
  27.                } 
  28.            }) 
  29.        }) 
  30.        dc.addObserverForName(NSPersistentStoreDidImportUbiquitousContentChangesNotification, object: self.persistentStoreCoordinator, queue: NSOperationQueue.mainQueue(), usingBlock: { (note) -> Void in 
  31.            self.managedObjectContext.performBlock({ () -> Void in 
  32.                self.managedObjectContext.mergeChangesFromContextDidSaveNotification(note) 
  33.            }) 
  34.        }) 
  35.          
  36.        if _persistentStoreCoordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: [NSPersistentStoreUbiquitousContentNameKey:"MyAppCloudStore"], error: &error) == nil { 
  37.            println("Unresolved error \(error), \(error?.userInfo)"
  38.            abort() 
  39.        } 
  40.    } 
  41.    return _persistentStoreCoordinator! 
  42. var _persistentStoreCoordinator: NSPersistentStoreCoordinator? = nil 

當(dāng)然你也可以用lazy關(guān)鍵字同樣來(lái)實(shí)現(xiàn)persistentStoreCoordinator屬性的惰性加載。

已經(jīng)有人將整套CoreData集成iCloud的邏輯抽象出來(lái),比如iCloudCoreDataStack。完全不需要再用宣稱(chēng)能讓CoreData與iCloud搭配更簡(jiǎn)單的第三方庫(kù)了,因?yàn)樵趇OS7中蘋(píng)果的確讓它簡(jiǎn)單至極了。

然而當(dāng)Xcode6和iOS8襲來(lái),一個(gè)個(gè)坑爭(zhēng)先恐后的出現(xiàn)了。

首先是iCloud Drive,它與之前iCloud有沖突。如升級(jí),請(qǐng)徹底,讓測(cè)試機(jī)器都升級(jí)iCloud Drive。

然后是Xcode6中開(kāi)啟Capabilities標(biāo)簽的iCloud選項(xiàng)卡后,如下的場(chǎng)景簡(jiǎn)直是臥槽:

 

該怎么選怎么選???!我只能說(shuō)按照上圖這么選就對(duì)了。順便說(shuō)一下iCloud默認(rèn)容器名稱(chēng)格式已經(jīng)變成了“iCloud.com.yourname.yourAppID”,其實(shí)這也不太準(zhǔn)確,官方稱(chēng)作“iCloud.$(CFBundleIdentifier)”,后面的美元號(hào)所指的變量就是General中Identity一欄的“Bundle Identifier”值。此外“Key-value storage”和“CloudKit”選項(xiàng)選不選都可以,但“iCloud Documents”一定要勾選,否則是無(wú)法同步CoreData數(shù)據(jù)的。

PS:CloudKit是蘋(píng)果***推出的基于iCloud的一個(gè)云端數(shù)據(jù)存儲(chǔ)服務(wù),提供了低成本的云存儲(chǔ)并能作為一個(gè)后端服務(wù)通過(guò)用戶(hù)們的iCloud賬號(hào)分享其應(yīng)用數(shù)據(jù)。

接下來(lái)是時(shí)候檢查我們是否成功添加了iCloud容器,可以在applicationDidFinishLaunchingWithOptions方法中嘗試獲取容器的URL來(lái)判斷:

  1. let containerURL = NSFileManager.defaultManager().URLForUbiquityContainerIdentifier("iCloud.com.yulingtianxia.HardChoice"
  2. if containerURL != nil { 
  3.   println("success:\(containerURL)"
  4. else
  5.   println("URL=nil"

如果之前沒(méi)有在Capabilities標(biāo)簽的iCloud中勾選“iCloud Documents”,“URLForUbiquityContainerIdentifier”方法會(huì)始終返回nil。來(lái)看看蘋(píng)果開(kāi)發(fā)者論壇上關(guān)于這個(gè)話(huà)題的討論吧

PS:官方文檔不建議在主線(xiàn)程使用URLForUbiquityContainerIdentifier方法,因?yàn)樗赡苄枰^長(zhǎng)時(shí)間來(lái)返回URL而阻塞主線(xiàn)程。這里只是為了測(cè)試使用。

然而判斷iCloud是否真的與CoreData工作正常,蘋(píng)果的官方文檔寫(xiě)的很詳細(xì):Using the iCloud Debugging Tools

當(dāng)我興致沖沖的打開(kāi)Xcode中的debug navigator,點(diǎn)擊左邊的iCloud查看狀態(tài)時(shí),被眼前的一切驚呆了:

 

“iCloud Usage”告訴我狀態(tài)不可用,然而右下角的日志中Using local storage已經(jīng)從1變成了0,也就是證明了我的APP(HardChoice)已經(jīng)從CoreData使用本地持久倉(cāng)庫(kù)轉(zhuǎn)移到了使用“iCloud-enabled”持久倉(cāng)庫(kù)。“Transfer Activity”中柱狀圖更是顯示從iCloud下載了數(shù)據(jù)。而這其實(shí)應(yīng)該是Xcode6的一個(gè)bug,有人已經(jīng)在蘋(píng)果開(kāi)發(fā)者論壇討論了。

根據(jù)我的測(cè)試,只勾選“Key-value storage”或者在模擬器上調(diào)試時(shí),“iCloud Usage”都不會(huì)出現(xiàn)。而即使“iCloud Usage”出現(xiàn)了,狀態(tài)也始終是Disabled,“Transfer Activity”也不是很靈敏。唯獨(dú)只能相信CoreData的log了。

但我們可以查看“My Mac”的“iCloud Usage”而不是iPhone的“iCloud Usage”:

 

在“Documents”一欄中可以看出我在兩個(gè)設(shè)備間同步了數(shù)據(jù),“mobile”后面跟著的是我的設(shè)備編號(hào)。展開(kāi)數(shù)據(jù)可以看到更詳細(xì)的同步記錄:

雖然通過(guò)“My Mac”可以看到iCloud與CoreData的數(shù)據(jù)同步記錄,但是在Xcode6.1.1中“Documents”的顯示不是很正常,在***的Xcode6.2beta版中雖然修復(fù)了“Documents”的顯示問(wèn)題,但“iCloud Usage”的種種bug依然存在。

***,確保網(wǎng)絡(luò)通常。我在中軟實(shí)訓(xùn)一個(gè)月時(shí),網(wǎng)絡(luò)奇差,或是屏蔽了iCloud,一直沒(méi)能調(diào)試成功。

貼一張HardChoice同步成功的測(cè)試圖,因?yàn)槲沂怯肧wift寫(xiě)的這個(gè)Demo,所以喜歡用Swift的可以直接把我的那部分源碼粘過(guò)去用:

 

責(zé)任編輯:chenqingxiang 來(lái)源: 玉令天下的博客
相關(guān)推薦

2020-04-21 15:18:11

財(cái)務(wù)信息化

2017-07-19 14:26:01

前端JavaScriptDOM

2021-09-07 14:35:48

DevSecOps開(kāi)源項(xiàng)目

2022-05-15 08:13:50

Mysql數(shù)據(jù)庫(kù)Mycat

2013-04-12 15:59:33

2020-03-12 15:00:44

JavaSpring依賴(lài)

2017-03-31 10:27:08

推送服務(wù)移動(dòng)

2017-07-06 11:41:48

CIOIT技術(shù)

2020-05-28 16:15:50

HTTP暗坑前端

2015-07-27 09:25:45

core data

2011-12-15 09:45:21

PhoneGap

2011-12-22 19:57:38

PhoneGap

2015-04-13 17:39:11

移動(dòng)IM開(kāi)發(fā)

2017-08-28 15:30:49

Android編碼器編碼

2018-02-06 08:36:02

簡(jiǎn)歷程序員面試

2017-08-04 17:07:32

JavaArraysList

2016-12-28 13:19:08

Android開(kāi)發(fā)坑和小技巧

2018-07-05 06:02:38

綜合布線(xiàn)弱電動(dòng)力線(xiàn)

2020-06-11 14:33:10

MacBookLinux軟件

2018-03-30 09:21:30

程序員網(wǎng)絡(luò)招聘
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)