精品国产一级在线观看,国产成人综合久久精品亚洲,免费一级欧美大片在线观看

當前位置:云計算技術專區 → 正文

CoreData遇見iCloud的那些坑

責任編輯:editor005 |來源:企業網D1Net  2015-03-12 14:33:55 本文摘自:玉令天下的博客

盡管蘋果把iCloud與CoreData之間的完美配合吹的天花亂墜,但在iOS7之前,想用iCloud同步CoreData數據簡直就是噩夢,蘋果自己也承認了之前的諸多bug和不穩定性,這讓蘋果不得不重新站出來說他們的工程師已經在iOS7中修復了bug,增強了體驗,balabala,關鍵是對于程序員來說,將iCloud集成到CoreData變得無比簡單。

在蘋果的官方文檔中已經把配置工作敘述的很明確了,簡單地說可以總結為三步:

在iTunes Connect創建App ID,在Xcode中找到項目的Capabilities標簽并開啟iCloud選項。這會為你創建一個默認的iCloud容器,名字格式為“com.XXX.yourAppID”

添加NSPersistentStore時向options參數傳入一個持久存儲的名稱,自己起一個就行,示例代碼如下:

NSDictionary *storeOptions =   @{NSPersistentStoreUbiquitousContentNameKey: @"MyAppCloudStore"}; NSPersistentStore *store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType                           configuration:nil                                URL:storeURL                              options:storeOptions                               error:&error];

對NSPersistentStoreCoordinatorStoresWillChangeNotification,NSPersistentStoreCoordinatorStoresDidChangeNotification和NSPersistentStoreDidImportUbiquitousContentChangesNotification這三個通知進行注冊以便接收通知后對數據進行處理。最好用NSNotificationCenter的addObserverForName:object:queue:usingBlock:方法來使邏輯更加明確,代碼更緊湊。

最后貼上Swift實現persistentStoreCoordinator的代碼:

