在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ iOS/ iCloud 和 Core Data
與四軸無(wú)人機(jī)的通訊
在沙盒中編寫(xiě)腳本
結(jié)構(gòu)體和值類型
深入理解 CocoaPods
UICollectionView + UIKit 力學(xué)
NSString 與 Unicode
代碼簽名探析
測(cè)試
架構(gòu)
第二期-并發(fā)編程
Metal
自定義控件
iOS 中的行為
行為驅(qū)動(dòng)開(kāi)發(fā)
Collection View 動(dòng)畫(huà)
截圖測(cè)試
MVVM 介紹
使 Mac 應(yīng)用數(shù)據(jù)腳本化
一個(gè)完整的 Core Data 應(yīng)用
插件
字符串
為 iOS 建立 Travis CI
先進(jìn)的自動(dòng)布局工具箱
動(dòng)畫(huà)
為 iOS 7 重新設(shè)計(jì) App
XPC
從 NSURLConnection 到 NSURLSession
Core Data 網(wǎng)絡(luò)應(yīng)用實(shí)例
GPU 加速下的圖像處理
自定義 Core Data 遷移
子類
與調(diào)試器共舞 - LLDB 的華爾茲
圖片格式
并發(fā)編程:API 及挑戰(zhàn)
IP,TCP 和 HTTP
動(dòng)畫(huà)解釋
響應(yīng)式 Android 應(yīng)用
初識(shí) TextKit
客戶端
View-Layer 協(xié)作
回到 Mac
Android
Core Image 介紹
自定義 Formatters
Scene Kit
調(diào)試
項(xiàng)目介紹
Swift 的強(qiáng)大之處
測(cè)試并發(fā)程序
Android 通知中心
調(diào)試:案例學(xué)習(xí)
從 UIKit 到 AppKit
iOS 7 : 隱藏技巧和變通之道
安全
底層并發(fā) API
消息傳遞機(jī)制
更輕量的 View Controllers
用 SQLite 和 FMDB 替代 Core Data
字符串解析
終身學(xué)習(xí)的一代人
視頻
Playground 快速原型制作
Omni 內(nèi)部
同步數(shù)據(jù)
設(shè)計(jì)優(yōu)雅的移動(dòng)游戲
繪制像素到屏幕上
相機(jī)與照片
音頻 API 一覽
交互式動(dòng)畫(huà)
常見(jiàn)的后臺(tái)實(shí)踐
糟糕的測(cè)試
避免濫用單例
數(shù)據(jù)模型和模型對(duì)象
Core Data
字符串本地化
View Controller 轉(zhuǎn)場(chǎng)
照片框架
響應(yīng)式視圖
Square Register 中的擴(kuò)張
DTrace
基礎(chǔ)集合類
視頻工具箱和硬件加速
字符串渲染
讓東西變得不那么糟
游戲中的多點(diǎn)互聯(lián)
iCloud 和 Core Data
Views
虛擬音域 - 聲音設(shè)計(jì)的藝術(shù)
導(dǎo)航應(yīng)用
線程安全類的設(shè)計(jì)
置換測(cè)試: Mock, Stub 和其他
Build 工具
KVC 和 KVO
Core Image 和視頻
Android Intents
在 iOS 上捕獲視頻
四軸無(wú)人機(jī)項(xiàng)目
Mach-O 可執(zhí)行文件
UI 測(cè)試
值對(duì)象
活動(dòng)追蹤
依賴注入
Swift
項(xiàng)目管理
整潔的 Table View 代碼
Swift 方法的多面性
為什么今天安全仍然重要
Core Data 概述
Foundation
Swift 的函數(shù)式 API
iOS 7 的多任務(wù)
自定義 Collection View 布局
測(cè)試 View Controllers
訪談
收據(jù)驗(yàn)證
數(shù)據(jù)同步
自定義 ViewController 容器轉(zhuǎn)場(chǎng)
游戲
調(diào)試核對(duì)清單
View Controller 容器
學(xué)無(wú)止境
XCTest 測(cè)試實(shí)戰(zhàn)
iOS 7
Layer 中自定義屬性的動(dòng)畫(huà)
第一期-更輕量的 View Controllers
精通 iCloud 文檔存儲(chǔ)
代碼審查的藝術(shù):Dropbox 的故事
GPU 加速下的圖像視覺(jué)
Artsy
照片擴(kuò)展
理解 Scroll Views
使用 VIPER 構(gòu)建 iOS 應(yīng)用
Android 中的 SQLite 數(shù)據(jù)庫(kù)支持
Fetch 請(qǐng)求
導(dǎo)入大數(shù)據(jù)集
iOS 開(kāi)發(fā)者的 Android 第一課
iOS 上的相機(jī)捕捉
語(yǔ)言標(biāo)簽
同步案例學(xué)習(xí)
依賴注入和注解,為什么 Java 比你想象的要好
編譯器
基于 OpenCV 的人臉識(shí)別
玩轉(zhuǎn)字符串
相機(jī)工作原理
Build 過(guò)程

