【问题标题】:Basic iCloud Key-Value storage test failing基本 iCloud 键值存储测试失败
【发布时间】:2016-06-05 00:21:39
【问题描述】:

我想测试 iCloud 键值存储。以下是我采取的步骤:

1) 100美元左右购买苹果开发者账号,等待激活

2) 在开发者区域,我创建了一个 App ID、一个 iCloud 容器、一个配置文件(iOS 开发),并确保它知道我的个人设备。

3) 在 XCode 中创建了一个新的单视图 swift 应用

4) 在应用程序中添加以下代码:didFinishLaunchingWithOptions: 方法:

    let keyStore = NSUbiquitousKeyValueStore.defaultStore()

    #if (arch(i386) || arch(x86_64)) && os(iOS)
        //let DEVICE_IS_SIMULATOR = true
        keyStore.setString("testValue2", forKey: "testKey2")
        let didSync = keyStore.synchronize()
        print("synched: \(didSync)")
    #else
        //let DEVICE_IS_SIMULATOR = false
        let didSync = keyStore.synchronize()
        print("synched: \(didSync)")
        if let theString = keyStore.stringForKey("testKey2") {
            print("the string: \(theString)")
        }
        else {
            print("did not find string with specified key")
        }
    #endif

5) 在5s模拟器上启动应用,确认keyStore.synchronize()返回true。

6) 等待 10 秒

7) 在我的 iPhone 6+ 上启动应用程序,确认 keyStore.synchronize() 返回 true。

8) 可悲的是,它打印出“没有找到具有指定键的字符串”

我做错了什么?

【问题讨论】:

  • 删除对synchronize的调用

标签: ios swift icloud


【解决方案1】:

在这种情况下,您不应致电 synchronize。来自documentation

在内存和磁盘同步期间,此方法会使用之前从 iCloud 收到的更改来更新内存中的键和值集

由于您正在写入内存,然后立即调用synchronize,您的内存值将被缓存值覆盖,对于全新的应用程序,缓存值是空的。系统还没有机会用你刚刚写入的值更新缓存。

您应该在applicationWillEnterForeground 中包含对synchronize 的调用:

建议在应用启动时或返回前台时调用此方法,以确保内存中的键值存储表示是最新的。

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.

    let keyStore = NSUbiquitousKeyValueStore.defaultStore()
    keyStore.synchronize()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(AppDelegate.iCloudChangedNotification(_:)), name: NSUbiquitousKeyValueStoreDidChangeExternallyNotification, object: nil)

    keyStore.setString("testValue2", forKey: "testKey2")
    if let theString = keyStore.stringForKey("testKey2") {
        print("the string: \(theString)")
    }
    else {
        print("did not find string with specified key")
    }  
    return true
}

func iCloudChangedNotification(notification: NSNotification) {
    print("iCloud changed")
    if let userInfo = notification.userInfo {
        if let changeReason = userInfo[NSUbiquitousKeyValueStoreChangeReasonKey] as? NSNumber {
            print("Change reason = \(changeReason)")
        }
        if let changedKeys = userInfo[NSUbiquitousKeyValueStoreChangedKeysKey] as? [String] {
            print("ChangedKeys = \(changedKeys)")
        }          
    }

    let keyStore = NSUbiquitousKeyValueStore.defaultStore()

    if let theString = keyStore.stringForKey("testKey2") {
        print("the string: \(theString)")
    }
    else {
        print("did not find string with specified key")
    }
}

func applicationWillEnterForeground(application: UIApplication) {
        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    let keyStore = NSUbiquitousKeyValueStore.defaultStore()
    keyStore.synchronize()            
}

【讨论】:

  • 不幸的是,这样做并没有改变结果。
  • 我刚刚注意到您正在尝试在两个模拟器之间进行同步;我假设您在两者上都登录了同一个 iCloud 帐户?我更新了我的代码,以显示如何注册 iCloud 更新通知
  • 在模拟器上,您可能还必须使用调试->触发 iCloud 同步才能看到更改
  • Paulw11,我正在尝试在模拟器和真实设备之间进行同步。选择触发 iCloud 同步选项会导致出现错误对话框:操作无法完成。 (BRCloudDocsErrorDomain 错误 2 - 已注销 - 未配置 iCloud Drive)
  • 你在模拟器上登录过你的iCloud账号吗?
猜你喜欢
  • 2016-10-19
  • 2013-08-08
  • 1970-01-01
  • 2017-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-24
  • 2013-06-08
相关资源
最近更新 更多