Swift 尝试将CLLocation对象传回iOS应用程序扩展时,Dictionary变为nil
我正试图将一个存储的Swift 尝试将CLLocation对象传回iOS应用程序扩展时,Dictionary变为nil,swift,dictionary,cllocation,watchkit,apple-watch,Swift,Dictionary,Cllocation,Watchkit,Apple Watch,我正试图将一个存储的CLLocation对象从我的iOS应用程序传递回一个扩展(在这种情况下:一个Apple Watch扩展) 为此,我正在使用扩展代码中的WKInterfaceController类中推荐的openParentApplication(userInfo:[NSObject:AnyObject]!,reply:([NSObject:AnyObject]!,NSError!)->Void)!->Bool函数。我正在通过应用程序代理的应用程序(应用程序:UIApplication!,h
CLLocation
对象从我的iOS应用程序传递回一个扩展(在这种情况下:一个Apple Watch扩展)
为此,我正在使用扩展代码中的WKInterfaceController
类中推荐的openParentApplication(userInfo:[NSObject:AnyObject]!,reply:([NSObject:AnyObject]!,NSError!)->Void)!->Bool
函数。我正在通过应用程序代理的应用程序(应用程序:UIApplication!,handleWatchKitExtensionRequest用户信息:[NSObject:AnyObject]!,回复:([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”
):
我在文档中读到:“字典的内容必须可以序列化为属性列表文件。”但是CLLocation不能以这种方式序列化。大概您必须(再次)将其包装在NSData中,然后才能将其粘贴到字典中以通过屏障。指出,“字典的内容必须可序列化为属性列表文件。”CLLocation不能以这种方式序列化。为了将其包含在此上下文中返回的NSDictionary中,需要将其包装为NSData对象。这很简单。CLLocation支持NSSecureCodeding,您可以使用如下NSKeyedArchiver:
CLLocation *myLocationToStore = ...; // (a CLLocation object)
NSData *locationData = [NSKeyedArchiver archivedDataWithRootObject:myLocationToStore];
然后可以将其添加到NSKeyedUnachiver,传递到应用程序扩展,然后在另一端解码,就像使用NSKeyedUnachiver一样简单:
CLLocation *myStoredLocation = (CLLocation *)[NSKeyedUnarchiver unarchiveObjectWithData:locationData];
这些措施包括:
@matt,请看我的问题更新。我想这只是因为
locStr
是loc
变量的字符串表示,正如您所知,它是可选的CLLocation?
。现在我明白您的意思了。但我只是将更改为CLLocation?
为为CLLocation
,将函数签名更改为CLLocation
,而不是CLLocation?
。它没有解决问题,但是现在locStr
不再显示为“可选”
。是的,我不得不将其重构为让loc=getlastnownlocation()
,但是CLLocation
仍然无法进入扩展应用程序,只有值类型似乎被转移。第三次幸运?。。。试试看会发生什么。是的,你走对了!现在我设法将字节返回到扩展,但目前无法将其转换回CLLocation
对象。我正在使用NSKeyedArchiver
和NSKeyedArchiver
但它不会转换回来……没关系。。。我正在转换到CLLocation
所有字典项,甚至字符串
s。。。现在它可以工作了,只是在NSData
之间来回转换不是很方便,但至少它可以工作!谢谢@matt!为所有错误的答案感到抱歉;手表套件是新的。我和你一起学习!谢谢你让我这么做。别难过,你帮了我很多。我来自ObjC,同时学习WatchKit和Swift,非常欢迎您的帮助:)
CLLocation *myLocationToStore = ...; // (a CLLocation object)
NSData *locationData = [NSKeyedArchiver archivedDataWithRootObject:myLocationToStore];
CLLocation *myStoredLocation = (CLLocation *)[NSKeyedUnarchiver unarchiveObjectWithData:locationData];
class func archivedDataWithRootObject(_ rootObject: AnyObject) -> NSData]
class func unarchiveObjectWithData(_ data: NSData) -> AnyObject?