Получить частичные ошибки от NSError

При использовании CloudKit иногда возвращается ошибка PartialFailure, которая может быть вызвана дублированием подписок и т. д. См. пример ниже.

<CKError 0x7f8318711520: "Partial Failure" (2/1011); 
"Failed to modify some subscriptions"; uuid = A434B010-7650-4BBA-8A7A-33CD0690FD15; 
container ID = "iCloud.xxx.xxx"; partial errors: { 
EFC65F4A-A595-44A3-A022-323D9CE9B535 = <CKError 0x7f831a007be0: "Server Rejected Request" (15/2032); server message = "subscription is duplicate of '_930081460_AA87A676-DE57-4530-8BB8-7465BF4F4303'"> 
C4913907-28F3-42DB-8455-9966D9084834 = <CKError 0x7f83185cfc20: "Server Rejected Request" (15/2032); server message = "subscription is duplicate of '_930081460_F92FA91D-3E92-4E46-AE59-E912F8871026'"> }>

Я хочу получить эти частичные ошибки из основного объекта ошибки, но я не знаю, как это сделать. NSError не имеет свойства partialError и не имеет ключ в userInfo, чтобы получить его.


person Ben Lu    schedule 11.08.2014    source источник
comment
Если ваш вопрос подходит для Swift или Objective C, скорее всего, он не должен быть помечен ни тем, ни другим.   -  person Matt Gibson    schedule 11.08.2014


Ответы (2)


Вы не получаете обратно прямо NSError, вы получаете обратно CKError. Глядя на документацию для CKError, на самом деле есть ключ CKPartialErrorsByItemIDKey. Это похоже на ключ, который вернул бы словарь CKErrors с ключом по идентификатору элемента, если вы спросите меня! Объект userInfo должен содержать этот ключ.

Также задокументировано здесь

Справочник по константам CloudKit Framework

person Acey    schedule 11.08.2014
comment
На самом деле CKError — это не класс, а просто подсистема CloudKit, которая содержит все соответствующие дополнения NSError. - person Ben Lu; 11.08.2014
comment
У вас есть #import ‹CloudKit/CloudKit.h›? Я вижу автозаполнение, Xcode 6 beta 4. - person Acey; 11.08.2014
comment
Хорошая точка зрения. Домен ошибки — это значение CKErrorDomain, но это просто тип NSError, что достаточно справедливо. - person Acey; 11.08.2014
comment
CKError — это структура Swift, эксклюзивная для Swift. - person Jonny; 29.07.2017
comment
@Jonny Не уверен, откуда вы берете эту информацию, но CloudKit Framework доступен с полной совместимостью либо на Swift, либо на Objective-C. - person Acey; 29.07.2017
comment
@Acey CloudKit доступен для обоих языков, но если вы посмотрите документацию в Xcode, вы увидите, что CKError доступен только для Swift. По сути, CKError — это просто оболочка NSError, которая содержит некоторые удобные вычисляемые свойства и делает API более быстрым. - person Jonny; 29.07.2017
comment
@ Джонни Да, ты прав. Мне нужно читать внимательнее, у меня был такой же разговор 3 года назад чуть выше в комментариях, видимо. - person Acey; 29.07.2017

Два года спустя, и я все еще не думаю, что доступ к частичным ошибкам особенно хорошо задокументирован. Спасибо @Acey за то, что направил меня на правильный путь с CKPartialErrorsByItemIDKey

Для тех, кто борется, вот пример того, как я получил доступ к частичной ошибке в CKModifySubscriptionsOperation (Swift 2.2):

someZoneSubscriptionOperation.modifySubscriptionsCompletionBlock = {(savedSubscriptions: [CKSubscription]?, deletedSubscriptionIDs:[String]?, operationError:NSError?) in

    // check specifically for an error in changing subscriptions to custom zone with specific subscriptionID
    if let partialError = operationError?.userInfo[CKPartialErrorsByItemIDKey]?[subscriptionID] as? ErrorType {
        print(partialError)         // prints partial error for custom zone with `subscriptionID` if it exists
    }
}
person So Over It    schedule 26.05.2016