Swift 3.0 CloudKit fetchDatabaseChangesCompletionBlock 错误

Swift 3.0 CloudKit fetchDatabaseChangesCompletionBlock Error

我正在跟随WWDC Session about CloudKit。在此,有这段代码被剪断:

let changesOperation = CKFetchDatabaseChangesOperation(previousServerChangeToken: privateDatabaseChangeToken)
//(...)
changesOperation.fetchDatabaseChangesCompletionBlock = {
        (newToken: CKServerChangeToken?, more: Bool, error: NSError?) -> Void in
        // error handling here
        self.sharedDBChangeToken = newToken // cache new token
        self.fetchZoneChanges(callback) // using CKFetchRecordZoneChangesOperation
    }

尽管代码完全是从幻灯片中复制的,XCode 还是出现了这个错误:

Cannot assign value of type '(CKServerChangeToken?, Bool, NSError?) -> Void' to type '((CKServerChangeToken?, Bool, Error?) -> Void)?'

我正在使用 XCode 8.0 Beta 4,目标是 iOS 10,以防这应该是编译器错误。

在 Beta 4[需要引用] 中,实施了 swift-进化提案 SE-0112,影响错误处理。

这里重要的一点是 Objective-C NSError 类型在 Swift 中导入为 Error(以前的 ErrorProtocol)类型而不是 NSError.

只需更新您的类型注释:

changesOperation.fetchDatabaseChangesCompletionBlock = {
    (newToken: CKServerChangeToken?, more: Bool, error: Error?) -> Void in
    // ...
}

附带说明一下,您实际上可以完全省略参数类型:

changesOperation.fetchDatabaseChangesCompletionBlock = { newToken, more, error in
    // ...
}

对于错误处理,据我所知,传递的错误通常是 CKError,这是一个新的(?)结构,它封装了 userInfo 字典的所有(?)旧 NSError.

changesOperation.fetchDatabaseChangesCompletionBlock = { newToken, more, error in
    guard error == nil else {
        if let ckerror = error as? CKError {
            // ... Handle the CKError
        }
        return
    }
    // ... Do something useful
}