iCloud 和 Core Data

當(dāng)喬布斯第一次在蘋果全球開(kāi)發(fā)大會(huì)上介紹 iCloud 的時(shí)候,他將無(wú)縫同步的功能描述的太過(guò)完美,以至于讓人懷疑其是否真的能實(shí)現(xiàn)。但當(dāng)你在 iOS 5iOS 6 系統(tǒng)中嘗試使用 iCloud Core Data 同步的時(shí)候你會(huì)對(duì)其真實(shí)情況了如指掌。

庫(kù)風(fēng)格應(yīng)用(譯者注:"盒子類型",比如 iPhoto )的同步中的問(wèn)題導(dǎo)致很多開(kāi)發(fā)者放棄支持 iCloud,而選擇一些其他的方案比如 Simperium,TICoreDataSyncWasabiSync

2013年初,在蘋果公司不透明及充滿 bug 的 iCloud Core Data 同步實(shí)現(xiàn)中掙扎多年后,開(kāi)發(fā)者終于公開(kāi)批判了這項(xiàng)服務(wù)的重大缺陷并將這個(gè)話題推上了風(fēng)口浪尖。 最終被 Ellis Hamburger 在一篇尖銳文章提出。

WWDC

蘋果也注意到了,很明顯這些事情必須改變。在 WWDC 2013,Nick Gillett 宣布 Core Data 團(tuán)隊(duì)花了一年時(shí)間專注于在 iOS 7 中解決一些 iCloud 最令人挫敗的漏洞,承諾大幅改善問(wèn)題并且讓開(kāi)發(fā)者更簡(jiǎn)單的使用?!拔覀兠黠@減少了開(kāi)發(fā)者所需要編寫(xiě)的復(fù)雜代碼的數(shù)量?!?Nick Gillett在 [“What’s New in Core Data and iCloud”] 舞臺(tái)上講到。 在 iOS 7 中,Apple 專注于 iCloud 的速度,可靠性,和性能,事實(shí)上這卓有成效。

讓我們看看具體有哪些改變,以及如何在 iOS 7 應(yīng)用程序?qū)崿F(xiàn) Core Data。

設(shè)置

要設(shè)置一個(gè) iCloud Core Data 應(yīng)用,你首先需要在你的應(yīng)用中請(qǐng)求 iCloud 的訪問(wèn)權(quán)限,讓你的應(yīng)用程序可以讀寫(xiě)一個(gè)或多個(gè)開(kāi)放性容器 (ubiquity containers),在 Xcode 5中你可以在你應(yīng)用 target 的 “Capabilities” 選項(xiàng)卡中輕易完成著這一切。

在開(kāi)放性容器內(nèi)部,Core Data Framework 將會(huì)存儲(chǔ)所有的事務(wù)日志 -- 記錄你的所有持久化的存儲(chǔ) -- 為了跨設(shè)備同步數(shù)據(jù)做準(zhǔn)備。 Core Data 使用了一個(gè)被稱為多源復(fù)制(multi-master replication)的技術(shù)來(lái)同步 iOS 和 Macs 之間的數(shù)據(jù)??沙志没鎯?chǔ)的數(shù)據(jù)存在了每個(gè)設(shè)備的 CoreDataUbiquitySupport 文件夾里,你可以在應(yīng)用沙盒中找到他。當(dāng)用戶修改了 iCloud accounts,Core Data framework 會(huì)管理多個(gè)賬戶,而并不需要你自己去監(jiān)聽(tīng)NSUbiquityIdentityDidChangeNotification。

