Обработка частичных ошибок CloudKit в Xamarin.ios

Задний план

Я следую этому руководству: https://www.toptal.com/ios/sync-data-across-devices-with-cloudkit

У него есть раздел для обработки частичных ошибок из CloudKit, написанный быстро:

      public func isSpecificErrorCode(code: CKError.Code) -> Bool {
    var match = false
    if self.code == code {
        match = true
    }
    else if self.code == .partialFailure {
        // This is a multiple-issue error. Check the underlying array
        // of errors to see if it contains a match for the error in question.
        guard let errors = partialErrorsByItemID else {
            return false
        }
        for (_, error) in errors {
            if let cke = error as? CKError {
                if cke.code == code {
                    match = true
                    break
                }
            }
        }
    }
    return match
}

Я пытаюсь перевести это на C# для Xamarin. Но я изо всех сил пытаюсь обрабатывать ошибки CloudKit, поскольку в Xamarin, похоже, отсутствует класс CKError. В статическом классе я написал следующее:

          static public bool isSpecificErrorCode(CKErrorCode code, NSError error) {
        var match = false;
        if ((int)code == error.Code) {
            match = true;
        }
        else if (code == CKErrorCode.PartialFailure) {
            // This is a multiple-issue error. Check the underlying array
            // of errors to see if it contains a match for the error in question.
            NSDictionary errors = (NSDictionary)error.UserInfo.ObjectForKey(CKErrorFields.PartialErrorsByItemIdKey);
            foreach (KeyValuePair<NSObject, NSObject> item in errors) {
                var err = (NSError) item.Value;
                if (err.Code == (int)code) {
                    match = true;
                    break;
                }
            }
        }

        return match;
    }

Главная проблема

Мое приведенное выше решение кажется громоздким, и, честно говоря, не уверен, что оно работает. Поскольку я не могу действительно протестировать из-за ошибок компиляции ниже.

Но возникает настоящая проблема. В своем следующем методе он каким-то образом обращается к и, которые, как я предполагаю, являются полями CKError? Как мне вообще получить к ним доступ? Я вставил стрелку в строку, которую не понимаю. Кажется, мне нужно получить доступ к некоторому внутреннему свойству CKError, когда все, что я могу получить, - это NSError в Xamarin.

      // ServerRecordChanged errors contain the CKRecord information
// for the change that failed, allowing the client to decide
// upon the best course of action in performing a merge.
public func getMergeRecords() -> (CKRecord?, CKRecord?) {
    if code == .serverRecordChanged {
        // This is the direct case of a simple serverRecordChanged Error.


        //here
        return (clientRecord, serverRecord) // <-- this is what's confusing me!!!
        //here

    }
    guard code == .partialFailure else {
        return (nil, nil)
    }
    guard let errors = partialErrorsByItemID else {
        return (nil, nil)
    }
    for (_, error) in errors {
        if let cke = error as? CKError {
            if cke.code == .serverRecordChanged {
    // This is the case of a serverRecordChanged Error 
    // contained within a multi-error PartialFailure Error.
                return cke.getMergeRecords()
            }
        }
    }
    return (nil, nil)
}

Попытка решения (ошибки компиляции из-за отсутствия данных)

Вот моя слабая попытка:

          public class MergeRecordPair {
        public CKRecord clientRecord = null;
        public CKRecord serverRecord = null;
    }

    static public MergeRecordPair getMergeRecords(this NSError error) {
        if (error.Code == (int)CKErrorCode.ServerRecordChanged) {
            // This is the direct case of a simple serverRecordChanged Error.
            
            // here
            return new MergeRecordPair {
                clientRecord = clientRecord, // <-- How do I get these?
                serverRecord = serverRecord // <-- How do I get these?
            };
            // here

        }
        if (error.Code == (int)CKErrorCode.PartialFailure) {
            return new MergeRecordPair();
        }
        
        NSDictionary errors = (NSDictionary)error.UserInfo.ObjectForKey(CKErrorFields.PartialErrorsByItemIdKey);
        if (errors == null) {
            return new MergeRecordPair();
        }
    
        foreach (KeyValuePair<NSObject, NSObject> item in errors) {
            var err = (NSError) item.Value;
            if (err.Code == (int)CKErrorCode.ServerRecordChanged) {
                return err.getMergeRecords();
            }
        }
        return new MergeRecordPair();
    }

Я уверен, что моя попытка решения даже идет по правильному пути. Я понятия не имею, где clientRecord а также serverRecordисходят из! Возможно, я упускаю какой-то нюанс Swift, который мне не хватает. Я никогда не программировал на swift. Любые предложения были бы полезны.

0 ответов

Другие вопросы по тегам