var persistentStoreCoordinator: NSPersistentStoreCoordinator! {   if _persistentStoreCoordinator == nil {     let storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("HardChoice.sqlite")     var error: NSError? = nil     _persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)     // iCloud notification subscriptions     let dc = NSNotificationCenter.defaultCenter()     dc.addObserverForName(NSPersistentStoreCoordinatorStoresWillChangeNotification, object: self.persistentStoreCoordinator, queue: NSOperationQueue.mainQueue(), usingBlock: { (note) -> Void in       self.managedObjectContext.performBlock({ -> Void in         var error: NSError? = nil         if self.managedObjectContext.hasChanges {           if !self.managedObjectContext.save(&error) {             println(error?.description)         self.managedObjectContext.reset()     dc.addObserverForName(NSPersistentStoreCoordinatorStoresDidChangeNotification, object: self.persistentStoreCoordinator, queue: NSOperationQueue.mainQueue(), usingBlock: { (note) -> Void in       self.managedObjectContext.performBlock({ -> Void in         var error: NSError? = nil         if self.managedObjectContext.hasChanges {           if !self.managedObjectContext.save(&error) {             println(error?.description)     dc.addObserverForName(NSPersistentStoreDidImportUbiquitousContentChangesNotification, object: self.persistentStoreCoordinator, queue: NSOperationQueue.mainQueue(), usingBlock: { (note) -> Void in       self.managedObjectContext.performBlock({ -> Void in         self.managedObjectContext.mergeChangesFromContextDidSaveNotification(note)     if _persistentStoreCoordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: [NSPersistentStoreUbiquitousContentNameKey:"MyAppCloudStore"], error: &error) == nil {       println("Unresolved error (error), (error?.userInfo)")       abort()   return _persistentStoreCoordinator! var _persistentStoreCoordinator: NSPersistentStoreCoordinator? = nil

當然你也可以用lazy關鍵字同樣來實現persistentStoreCoordinator屬性的惰性加載。

已經有人將整套CoreData集成iCloud的邏輯抽象出來,比如iCloudCoreDataStack。完全不需要再用宣稱能讓CoreData與iCloud搭配更簡單的第三方庫了,因為在iOS7中蘋果的確讓它簡單至極了。

然而當Xcode6和iOS8襲來,一個個坑爭先恐后的出現了。

首先是iCloud Drive,它與之前iCloud有沖突。如升級,請徹底,讓測試機器都升級iCloud Drive。

然后是Xcode6中開啟Capabilities標簽的iCloud選項卡后,如下的場景簡直是臥槽:

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

PS:CloudKit是蘋果最新推出的基于iCloud的一個云端數據存儲服務,提供了低成本的云存儲并能作為一個后端服務通過用戶們的iCloud賬號分享其應用數據。

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

let containerURL = NSFileManager.defaultManager().URLForUbiquityContainerIdentifier("iCloud.com.yulingtianxia.HardChoice") if containerURL != nil {  println("success:(containerURL)") } else{  println("URL=nil") }

如果之前沒有在Capabilities標簽的iCloud中勾選“iCloud Documents”,“URLForUbiquityContainerIdentifier”方法會始終返回nil。來看看蘋果開發者論壇上關于這個話題的討論吧

PS:官方文檔不建議在主線程使用URLForUbiquityContainerIdentifier方法,因為它可能需要較長時間來返回URL而阻塞主線程。這里只是為了測試使用。

然而判斷iCloud是否真的與CoreData工作正常,蘋果的官方文檔寫的很詳細:Using the iCloud Debugging Tools

當我興致沖沖的打開Xcode中的debug navigator,點擊左邊的iCloud查看狀態時,被眼前的一切驚呆了:

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

根據我的測試,只勾選“Key-value storage”或者在模擬器上調試時,“iCloud Usage”都不會出現。而即使“iCloud Usage”出現了,狀態也始終是Disabled,“Transfer Activity”也不是很靈敏。唯獨只能相信CoreData的log了。

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

在“Documents”一欄中可以看出我在兩個設備間同步了數據,“mobile”后面跟著的是我的設備編號。展開數據可以看到更詳細的同步記錄:

雖然通過“My Mac”可以看到iCloud與CoreData的數據同步記錄,但是在Xcode6.1.1中“Documents”的顯示不是很正常,在最新的Xcode6.2beta版中雖然修復了“Documents”的顯示問題,但“iCloud Usage”的種種bug依然存在。

最后,確保網絡通常。我在中軟實訓一個月時,網絡奇差,或是屏蔽了iCloud,一直沒能調試成功。

貼一張HardChoice同步成功的測試圖,因為我是用Swift寫的這個Demo,所以喜歡用Swift的可以直接把我的那部分源碼粘過去用:

關鍵字:CoreDataiCloud

本文摘自:玉令天下的博客

x CoreData遇見iCloud的那些坑 掃一掃
分享本文到朋友圈
當前位置:云計算技術專區 → 正文

CoreData遇見iCloud的那些坑

責任編輯:editor005 |來源:企業網D1Net  2015-03-12 14:33:55 本文摘自:玉令天下的博客

盡管蘋果把iCloud與CoreData之間的完美配合吹的天花亂墜,但在iOS7之前,想用iCloud同步CoreData數據簡直就是噩夢,蘋果自己也承認了之前的諸多bug和不穩定性,這讓蘋果不得不重新站出來說他們的工程師已經在iOS7中修復了bug,增強了體驗,balabala,關鍵是對于程序員來說,將iCloud集成到CoreData變得無比簡單。

在蘋果的官方文檔中已經把配置工作敘述的很明確了,簡單地說可以總結為三步:

在iTunes Connect創建App ID,在Xcode中找到項目的Capabilities標簽并開啟iCloud選項。這會為你創建一個默認的iCloud容器,名字格式為“com.XXX.yourAppID”

添加NSPersistentStore時向options參數傳入一個持久存儲的名稱,自己起一個就行,示例代碼如下:

NSDictionary *storeOptions =   @{NSPersistentStoreUbiquitousContentNameKey: @"MyAppCloudStore"}; NSPersistentStore *store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType                           configuration:nil                                URL:storeURL                              options:storeOptions                               error:&error];

對NSPersistentStoreCoordinatorStoresWillChangeNotification,NSPersistentStoreCoordinatorStoresDidChangeNotification和NSPersistentStoreDidImportUbiquitousContentChangesNotification這三個通知進行注冊以便接收通知后對數據進行處理。最好用NSNotificationCenter的addObserverForName:object:queue:usingBlock:方法來使邏輯更加明確,代碼更緊湊。

最后貼上Swift實現persistentStoreCoordinator的代碼:

