쥘,
당신이 너무 많은 이와 같은 코드의 조각을 사용하여 말고, 아이 클라우드를 사용할 앱 기록을 작성
. 이제
func files_saveNotes(rex: Int) {
var localChanges:[CKRecord] = []
let newRecordID = CKRecordID(recordName: sharedDataAccess.returnRexID(index2seek: rex))
let newRecord = CKRecord(recordType: "Blah", recordID: newRecordID)
let theLinkID = CKReference(recordID: sharedDataAccess.iCloudID, action: .deleteSelf)
let thePath = sharedDataAccess.fnGet(index2seek: rex)
newRecord["theLink"] = theLinkID
newRecord["theBLAHnumber"] = rex as CKRecordValue?
newRecord["theBLAHpath"] = thePath as CKRecordValue?
localChanges.append(newRecord)
let records2Erase:[CKRecordID] = []
let saveRecordsOperation = CKModifyRecordsOperation(recordsToSave: localChanges, recordIDsToDelete: records2Erase)
saveRecordsOperation.savePolicy = .allKeys
saveRecordsOperation.perRecordCompletionBlock = { record, error in
if error != nil {
//print(error!.localizedDescription)
}
// deal with conflicts
// set completionHandler of wrapper operation if it's the case
}
saveRecordsOperation.modifyRecordsCompletionBlock = { savedRecords, deletedRecordIDs, error in
self.theApp.isNetworkActivityIndicatorVisible = false
guard error == nil else {
if let ckerror = error as? CKError {
if ckerror.code == CKError.requestRateLimited {
let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
DispatchQueue.main.async {
Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.files_saveNotes), userInfo: nil, repeats: false)
}
} else if ckerror.code == CKError.zoneBusy {
let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
DispatchQueue.main.async {
Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.files_saveNotes), userInfo: nil, repeats: false)
}
} else if ckerror.code == CKError.limitExceeded {
let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
DispatchQueue.main.async {
Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.files_saveNotes), userInfo: nil, repeats: false)
}
} else if ckerror.code == CKError.notAuthenticated {
NotificationCenter.default.post(name: Notification.Name("noCloud"), object: nil, userInfo: nil)
} else if ckerror.code == CKError.networkFailure {
NotificationCenter.default.post(name: Notification.Name("networkFailure"), object: nil, userInfo: nil)
} else if ckerror.code == CKError.networkUnavailable {
NotificationCenter.default.post(name: Notification.Name("noWiFi"), object: nil, userInfo: nil)
} else if ckerror.code == CKError.quotaExceeded {
NotificationCenter.default.post(name: Notification.Name("quotaExceeded"), object: nil, userInfo: nil)
} else if ckerror.code == CKError.partialFailure {
NotificationCenter.default.post(name: Notification.Name("partialFailure"), object: nil, userInfo: nil)
} else if (ckerror.code == CKError.internalError || ckerror.code == CKError.serviceUnavailable) {
NotificationCenter.default.post(name: Notification.Name("serviceUnavailable"), object: nil, userInfo: nil)
}
} // end of guard statement
return
}
if error != nil {
print(error!.localizedDescription)
} else {
print("ok \(savedRecords)")
}
}
saveRecordsOperation.qualityOfService = .background
privateDB.add(saveRecordsOperation)
theApp.isNetworkActivityIndicatorVisible = true
}
여기에서 많은이 저를 용서, 나는 상세하게 모두 설명 할 시간이 없다,하지만 기록 방식은,이 코드에 CKRecord 생성 호출 4 번째 줄에서 레코드 유형을 제공 이 경우에는 "Blah"라고 불립니다.
[스키마] 내의 필드는 코드에서 자세히 설명해야하므로 여기서는 theLink, BLAHnumber 및 BLAHpath를 사용합니다. 이 정보는 다운로드되지 않으며 제작에 들어가면 변경할 수 없습니다. 따라서 새로운 스키마는 새로운 레코드 유형이어야하며 현재 업데이트 된 필드 업데이트를 통해 앱이 이전 버전인지 확인해야합니다. 호환 가능. 희망은 물건을 조금 더 분명하게하는 데 도움이됩니다.
이 기사 https://www.shinobicontrols.com/blog/ios8-day-by-day-day-33-cloudkit은 전체 주제에 대해 자세히 설명합니다. Atomic 커밋, 특히 여기에 귀하의 질문 중 하나가 언급되어 있습니다.
아, 내 질문 중 하나에 답변했습니다. 버그가 수정되었음을 알았습니다. http://stackoverflow.com/questions/31108576/cloudkit-push-notifications-on-record-update-stopped-working – Jules