菜鸟教程小白 发表于 2022-12-12 08:53:41

ios - 保存 CKRecord 时的错误处理


                                            <p><p>我正在寻找保存 <code>CKRecord</code> 时正确处理错误的示例。根据 <a href="https://developer.apple.com/library/prerelease/ios/documentation/CloudKit/Reference/CKRecord_class/index.html" rel="noreferrer noopener nofollow">Apple docs</a>我应该“使用错误对象中的信息来确定问题是否有解决方法。”</p>

<p>我知道错误对象有一个 <code>userInfo</code> 字典,但我如何确定字典的键是什么以及如何处理错误?</p>

<p>以下示例说明了我当前如何保存 <code>CKRecord</code>:</p>

<pre><code>    CKRecord *record = [ initWithRecordType:@&#34;MyRecordType&#34;];
forKey:@&#34;myInt&#34;];

[db saveRecord:record completionHandler:^(CKRecord *savedPlace, NSError *error) {
    // handle errors here
    if (savedPlace) {
      NSLog(@&#34;save successful&#34;);
    }else{
      NSLog(@&#34;save unsuccessful&#34;);
    }
    if (error) {
      NSLog(@&#34;Error saving %@&#34;, error.localizedDescription);
    }

}];
</code></pre>

<p>如何改进此代码以解决潜在的保存问题?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>在我的图书馆<a href="https://github.com/evermeer/EVCloudKitDao" rel="noreferrer noopener nofollow">EVCloudKitDao</a>我有一个单独的方法,它将根据错误代码返回错误类型。根据该类型,您可以决定要做什么。这是那个方法:</p>

<pre><code>public enum HandleCloudKitErrorAs {
    case Success,
    Retry(afterSeconds:Double),
    RecoverableError,
    Fail
}

public static func handleCloudKitErrorAs(error:NSError?, retryAttempt:Double = 1) -&gt; HandleCloudKitErrorAs {
    if error == nil {
      return .Success
    }
    let errorCode:CKErrorCode = CKErrorCode(rawValue: error!.code)!
    switch errorCode {
    case .NetworkUnavailable, .NetworkFailure, .ServiceUnavailable, .RequestRateLimited, .ZoneBusy, .ResultsTruncated:
      // Use an exponential retry delay which maxes out at half an hour.
      var seconds = Double(pow(2, Double(retryAttempt)))
      if seconds &gt; 1800 {
            seconds = 1800
      }
      // Or if there is a retry delay specified in the error, then use that.
      if let userInfo = error?.userInfo {
            if let retry = userInfo as? NSNumber {
                seconds = Double(retry)
            }
      }
      NSLog(&#34;Debug: Should retry in \(seconds) seconds. \(error)&#34;)
      return .Retry(afterSeconds: seconds)
    case .UnknownItem, .InvalidArguments, .IncompatibleVersion, .BadContainer, .MissingEntitlement, .PermissionFailure, .BadDatabase, .AssetFileNotFound, .OperationCancelled, .NotAuthenticated, .AssetFileModified, .BatchRequestFailed, .ZoneNotFound, .UserDeletedZone, .InternalError, .ServerRejectedRequest, .ConstraintViolation:
      NSLog(&#34;Error: \(error)&#34;)
      return .Fail;
    case .QuotaExceeded, .LimitExceeded:
      NSLog(&#34;Warning: \(error)&#34;)
      return .Fail;
    case .ChangeTokenExpired,.ServerRecordChanged:
      NSLog(&#34;Info: \(error)&#34;)
      return .RecoverableError
    default:
      NSLog(&#34;Error: \(error)&#34;) //New error introduced in iOS...?
      return .Fail;
    }
}
</code></pre>

<p>在 CloudKit 方法的回调中,您可以像这样使用这个函数:</p>

<pre><code>func loadContacts(retryCount:Double = 1) {      
    // Look who of our contact is also using this app.
    EVCloudKitDao.publicDB.allContactsUserInfo({ users in
            EVLog(&#34;AllContactUserInfo count = \(users.count)&#34;);
            Async.main{
                self.contacts = users
                self.tableView.reloadData()
            }
      }, errorHandler: { error in
            switch EVCloudKitDao.handleCloudKitErrorAs(error, retryAttempt: retryCount) {
            case .Retry(let timeToWait):
                Async.background(after: timeToWait) {
                  self.loadContacts(retryCount + 1)
                }
            case .Fail:
                Helper.showError(&#34;Something went wrong: \(error.localizedDescription)&#34;)
            default: // For here there is no need to handle the .Success, .Fail and .RecoverableError
                break
            }
    })
}
</code></pre>

<p>在我上面的例子中,我使用了一个单独的错误回调处理程序。您也可以在 CloudKit 方法回调中直接调用它。只需先检查是否有错误。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 保存 CKRecord 时的错误处理,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/32621306/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/32621306/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 保存 CKRecord 时的错误处理