每一個(gè)事務(wù)日志都是一個(gè)plist文件,負(fù)責(zé)實(shí)體的跟蹤插入,刪除以及更新。這些日志會(huì)自動(dòng)被系統(tǒng)按照一定基準(zhǔn)合并。

在你設(shè)置iCloud的持久化存儲(chǔ)的時(shí)候,調(diào)用addPersistentStoreWithType:configuration:URL:options:error:或者 migratePersistentStore:toURL:options:withType:error:的時(shí)候注意需要設(shè)置一些選項(xiàng):

  • NSPersistentStoreUbiquitousContentNameKey (NSString)
    給 iCloud 存儲(chǔ)空間指定一個(gè)名字(例如 @“MyAppStore”)

  • NSPersistentStoreUbiquitousContentURLKey (NSString, iOS 7 中可選) 給事務(wù)日志指定一個(gè)二級(jí)目錄(例如 @"Logs")

  • NSPersistentStoreUbiquitousPeerTokenOption (NSString, 可選)
    為每個(gè)程序設(shè)置一個(gè)鹽,為了讓不同應(yīng)用可以在同一個(gè)集成 iCloud 的設(shè)備中分享 Core Data 數(shù)據(jù) (比如@"d70548e8a24c11e3bbec425861b86ab6")

  • NSPersistentStoreRemoveUbiquitousMetadataOption (NSNumber (Boolean), 可選) 指定程序是否需要備份或遷移 iCloud 的元數(shù)據(jù)(例如 @YES)

  • NSPersistentStoreUbiquitousContainerIdentifierKey (NSString)
    指定一個(gè)容器,如果你的應(yīng)用有多個(gè)容器定義在 entitlements 中(例如 @"com.company.MyApp.anothercontainer")

  • NSPersistentStoreRebuildFromUbiquitousContentOption (NSNumber (Boolean), 可選) 告訴 Core Data 抹除本地存儲(chǔ)數(shù)據(jù)并且用 iCoud 重建數(shù)據(jù)(例如 @YES)

只支持 iOS 7 的應(yīng)用的唯一必填選項(xiàng)是 ContentNameKey,它是為了讓 Core Data 知道把日志和元數(shù)據(jù)放在哪里。在 iOS 7 中,你傳入 NSPersistentStoreUbiquitousContentNameKey 的字符串值不應(yīng)該包含'.'。 如果你的應(yīng)用已經(jīng)使用 Core Data 去存儲(chǔ)持久化數(shù)據(jù),但是沒(méi)有實(shí)現(xiàn) iCloud 同步,你只需要簡(jiǎn)單加入 content name key 就能將存儲(chǔ)轉(zhuǎn)為可以使用 iCloud 的狀態(tài),而無(wú)需關(guān)注有沒(méi)有活躍的 iCloud 賬戶。

為你的應(yīng)用設(shè)置一個(gè)管理對(duì)象上下文簡(jiǎn)單到只需要實(shí)例化一個(gè) NSManagedObjectContext 并連同一個(gè)合并策略一并告訴你的持久化存儲(chǔ)。蘋果建議使用 NSMergeByPropertyObjectTrumpMergePolicy 作為合并策略,它會(huì)合并沖突,并給予內(nèi)存中的變化的數(shù)據(jù)相較于磁盤數(shù)據(jù)更高的優(yōu)先級(jí)。

雖然 Apple 還沒(méi)有發(fā)布官方的 iOS7 中 iCloud Core Data 的示例代碼,但是 Apple 的 Core Data 團(tuán)隊(duì)中的一個(gè)工程師在開(kāi)發(fā)者論壇上提供了這個(gè)模板。我們稍微修改讓它更清晰:

#pragma mark - Notification Observers
- (void)registerForiCloudNotifications {
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];

    [notificationCenter addObserver:self 
                           selector:@selector(storesWillChange:) 
                               name:NSPersistentStoreCoordinatorStoresWillChangeNotification 
                             object:self.persistentStoreCoordinator];

    [notificationCenter addObserver:self 
                           selector:@selector(storesDidChange:) 
                               name:NSPersistentStoreCoordinatorStoresDidChangeNotification 
                             object:self.persistentStoreCoordinator];

    [notificationCenter addObserver:self 
                           selector:@selector(persistentStoreDidImportUbiquitousContentChanges:) 
                               name:NSPersistentStoreDidImportUbiquitousContentChangesNotification 
                             object:self.persistentStoreCoordinator];
}

# pragma mark - iCloud Support

/// 在 -addPersistentStore: 使用這些配置
- (NSDictionary *)iCloudPersistentStoreOptions {
    return @{NSPersistentStoreUbiquitousContentNameKey: @"MyAppStore"};
}

- (void) persistentStoreDidImportUbiquitousContentChanges:(NSNotification *)notification {
    NSManagedObjectContext *context = self.managedObjectContext;

    [context performBlock:^{
        [context mergeChangesFromContextDidSaveNotification:changeNotification];
    }];
}

- (void)storesWillChange:(NSNotification *)notification {
    NSManagedObjectContext *context = self.managedObjectContext;

    [context performBlockAndWait:^{
        NSError *error;

        if ([context hasChanges]) {
            BOOL success = [context save:&error];

            if (!success && error) {
                // 執(zhí)行錯(cuò)誤處理
                NSLog(@"%@",[error localizedDescription]);
            }
        }

        [context reset];
    }];

    // 刷新界面
}

- (void)storesDidChange:(NSNotification *)notification {
    // 刷新界面
}

異步持久化設(shè)置

在 iOS 7 中,使用 iCloud 選項(xiàng)來(lái)調(diào)用 addPersistentStoreWithType:configuration:URL:options:error: 幾乎可以瞬間返回存儲(chǔ)對(duì)象。1 能做到這樣是因?yàn)樗紫仍O(shè)置了一個(gè)內(nèi)部‘回滾’存儲(chǔ),利用本地存儲(chǔ)作為一個(gè)占位符,同時(shí)由事務(wù)日志和元數(shù)據(jù)來(lái)異步地構(gòu)建 iCloud 存儲(chǔ)。當(dāng)回滾存儲(chǔ)有變化時(shí),這些變化將在 iCloud 存儲(chǔ)被添加到 coordinator 時(shí)合并至其中。在完成回滾存儲(chǔ)的設(shè)置后,控制臺(tái)將會(huì)打印Using local storage: 1 ,當(dāng) iCloud 完全設(shè)置完后,你會(huì)看到 Using local storage: 0。 這句話的意思是 iCloud 存儲(chǔ)已經(jīng)啟用,此后你可以通過(guò)監(jiān)聽(tīng)NSPersistentStoreDidImportUbiquitousContentChangesNotification看到來(lái)自 iCloud 的內(nèi)容。

如果你的應(yīng)用關(guān)注在不同存儲(chǔ)間的遷移,那么你需要監(jiān)聽(tīng) NSPersistentStoreCoordinatorStoresWillChangeNotification 和/或NSPersistentStoreCoordinatorStoresDidChangeNotification(將這些通知關(guān)聯(lián)到你的 coordinator,這樣就可以過(guò)濾其他和你無(wú)關(guān)的通知) 并且在 userInfo 中檢查 NSPersistentStoreUbiquitousTransitionTypeKey 的值, 這個(gè)數(shù)值是一個(gè)對(duì)應(yīng) NSPersistentStoreUbiquitousTransitionType 枚舉類型的 NSNumber,在遷移已經(jīng)發(fā)生時(shí),這個(gè)值是NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted

邊緣情況

混淆 (Churn)

在 iOS 5 和 iOS 6 中測(cè)試 iCloud 時(shí)最嚴(yán)重的一個(gè)問(wèn)題是重度用戶的賬號(hào)會(huì)遇到一種“混淆”的狀態(tài),導(dǎo)致無(wú)法使用。同步將完全停止,甚至刪除開(kāi)放性數(shù)據(jù)也無(wú)法使其正常工作。在 Lickability,我們親切地稱為這種狀態(tài)“f \ \ \ * ing bucket。”