var persistentStoreCoordinator: NSPersistentStoreCoordinator! {   if _persistentStoreCoordinator == nil {     let storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("HardChoice.sqlite")     var error: NSError? = nil     _persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)     // iCloud notification subscriptions     let dc = NSNotificationCenter.defaultCenter()     dc.addObserverForName(NSPersistentStoreCoordinatorStoresWillChangeNotification, object: self.persistentStoreCoordinator, queue: NSOperationQueue.mainQueue(), usingBlock: { (note) -> Void in       self.managedObjectContext.performBlock({ -> Void in         var error: NSError? = nil         if self.managedObjectContext.hasChanges {           if !self.managedObjectContext.save(&error) {             println(error?.description)         self.managedObjectContext.reset()     dc.addObserverForName(NSPersistentStoreCoordinatorStoresDidChangeNotification, object: self.persistentStoreCoordinator, queue: NSOperationQueue.mainQueue(), usingBlock: { (note) -> Void in       self.managedObjectContext.performBlock({ -> Void in         var error: NSError? = nil         if self.managedObjectContext.hasChanges {           if !self.managedObjectContext.save(&error) {             println(error?.description)     dc.addObserverForName(NSPersistentStoreDidImportUbiquitousContentChangesNotification, object: self.persistentStoreCoordinator, queue: NSOperationQueue.mainQueue(), usingBlock: { (note) -> Void in       self.managedObjectContext.performBlock({ -> Void in         self.managedObjectContext.mergeChangesFromContextDidSaveNotification(note)     if _persistentStoreCoordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: [NSPersistentStoreUbiquitousContentNameKey:"MyAppCloudStore"], error: &error) == nil {       println("Unresolved error (error), (error?.userInfo)")       abort()   return _persistentStoreCoordinator! var _persistentStoreCoordinator: NSPersistentStoreCoordinator? = nil

當然你也可以用lazy關鍵字同樣來實現persistentStoreCoordinator屬性的惰性加載。

已經有人將整套CoreData集成iCloud的邏輯抽象出來,比如iCloudCoreDataStack。完全不需要再用宣稱能讓CoreData與iCloud搭配更簡單的第三方庫了,因為在iOS7中蘋果的確讓它簡單至極了。

然而當Xcode6和iOS8襲來,一個個坑爭先恐后的出現了。

首先是iCloud Drive,它與之前iCloud有沖突。如升級,請徹底,讓測試機器都升級iCloud Drive。

然后是Xcode6中開啟Capabilities標簽的iCloud選項卡后,如下的場景簡直是臥槽:

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

PS:CloudKit是蘋果最新推出的基于iCloud的一個云端數據存儲服務,提供了低成本的云存儲并能作為一個后端服務通過用戶們的iCloud賬號分享其應用數據。

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

let containerURL = NSFileManager.defaultManager().URLForUbiquityContainerIdentifier("iCloud.com.yulingtianxia.HardChoice") if containerURL != nil {  println("success:(containerURL)") } else{  println("URL=nil") }

如果之前沒有在Capabilities標簽的iCloud中勾選“iCloud Documents”,“URLForUbiquityContainerIdentifier”方法會始終返回nil。來看看蘋果開發者論壇上關于這個話題的討論吧

PS:官方文檔不建議在主線程使用URLForUbiquityContainerIdentifier方法,因為它可能需要較長時間來返回URL而阻塞主線程。這里只是為了測試使用。

然而判斷iCloud是否真的與CoreData工作正常,蘋果的官方文檔寫的很詳細:Using the iCloud Debugging Tools

當我興致沖沖的打開Xcode中的debug navigator,點擊左邊的iCloud查看狀態時,被眼前的一切驚呆了:

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

根據我的測試,只勾選“Key-value storage”或者在模擬器上調試時,“iCloud Usage”都不會出現。而即使“iCloud Usage”出現了,狀態也始終是Disabled,“Transfer Activity”也不是很靈敏。唯獨只能相信CoreData的log了。

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

在“Documents”一欄中可以看出我在兩個設備間同步了數據,“mobile”后面跟著的是我的設備編號。展開數據可以看到更詳細的同步記錄:

雖然通過“My Mac”可以看到iCloud與CoreData的數據同步記錄,但是在Xcode6.1.1中“Documents”的顯示不是很正常,在最新的Xcode6.2beta版中雖然修復了“Documents”的顯示問題,但“iCloud Usage”的種種bug依然存在。

最后,確保網絡通常。我在中軟實訓一個月時,網絡奇差,或是屏蔽了iCloud,一直沒能調試成功。

貼一張HardChoice同步成功的測試圖,因為我是用Swift寫的這個Demo,所以喜歡用Swift的可以直接把我的那部分源碼粘過去用:

關鍵字:CoreDataiCloud

本文摘自:玉令天下的博客

電子周刊
回到頂部

關于我們聯系我們版權聲明隱私條款廣告服務友情鏈接投稿中心招賢納士

企業網版權所有 ©2010-2024 京ICP備09108050號-6 京公網安備 11010502049343號

^
  • <menuitem id="jw4sk"></menuitem>

    1. <form id="jw4sk"><tbody id="jw4sk"><dfn id="jw4sk"></dfn></tbody></form>
      主站蜘蛛池模板: 安新县| 西昌市| 望奎县| 黔江区| 洞口县| 屏边| 五寨县| 油尖旺区| 浦东新区| 芷江| 福清市| 额尔古纳市| 金沙县| 贵溪市| 丁青县| 五指山市| 灵宝市| 施秉县| 探索| 横峰县| 荥经县| 彩票| 肃北| 承德市| 平顺县| 额尔古纳市| 平顶山市| 陆河县| 那曲县| 四川省| 洪湖市| 阿城市| 南涧| 娄底市| 阳泉市| 神农架林区| 金山区| 安乡县| 凤凰县| 沙坪坝区| 荥经县|