使用suiteName检测NSUserDefaults中的更改

时间:2016-07-26 19:07:08

标签: ios swift nsuserdefaults watchkit watch-os-2

在我的项目中,我使用app group将数据传输到Apple watch! 看起来像这样

let sharedDefaults = NSUserDefaults(suiteName: "group.com.myappname.defaults")
sharedDefaults?.setObject(MyData, forKey: "DataKey")
sharedDefaults?.synchronize()

在WKInterfaceController中,我使用以下代码获取数据:

let sharedDefaults = NSUserDefaults(suiteName: "group.com.myappname.defaults")
let MyData = sharedDefaults?.objectForKey("DataKey") as! [[AnyObject]]

一切正常!

现在我尝试检测sharedDefaults中的数据?.objectForKey(" DataKey")是否确实发生了变化。我尝试使用addObserver方法:

override func willActivate() {
NSUserDefaults(suiteName: "group.com.myappname.defaults")!.addObserver(self, forKeyPath: "DataKey", options: NSKeyValueObservingOptions.New, context: nil)
}

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>){
      print("Data Changed")
}

但&#34;覆盖func observeValueForKeyPath&#34;只有当WKInterfaceController激活时才调用,当我在NSUserDefaults中更改数据时没有调用(suiteName:&#34; group.com.myappname.defaults&#34;)

我也尝试使用NSNotificationCenter:

override func willActivate() {
let sharedDefaults = NSUserDefaults(suiteName: "group.com.myappname.defaults")
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(userDefaultsDidChangeNotificationMethod(_:)), name: NSUserDefaultsDidChangeNotification, object: nil)
}

func userDefaultsDidChangeNotificationMethod(notification: NSNotification){
 print("Data Changed")
}

它没有用(

我做错了什么?如何检测数据是否发生变化?

2 个答案:

答案 0 :(得分:2)

我知道这是一种不好的方式,但我找不到任何其他人...... 我的方式是无休止的循环:

var NeedCheking = Bool()


override func willActivate() {
        super.willActivate()
        NeedChecking = true
        CheckDefaults()
}

override func didDeactivate() {
    NeedChecking = false
    super.didDeactivate()
}

func CheckDefaults(){

        let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
        dispatch_async(dispatch_get_global_queue(priority, 0)) {

        repeat {

            let sharedDefaults = NSUserDefaults(suiteName: "group.com.myappname.defaults")
            let NewData = sharedDefaults?.objectForKey("DataKey") as! [[AnyObject]]
            if NewData != self.MyData {

                dispatch_async(dispatch_get_main_queue()) {
                    self.MyData = NewData
                    //Here do update actions!
               }
            }
            sleep(2)
        }while self.NeedChecking
    }
    }

如果有人知道其他方式,请发布您的解决方案作为这个问题的答案!

答案 1 :(得分:2)

Relationship between the Watch app interface, the WatchKit extension, and the iOS app

基于这种关系,我认为KVO在watch和ios之间不起作用,如果你想从ios app获得最新数据,有两种方法。

  1. 检查willActivate
  2. 中的最新数据
  3. 后台任务
  4.   

    后台任务是一种让您的应用界面保持最新状态的方法。从系统接收后台任务对象是执行特定类型操作的信号。任务对象定义要执行的任务类型,并包含完成任务所需的任何数据。系统通过调用应用程序扩展委托的handleBackgroundTasks:方法,将后台任务对象传递给您的应用程序。

         

    watchOS支持以下类型的后台任务:

         
        
    • 后台应用刷新任务。使用WKApplicationRefreshBackgroundTask对象来处理应用程序状态的常规更新。例如,您可以使用此类任务来检入公司的服务器或开始下载新内容。您可以从应用程序的WKExtension对象中明确安排此类后台任务。
    •   
    • 后台快照刷新任务。使用WKSnapshotRefreshBackgroundTask对象更新应用程序的界面,准备拍摄快照。此任务完成后,系统会自动拍摄快照。系统会定期计划后台快照刷新任务以更新快照。您还可以在界面更改时从应用程序的WKExtension对象中明确计划此类任务。
    •   
    • 背景观察连接任务。使用WKWatchConnectivityRefreshBackgroundTask对象接收iOS应用程序使用Watch Connectivity框架发送的数据。当您的Watch应用程序从配对的iPhone上运行的相应iOS应用程序接收数据时,系统会自动创建此类任务。您不自行安排此类任务。
    •   
    • 背景NSURLSession任务。使用WKURLSessionRefreshBackgroundTask对象接收先前使用NSURLSession对象请求的数据。当后台传输需要授权或后台传输完成(成功或失败)时,将触发此任务。您不自行安排此类任务。
    •   

    请记住,后台转移可能无法立即发送。文件和上下文数据尽可能快地传递,但传输不是即时的。涉及大文件或大量数据的数据文件也需要相当长的时间才能完成。