在 iOS 7 中,系統(tǒng)提供了一個(gè)方法來(lái)真正移除全部的開(kāi)放性存儲(chǔ)內(nèi)容: +removeUbiquitousContentAndPersistentStoreAtURL:options:error:,這個(gè)方法對(duì)測(cè)試很有幫助,甚至在你應(yīng)用中,當(dāng)你用戶進(jìn)入了一個(gè)不正常的狀態(tài)時(shí),他們可以通過(guò)這個(gè)方法刪除所有數(shù)據(jù),并重新來(lái)過(guò)。不過(guò),需要指出的是:首先,這種方法是同步的。甚至在做網(wǎng)絡(luò)操作的時(shí)候它也是同步的,因此它會(huì)花很長(zhǎng)時(shí)間,并且在完成前也不會(huì)返回。第二,絕對(duì)不能在有持久性存儲(chǔ) coordinators 活躍時(shí)執(zhí)行此操作。這樣會(huì)造成很嚴(yán)重的問(wèn)題,你的應(yīng)用程序可能進(jìn)入一個(gè)不可恢復(fù)的狀態(tài),而且官方指導(dǎo)指出所有活躍的持久性存儲(chǔ) coordinators 都應(yīng)在使用這個(gè)方法前完全銷毀收回。

賬戶修改

iOS 5 系統(tǒng)中,用戶在切換 iCloud 賬戶或者禁用賬戶時(shí),NSPersistentStoreCoordinator 中的數(shù)據(jù)會(huì)在應(yīng)用無(wú)法知曉的情況下完全消失。事實(shí)上檢查一個(gè)賬號(hào)是否變更了的唯一的方法是調(diào)用 NSFileManager 中的 URLForUbiquityContainerIdentifier,這個(gè)方法可以創(chuàng)建一個(gè)開(kāi)放性容器文件夾,而且需要數(shù)秒返回。在 iOS 6,這種情況隨著引進(jìn) ubiquityIdentityToken 和相應(yīng)的NSUbiquityIdentityDidChangeNotification 之后得到改善。因?yàn)樵?ubiquity id 變化的時(shí)候會(huì)發(fā)送通知,這就可以對(duì)應(yīng)用賬戶的變更進(jìn)行有效的確認(rèn)并及時(shí)的發(fā)出提示。

然而,iOS 7 中這種轉(zhuǎn)換的情況就變得更加簡(jiǎn)單,賬戶的切換是由 Core Data 框架來(lái)處理的,因此只要你的程序能夠正常響應(yīng) NSPersistentStoreCoordinatorStoresWillChangeNotificationNSPersistentStoreCoordinatorStoresDidChangeNotification 便可以在切換賬戶的時(shí)候流暢的更換信息。檢查 userInfo 的字典中 NSPersistentStoreUbiquitousTransitionType 鍵將提供更多關(guān)于遷移的類型的細(xì)節(jié)。

在應(yīng)用沙箱中框架會(huì)為每個(gè)賬戶管理各自獨(dú)立的持久化存儲(chǔ),所以這就意味著如果用戶回到之前的賬戶,其數(shù)據(jù)會(huì)和之前離開(kāi)時(shí)一樣,仍然可用。Core Data 現(xiàn)在也會(huì)在磁盤空間不足時(shí)管理對(duì)這些文件進(jìn)行的清理工作。

iCloud 的啟用與停用

在 iOS 7 中應(yīng)用實(shí)現(xiàn)用一個(gè)開(kāi)關(guān)用來(lái)切換啟用關(guān)閉 iCloud 變的非常容易,雖然對(duì)大部分應(yīng)用來(lái)說(shuō)這個(gè)功能不是很需要,因?yàn)樵趧?chuàng)建 NSPersistentStore 時(shí)候如果加入 iCloud 選項(xiàng),那么 API 現(xiàn)在將自動(dòng)建立一個(gè)獨(dú)立的文件結(jié)構(gòu),這意味著本地存儲(chǔ)和 iCloud 存儲(chǔ)共用相同的存儲(chǔ) URL 和其他很多設(shè)置。這個(gè)選項(xiàng)將把 ubiquitous 元數(shù)據(jù)和存儲(chǔ)本身進(jìn)行分離,并專門為遷移或者復(fù)制的場(chǎng)景進(jìn)行了特殊設(shè)計(jì)。下面是一個(gè)示例:

