我对Cloud Kit有以下疑问
func cloudKitManageUserPublicTable (typeOfOperation: Int, encriptedBabyName: String?, encriptedOllyKey:String?, result: (error: NSError?, userHasBeenFound: Bool?, ollYKeyHasBeenFound: Bool?, encriptedBabyNameFound: String?) -> Void){
// OPERATION TYPES
// 1 - search for user and add, link or update a key
// 2 - search for user and check he has a key
// 3 - search for a key
// 4 - search for user and add a default one if has not been found
print("cloudKitManageUserPublicTable - operation \(typeOfOperation)")
var recordCounter = 0
var publicUserRecord = CKRecord(recordType: "PublicUsers")
let useriCloudID = NSUserDefaults.standardUserDefaults().objectForKey("useriCloudID") as! String
var predicate = NSPredicate()
switch typeOfOperation {
case 1:
predicate = NSPredicate(format: "useriCloudID == %@", useriCloudID)
case 2:
predicate = NSPredicate(format: "useriCloudID == %@", useriCloudID)
case 3:
predicate = NSPredicate(format: "encriptedOllyKey == %@", encriptedOllyKey!)
default:
print("no scenarios")
}
let cloudKitQuery = CKQuery(recordType: "PublicUsers", predicate: predicate)
let queryOperation = CKQueryOperation(query: cloudKitQuery)
let operationQueue = NSOperationQueue()
let publicDatabase = CKContainer.defaultContainer().publicCloudDatabase;
queryOperation.database = publicDatabase
queryOperation.recordFetchedBlock = { (record : CKRecord) -> Void in
publicUserRecord = record
recordCounter += 1
}
queryOperation.queryCompletionBlock = { (cursor: CKQueryCursor?, error: NSError?) -> Void in
print("cloudKitManageUserPublicTable - # of record found - \(recordCounter)")
if error != nil
{
// ERROR STOP
print("cloudKitManageUserPublicTable - error - \(error)")
result(error: error, userHasBeenFound: nil, ollYKeyHasBeenFound: nil, encriptedBabyNameFound: nil)
}
else
{
switch typeOfOperation {
case 1:
// KEY FOUND, UPDATE
print("cloudKitManageUserPublicTable - search for user and add or update a key")
publicUserRecord["encriptedBabyName"] = encriptedBabyName!
publicUserRecord["encriptedOllyKey"] = encriptedOllyKey!
publicUserRecord["hasKey"] = true
publicDatabase.saveRecord(publicUserRecord) { (CKRecord: CKRecord?, error: NSError?) -> Void in
if error != nil
{
print("cloudKitManageUserPublicTable - creating key - UPDATE error \(error)")
result(error: error, userHasBeenFound: nil, ollYKeyHasBeenFound: nil, encriptedBabyNameFound: nil)
}
else
{
print("cloudKitManageUserPublicTable - creating key - UPDATE OK")
result(error: error, userHasBeenFound: nil, ollYKeyHasBeenFound: true, encriptedBabyNameFound: nil)
}
}
case 2:
print("cloudKitManageUserPublicTable - search for user and check it has a key")
if publicUserRecord.objectForKey("hasKey") as? Bool == false
{
print("cloudKitManageUserPublicTable - user do not have a key")
result(error: nil, userHasBeenFound: nil, ollYKeyHasBeenFound: false, encriptedBabyNameFound: nil)
}
else
{
print("cloudKitManageUserPublicTable - user has a key")
result(error: nil, userHasBeenFound: nil, ollYKeyHasBeenFound: true, encriptedBabyNameFound: nil)
}
case 3:
if recordCounter == 0
{
print("cloudKitManageUserPublicTable - no record has this key")
result(error: nil, userHasBeenFound: nil, ollYKeyHasBeenFound: false, encriptedBabyNameFound: nil)
}
else
{
print("cloudKitManageUserPublicTable - \(recordCounter) records have this key")
result(error: nil, userHasBeenFound: nil, ollYKeyHasBeenFound: true, encriptedBabyNameFound: nil)
}
case 4:
if recordCounter == 0
{
// NO USER FOUND, CREATE
print("cloudKitManageUserPublicTable - search for user and add a default one if has not been found")
// publicUserRecord["encriptedBabyName"] = ""
// publicUserRecord["encriptedOllyKey"] = ""
publicUserRecord["hasKey"] = false
publicUserRecord["useriCloudID"] = useriCloudID
publicDatabase.saveRecord(publicUserRecord) { (CKRecord: CKRecord?, error: NSError?) -> Void in
dispatch_async(dispatch_get_main_queue()) {
if error != nil
{
print("cloudKitManageUserPublicTable - no user - CREATE error \(error)")
result(error: nil, userHasBeenFound: false, ollYKeyHasBeenFound: nil, encriptedBabyNameFound: nil)
}
else
{
print("cloudKitManageUserPublicTable - no user found - CREATE ok")
result(error: nil, userHasBeenFound: false, ollYKeyHasBeenFound: nil, encriptedBabyNameFound: nil)
}
}
}
}
else
{
// USER FOUND - DO NOTHING
print("cloudKitManageUserPublicTable - user exists, do nothing for now")
result(error: nil, userHasBeenFound: true, ollYKeyHasBeenFound: nil, encriptedBabyNameFound: nil)
}
default:
print("no scenarios")
}
}
}
operationQueue.addOperation(queryOperation)
}
上面的方法通过下面的方法调用FIRST TIME,我等待完成处理程序返回,然后调用上面的方法进行SECOND TIME,然后验证publicUserRecord["hasKey"] = false
是否设置为false。
但我的问题是。当我调用方法SECOND TIME来验证publicUserRecord["hasKey"]
它返回时尚未保存任何内容。如果我稍等一下并调用该方法来验证第三次的publicUserRecord["hasKey"]
,那么它会找到并验证它。
由于我正在进行同样的调用并且结果已保存在FIRST调用中似乎与苹果服务器有点滞后或者我没有正确使用完成处理程序,dispatch_async,dispatch_sync?有任何想法吗?
func manageUserPublicTable(){
tryAgainButtonOutlet.enabled = false
let spinningActivity = MBProgressHUD.showHUDAddedTo(self.view, animated: true)
spinningActivity.labelText = "Talking to Apple Servers"
spinningActivity.detailsLabelText = "Creating user credentials..."
cloudKitManageUserPublicTable(1) { (error, userExists) -> Void in
dispatch_sync(dispatch_get_main_queue()) {
if error != nil
{
spinningActivity.hide(true)
// let user try again
let optionMenu = UIAlertController(title: nil, message: "Are you all set to upload this record?!", preferredStyle: .ActionSheet)
let tryAgain = UIAlertAction(title: "Try again", style: .Default, handler: {
(alert: UIAlertAction!) -> Void in
self.tryAgainButtonOutlet.enabled = true
})
let cancelAction = UIAlertAction(title: "Not yet...", style: .Cancel, handler: {
(alert: UIAlertAction!) -> Void in
self.tryAgainButtonOutlet.enabled = true
})
optionMenu.addAction(tryAgain)
optionMenu.addAction(cancelAction)
if(isIPad()) {
optionMenu.popoverPresentationController!.permittedArrowDirections = UIPopoverArrowDirection()
optionMenu.popoverPresentationController!.sourceView = self.view
optionMenu.popoverPresentationController!.sourceRect = CGRectMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height / 2.0, 1.0, 1.0)
}
self.presentViewController(optionMenu, animated: true, completion: nil)
}
else
{
spinningActivity.hide(true)
self.manageEncriptedKey()
}
}
}
}
答案 0 :(得分:1)
确实可以在保存数据和检索数据之间留出一些时间。没有说明这可能有多长。通常它不到几秒钟。
所以你必须制作你的应用程序逻辑,以便它不关心它。您已保存记录,因此您的应用已经知道该记录的内容。您可以从回调中传递记录,这样您就不必再次查询。
另一个想法。你的功能有点大我的口味。 1功能中功能太多。这使得阅读起来很困难。理想情况下,函数应该只做一件事。