3

我正在尝试将存储的CLLocation对象从我的 iOS 应用程序传递回扩展程序(在这种情况下:Apple Watch 扩展程序)。

为此,我在扩展代码中使用类中推荐的openParentApplication(userInfo: [NSObject : AnyObject]!, reply: (([NSObject : AnyObject]!, NSError!) -> Void)!) -> Bool函数。WKInterfaceController我通过应用程序委托的application(application: UIApplication!, handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]!, reply: (([NSObject : AnyObject]!) -> Void)!)功能在我的 iOS 应用程序中成功接收了请求。

现在,我正在尝试使用以下代码将数据传递回应用程序扩展:

    var results = [NSObject: AnyObject]()
    if let loc = getLastKnownLocation() {
        results["hasLoc"] = "yes"
        results["locStr"] = "\(loc)"
        results["results"] = loc // at this point, loc is actually a valid CLLocation object
    }
    reply(results)

所有这些代码都在 iOS 应用程序的上下文中执行,并且一切正常。但是,当reply在扩展的上下文中调用函数时,字典最终会变为nil.

    InterfaceController.openParentApplication(parentValues, reply: {(values, error) -> Void in
        NSLog("\(values) (err: \(error))") // echoed back to the console: "nil (err: nil)"
    })

我意识到有故障的线路是这个:

                results["results"] = loc

当这一行被注释时,扩展成功地获得了一个字典,其中包含两个前两个项目作为字符串("hasLoc""locStr"):

[locStr: Optional(<+37.33756323,-122.04115699> +/- 10.00m (speed 5.00 mps / course 272.00) @ 21/12/2014 19:20:05 heure normale d’Europe centrale), hasLoc: yes] (err: nil)

所以似乎CLLocation在我的字典中插入一个对象会使它全部失败并成为nil,但我不明白为什么。我究竟做错了什么?

谢谢你的帮助。

编辑:根据@matt 的要求,这是以下代码getLastKnownLocation()

class func getLastKnownLocation() -> CLLocation? {
    return NSKeyedUnarchiver.unarchiveObjectWithData(NSUserDefaults(suiteName: AppHelper.appGroupName)!.dataForKey("UserLastLocation")!) as CLLocation?
}
4

2 回答 2

4

我在文档中读到:“字典的内容必须可序列化为属性列表文件。” 但是 CLLocation 不能以这种方式序列化。大概您必须(再次)将其包装在 NSData 中,然后再将其粘贴到字典中以越过障碍。

于 2014-12-21T18:37:15.487 回答
2

Apple 文档指出,“字典的内容必须可序列化为属性列表文件。” CLLocation 不能以这种方式序列化。为了将它包含在此上下文中返回的 NSDictionary 中,您需要将其包装为 NSData 对象。这很简单。CLLocation 支持 NSSecureCoding,您可以像这样使用 NSKeyedArchiver:

CLLocation *myLocationToStore = ...; // (a CLLocation object)
NSData *locationData = [NSKeyedArchiver archivedDataWithRootObject:myLocationToStore];

然后可以将其添加到 NSDictionary,传递给应用程序扩展,然后在另一端解码,就像使用 NSKeyedUnarchiver 一样简单:

CLLocation *myStoredLocation = (CLLocation *)[NSKeyedUnarchiver unarchiveObjectWithData:locationData];

Swift 等价函数是:

class func archivedDataWithRootObject(_ rootObject: AnyObject) -> NSData]
class func unarchiveObjectWithData(_ data: NSData) -> AnyObject?
于 2015-01-08T19:44:40.467 回答