- (void)migrateiCloudStoreToLocalStore {
    // 假設(shè)你只有一個(gè)存儲(chǔ)
    NSPersistentStore *store = [[_coordinator persistentStores] firstObject]; 

    NSMutableDictionary *localStoreOptions = [[self storeOptions] mutableCopy];
    [localStoreOptions setObject:@YES forKey:NSPersistentStoreRemoveUbiquitousMetadataOption];

    NSPersistentStore *newStore =  [_coordinator migratePersistentStore:store 
                                                                  toURL:[self storeURL] 
                                                                options:localStoreOptions 
                                                               withType:NSSQLiteStoreType error:nil];

    [self reloadStore:newStore];
}

- (void)reloadStore:(NSPersistentStore *)store {
    if (store) {
        [_coordinator removePersistentStore:store error:nil];
    }

    [_coordinator addPersistentStoreWithType:NSSQLiteStoreType 
                               configuration:nil 
                                         URL:[self storeURL] 
                                     options:[self storeOptions] 
                                       error:nil];
}

切換一個(gè)本地存儲(chǔ)到 iCloud 存儲(chǔ)是一個(gè)非常容易的事情,簡(jiǎn)單到只需啟用 iCloud 選項(xiàng),并且把擁有相同選項(xiàng)的可持久存儲(chǔ)加入到 coordinator 中。

外部文件的引用

外部文件的應(yīng)用是一個(gè)在 iOS 5 中加入的 Core Data 新特性,允許大尺寸的二進(jìn)制自動(dòng)存儲(chǔ)在 SQLite 數(shù)據(jù)庫(kù)之外的文件系統(tǒng)中。 在我們測(cè)試中,當(dāng)發(fā)生改變時(shí),iCloud 并不知道如何解決依賴關(guān)系并會(huì)拋出異常。如果你計(jì)劃使用 iCloud 同步 ,可以考慮在 iCloud entities 中取消這個(gè)選擇:

http://wiki.jikexueyuan.com/project/objc/images/10-6.png" alt="" />

Model 版本

如果你計(jì)劃使用 iCloud,存儲(chǔ)的內(nèi)容只能在未來(lái)兼容自動(dòng)輕量級(jí)遷移, 這意味著 Core Data 需要能推斷出映射,你也不能提供自己的映射模型。在未來(lái)只有對(duì) Model 的簡(jiǎn)單改變,比如添加和重命名屬性,才能被支持。在考慮是否使用 Core Data 同步時(shí),一定要考慮到你的 app 的 Model 在未來(lái)版本中改變的情況。

合并沖突

在任何同步系統(tǒng)中,服務(wù)器和客戶端之前的文件沖突是不可避免的。不同于 iCloud Data 文檔同步的 APIs, iCloud 的 Core Data 整合并沒(méi)有明確允許處理本地存儲(chǔ)和事務(wù)日志之間的沖突。這其實(shí)是因?yàn)?Core Data 已經(jīng)支持通過(guò)實(shí)現(xiàn) NSMergePolicy 的子類來(lái)自定義策合并策略。 如果你要處理沖突,創(chuàng)建 NSMergePolicy 的子類并且覆蓋 resolveConflicts:error: 來(lái)決定在沖突發(fā)生的時(shí)候做什么。然后在你的 NSManagedObjectContext 子類中,讓mergePolicy 方法返回一個(gè)你自定義的策略的實(shí)例。

界面更新

很多庫(kù)風(fēng)格應(yīng)用同時(shí)顯示集合對(duì)象和一個(gè)對(duì)象的詳細(xì)信息。 視圖是由 NSFetchedResultsController 實(shí)例自動(dòng)從網(wǎng)絡(luò)更新 Core Data 的數(shù)據(jù)然后刷新。然而,您應(yīng)該確保每一個(gè)詳細(xì)視圖正確監(jiān)聽(tīng)變化對(duì)象并使自己保持最新。如果你不這樣做, 將有顯示陳舊的數(shù)據(jù)的風(fēng)險(xiǎn),或者更糟,你將覆蓋其他設(shè)備修改的數(shù)據(jù)。

