背景
我正在关注本教程:https ://www.toptal.com/ios/sync-data-across-devices-with-cloudkit
他有一个部分来处理用 swift 编写的来自 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
}
我正在尝试将其转换为 Xamarin 的 C#。但是我正在努力如何处理 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;
}
主要问题
我的上述解决方案似乎笨拙,老实说不确定它是否有效。由于下面的编译错误,我无法真正测试。
但真正的问题来了。在他的下一个方法中,他以某种方式访问clientRecord
and serverRecord
,我认为这是 a 的字段CKError
?我什至如何访问这些?我在我不理解的行中插入了一个箭头。当我只能访问 Xamarin 中的 NSError 时,似乎我需要访问 CKError 的一些内部属性。
// 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
andserverRecord
来自哪里!也许我错过了一些我错过的 Swift 的细微差别。我从来没有快速编码过。任何的意见都将会有帮助。