首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iOS 8:通过订阅获得CKRecord更改的通知

iOS 8:通过订阅获得CKRecord更改的通知
EN

Stack Overflow用户
提问于 2014-07-15 07:46:54
回答 2查看 1.9K关注 0票数 3

我正在运行一个CKFetchNotificationChangesOperation来下载所有的更新通知,这些通知应该是从我的应用程序上次运行以来发送的。

正如我所期望的,我得到了一堆CKNotification对象,但是每个CKNotification的recordFields对象都是空的。我希望它会填充我的对象的所有更改的属性。但也许事实并非如此。

我没有指定CKSubscription对象的desiredKeys属性,这显然会强制CKNotification recordFields保存该数据。但是文档说desiredKeys只能有3个值,而我的对象有比3个值多得多的值可以更新。

所以现在我想,我只需要获取CKNotification对象,看看它是否是更新,然后重新获取它所指向的对象来检索它的数据。然后,我可以对新的CKRecord和旧的进行比较,看看有什么变化。

我的理解正确吗?

EN

回答 2

Stack Overflow用户

发布于 2014-07-20 11:53:23

首先,您需要存储CKFetchNotificationChangesOperation提供的CKServerChangeToken

代码语言:javascript
复制
var notificationChangesOperation = CKFetchNotificationChangesOperation(previousServerChangeToken: previousChangeToken)

var fetchedRecordIDs:[CKRecordID]()

//we just care about inserts, we don't care about of changes of records existing in database, that's why it's enough just to save recordIDs
notificationChangesOperation.notificationChangedBlock = {notification in

    let queryNotif = notification as CKQueryNotification
    //            println("fetched  CKQueryNotification \(queryNotif)")

    if (!contains(fetchedRecordIDs, queryNotif.recordID)) {
        fetchedRecordIDs.append(queryNotif.recordID)
    }
}

notificationChangesOperation.fetchNotificationChangesCompletionBlock = {serverChangeToken, error in
    if (error) {
        println("failed to fetch notification \(error)")
    }

    self.previousChangeToken = serverChangeToken

    completionHandler(recordIDs: fetchedRecordIDs, error: error)
}

container.addOperation(notificationChangesOperation)

var previousChangeToken:CKServerChangeToken? {
    get {
        let encodedObjectData = NSUserDefaults.standardUserDefaults().objectForKey(SubscriptionKeys.PreviousChangeToken) as? NSData

        if (encodedObjectData) {
            return NSKeyedUnarchiver.unarchiveObjectWithData(encodedObjectData) as? CKServerChangeToken
        }

        return nil
    }
    set(newToken) {
        if (newToken) {
            println("new token \(newToken)")

            NSUserDefaults.standardUserDefaults().setObject(NSKeyedArchiver.archivedDataWithRootObject(newToken), forKey:SubscriptionKeys.PreviousChangeToken)
        }
    }
}

然后在CKFetchNotificationChangesOperation的下一个调用中传递它。则此操作将为您提供自上次请求以来的更新。CKNotification (CKQueryNotification)为您提供CKRecordID对象,而不是CKRecord

因此,您需要使用CKFetchRecordsOperation重新获取这些ID的所有CKRecord,并相应地更新模型对象。

代码语言:javascript
复制
func queryMessagesWithIDs(IDs:[CKRecordID], completionHandler: ([CKRecord]!, NSError!) -> Void) {
    var fetchRecordsOperation = CKFetchRecordsOperation(recordIDs: IDs)

    var messages:[CKRecord]()

    fetchRecordsOperation.perRecordCompletionBlock = {record, recordID, error in
        if (!error) {
            messages.append(record)
        } else {
            println("failed to get message with ID \(recordID.recordName)")
        }
    }

    fetchRecordsOperation.fetchRecordsCompletionBlock = {_, error in
        if (error) {
            println(error)
        } else {
            messages.sort{$0.creationDate.compare($1.creationDate) == NSComparisonResult.OrderedAscending}
        }

        dispatch_async(dispatch_get_main_queue(), {completionHandler(messages, error)})
    }

    publicDatabase.addOperation(fetchRecordsOperation)
}
票数 3
EN

Stack Overflow用户

发布于 2015-04-18 17:59:30

iOS 11中弃用了CKFetchNotificationChangesOperation,在标题中苹果建议:

使用CKDatabaseSubscription、CKFetchDatabaseChangesOperation和CKFetchRecordZoneChangesOperation,而不是通过迭代通知来枚举已更改的记录区

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24747799

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档