測(cè)試

本地網(wǎng)絡(luò)和因特網(wǎng)同步

iCloud 守護(hù)進(jìn)程將使用本地網(wǎng)絡(luò)或使用因特網(wǎng)這兩種方式中的其中一種,來(lái)進(jìn)行跨設(shè)備的數(shù)據(jù)同步。守護(hù)進(jìn)程檢測(cè)到兩個(gè)設(shè)備時(shí),也被稱為對(duì)等網(wǎng)絡(luò),在同一個(gè)局域網(wǎng),將在內(nèi)網(wǎng)快速傳輸。然而,如果在不同的網(wǎng)絡(luò),該系統(tǒng)將傳輸回滾事務(wù)日志。這很重要,你必須在開(kāi)發(fā)中對(duì)兩種情況進(jìn)行大量的測(cè)試,以確保您的應(yīng)用程序正常運(yùn)作。在這兩種場(chǎng)景中,從備份存儲(chǔ)同步更改或過(guò)渡到 iCloud 有時(shí)需要比預(yù)期更長(zhǎng)的時(shí)間,所以如果有什么不工作,嘗試給它點(diǎn)時(shí)間。

模擬器中使用 iCloud

在 iOS 7 中最有用的更新就是 iCloud 終于可以在模擬器中使用。在以往的版本中,你只能在設(shè)備中測(cè)試,這個(gè)限制使監(jiān)聽(tīng)開(kāi)發(fā)的同步進(jìn)程有點(diǎn)困難?,F(xiàn)在你甚至可以在你的 Mac 和模擬器中進(jìn)行數(shù)據(jù)同步。

在 Xcode 5 新增的 iCloud 調(diào)試儀表中,你可以看到在你的應(yīng)用程序的開(kāi)放性存儲(chǔ)中的文件,以及檢查它們的文件傳輸狀態(tài),比如 "Current", "Excluded", 和 "Stored in Cloud" 等。 對(duì)于更底層的調(diào)試,可以把 -com.apple.coredata.ubiquity.logLevel 3 加入到啟動(dòng)參數(shù)或者設(shè)置成用戶默認(rèn),以啟用詳細(xì)日志。還可以考慮在 iOS 中安裝 iCloud 存儲(chǔ)調(diào)試日志配置文件 以及新的 ubcontrol 命令行工具提供高質(zhì)量錯(cuò)誤報(bào)告到Apple 。你可以在你的設(shè)備連入 iTunes 并同步后在 ~/Library/Logs/CrashReporter/MobileDevice/device-name/DiagnosticLogs 中獲取這些工具生成的日志。

然而,iCloud Core Data 并不完全支持模擬器。在用實(shí)際設(shè)備和模擬器測(cè)試傳輸時(shí),似乎模擬器的 iCloud Core Data 只上傳更改,卻從不把它們抓取下來(lái)。雖然比起分別使用多個(gè)不同測(cè)試設(shè)備來(lái)說(shuō),確實(shí)進(jìn)步和方便了很多,但是 iOS 模擬器上的 iCloud Core Data 支持絕對(duì)還沒(méi)有完全成熟。

繼續(xù)改進(jìn)

因?yàn)?iOS 7 中 APIs 和功能得到了極大的改善,那些在 iOS 5 和 iOS 6 上分發(fā)的帶有 iCloud Core Data 的應(yīng)用的命運(yùn)就顯得撲朔迷離了。 由于從 API 的角度來(lái)看它們完全不同(當(dāng)然我們從功能角度也驗(yàn)證了這一點(diǎn)),Apple 的建議對(duì)于那些需要傳統(tǒng)同步的應(yīng)用來(lái)說(shuō)并不那么友好。Apple 清楚地開(kāi)發(fā)者論壇 上建議,絕對(duì)不要在 iOS 7 和之前的設(shè)備同步之間同步數(shù)據(jù)。

事實(shí)上,“任何時(shí)候你都不應(yīng)該在 iOS 7 與 iOS 6 同步。iOS 6 將持續(xù)造成那些已經(jīng)在 iOS 7 上修正了的 bug,這樣做將會(huì)會(huì)污染 iCloud 賬戶?!?保證這種分離的最簡(jiǎn)單的方法是簡(jiǎn)單地改變你存儲(chǔ)中的 NSPersistentStoreUbiquitousContentNameKey,遵循規(guī)范進(jìn)行命名。這樣保證從舊版本數(shù)據(jù)同步的方法是孤立的,并允許開(kāi)發(fā)人員從老舊的實(shí)現(xiàn)中完全脫身。

發(fā)布

發(fā)布一個(gè) iCloud Core Data 應(yīng)用仍舊有很大的風(fēng)險(xiǎn),你需要對(duì)所有的環(huán)節(jié)進(jìn)行測(cè)試:賬戶轉(zhuǎn)換,iCloud 存儲(chǔ)空間耗盡,多種設(shè)備,Model 的升級(jí),以及設(shè)備恢復(fù)等。盡管 iCloud 調(diào)試儀表和 developer.icloud.com 對(duì)這些有所幫助,但依靠一個(gè)你完全無(wú)法控制的服務(wù)來(lái)發(fā)布一個(gè)應(yīng)用仍然需要那種縱身一躍入深淵的信念。

正如 Brent Simmon 提到的,發(fā)布任意一種 iCloud Syncing 應(yīng)用都會(huì)有限制,所以需要事先了解一下成本。像 Day One1Password 這樣的程序,會(huì)讓使用者選擇用 iCloud 還是 Dropbox 來(lái)同步他們的數(shù)據(jù)。對(duì)于很多使用者來(lái)說(shuō),沒(méi)什么可以比一個(gè)獨(dú)立的賬戶更加簡(jiǎn)易,但是一部分動(dòng)手能力強(qiáng)的人喜歡更好的更全面的控制他們的數(shù)據(jù)。對(duì)于開(kāi)發(fā)者而言,維持這種完全不同的數(shù)據(jù)庫(kù)同步系統(tǒng)在開(kāi)發(fā)和測(cè)試的過(guò)程當(dāng)中是十分繁瑣和超負(fù)荷的。

Bugs

一旦你測(cè)試并且發(fā)布了你的 iCloud Core Data 應(yīng)用,你很可能會(huì)遇到很多框架里的 bug,最好的辦法是反饋這些 bug 的詳細(xì)信息到 Apple,其中需要包含以下信息:

  1. 完整的重現(xiàn)步驟
  2. 安裝了 iCloud 調(diào)試配置并將 iCloud 調(diào)試日志輸出級(jí)別調(diào)為 3 的終端輸出
  3. 打包為 zip 的完整的開(kāi)放性存儲(chǔ)內(nèi)容

結(jié)論

在 iOS 5 和 6 中 iCloud Core Data 根本就沒(méi)法用這件事已經(jīng)是不是一個(gè)秘密, Apple 的程序員自己都承認(rèn)“在 iOS 5 和 6 中使用 Core Data + iCloud 時(shí),存在重大的穩(wěn)定性和長(zhǎng)期可靠性的問(wèn)題,要使用它的話請(qǐng)一定一定一定把應(yīng)用設(shè)為 iOS 7 only“。一些高端的開(kāi)發(fā)者,比如 Agile Tortoise 以及 Realmac Software,現(xiàn)在已經(jīng)信任 iCloud Core Data,并把它集成到了他們的應(yīng)用中。因?yàn)橛兄浞值?a rel="nofollow" >考量和測(cè)試,你也應(yīng)該這么做了。

特別感謝 Andrew Harrison, Greg Pierce, and Paul Bruneau 對(duì)這篇文章的幫助


  1. 在之前的 OS 版本中,這個(gè)方法直到 iCloud 數(shù)據(jù)下載并合并到持久化存儲(chǔ)中前是不會(huì)返回的。這將造成大幅延遲,并意味著任何對(duì)這個(gè)方法的調(diào)用需要被派發(fā)到一個(gè)后臺(tái)的隊(duì)列中去。值得慶幸的是現(xiàn)在已經(jīng)不再需要這么做了。