无法使用 WatchConnectivity (swift) 发送自定义对象
Failed to send custom object using WatchConnectivity (swift)
我试图将我的 swift 对象从 iOS 应用程序传递到手表。但是,我发现它适用于像 NSString 这样的基本类型,但我的自定义对象类型。
我的自定义对象能够转换为 NSData
我已经让我的对象实现了 NSObject 和 NSCoding,效果很好。我可以毫无问题地执行以下操作:
let encodedChordProgression = NSKeyedArchiver.archivedDataWithRootObject(chordProgressions[1])
let decodedChordProgression = NSKeyedUnarchiver.unarchiveObjectWithData(encodedChordProgression) as! ChordProgression
NSLog("get decodedChordProgression = \(decodedChordProgression.description)")
WatchConnectivity 代码适用于 NSString
在iPhone中:
try WatchSessionManager.sharedManager.updateApplicationContext(["data": "mystringishere"])
手表:
dispatch_async(dispatch_get_main_queue()) { [weak self] in
self?.dataSourceChangedDelegates.forEach { [=13=].dataSourceDidUpdate(applicationContext["data"] as! NSString)}
}
有效。
我的带有 WatchConnectivity 的自定义对象失败
但是,当我将对象切换为自己的对象时,由于没有调用dataSourceChangedDelegates
回调函数而失败。即:
在iPhone中:
let encodedChordProgression = NSKeyedArchiver.archivedDataWithRootObject(chordProgressions[1])
try WatchSessionManager.sharedManager.updateApplicationContext(["data": encodedChordProgression])
手表:
dispatch_async(dispatch_get_main_queue()) { [weak self] in
self?.dataSourceChangedDelegates.forEach { [=15=].dataSourceDidUpdate(applicationContext["data"] as! NSData)}
}
和
func dataSourceDidUpdate(encodedChordProgression: NSData) {
let chordProgression = NSKeyedUnarchiver.unarchiveObjectWithData(encodedChordProgression) as! ChordProgression
NSLog("get something here: \(chordProgression.description)")
}
我的尝试和我的问题
我已经尝试阅读 iPhone 应用程序和 Watch 应用程序的 system.log
,但我找不到任何线索,这是我现在遇到的最大问题。
完整代码为:here(签出7f2a72c6004f6580e2a38a2d7fd0ed2cef8a2b2e
)
不幸的是,NSKeyedArchiver/NSKeyedUnarchiver 不会以这种方式工作。这是因为即使您可以在 watchkit 和 iOS 目标之间共享 class 文件,它们与编译器在本质上是不同的 class,因为它们是为不同的体系结构编译的。
我自己解决这个问题(因为我最初尝试做同样的事情)是将我的自定义对象序列化到 json 字典(或者 json NSData,如果你愿意的话) 并发送。这是我制作的 github project,它会自动将您的 swift 对象序列化为 json(特别是考虑到这个用例)。
我用 "NSKeyedArchiver/NSKeyedUnarchiver"
试过了,效果很好。
无需进行 序列化 等等。
你的字典应该有相同类型的数据,Archiver 做得很好。
我试图将我的 swift 对象从 iOS 应用程序传递到手表。但是,我发现它适用于像 NSString 这样的基本类型,但我的自定义对象类型。
我的自定义对象能够转换为 NSData
我已经让我的对象实现了 NSObject 和 NSCoding,效果很好。我可以毫无问题地执行以下操作:
let encodedChordProgression = NSKeyedArchiver.archivedDataWithRootObject(chordProgressions[1])
let decodedChordProgression = NSKeyedUnarchiver.unarchiveObjectWithData(encodedChordProgression) as! ChordProgression
NSLog("get decodedChordProgression = \(decodedChordProgression.description)")
WatchConnectivity 代码适用于 NSString
在iPhone中:
try WatchSessionManager.sharedManager.updateApplicationContext(["data": "mystringishere"])
手表:
dispatch_async(dispatch_get_main_queue()) { [weak self] in
self?.dataSourceChangedDelegates.forEach { [=13=].dataSourceDidUpdate(applicationContext["data"] as! NSString)}
}
有效。
我的带有 WatchConnectivity 的自定义对象失败
但是,当我将对象切换为自己的对象时,由于没有调用dataSourceChangedDelegates
回调函数而失败。即:
在iPhone中:
let encodedChordProgression = NSKeyedArchiver.archivedDataWithRootObject(chordProgressions[1])
try WatchSessionManager.sharedManager.updateApplicationContext(["data": encodedChordProgression])
手表:
dispatch_async(dispatch_get_main_queue()) { [weak self] in
self?.dataSourceChangedDelegates.forEach { [=15=].dataSourceDidUpdate(applicationContext["data"] as! NSData)}
}
和
func dataSourceDidUpdate(encodedChordProgression: NSData) {
let chordProgression = NSKeyedUnarchiver.unarchiveObjectWithData(encodedChordProgression) as! ChordProgression
NSLog("get something here: \(chordProgression.description)")
}
我的尝试和我的问题
我已经尝试阅读 iPhone 应用程序和 Watch 应用程序的 system.log
,但我找不到任何线索,这是我现在遇到的最大问题。
完整代码为:here(签出7f2a72c6004f6580e2a38a2d7fd0ed2cef8a2b2e
)
NSKeyedArchiver/NSKeyedUnarchiver 不会以这种方式工作。这是因为即使您可以在 watchkit 和 iOS 目标之间共享 class 文件,它们与编译器在本质上是不同的 class,因为它们是为不同的体系结构编译的。
我自己解决这个问题(因为我最初尝试做同样的事情)是将我的自定义对象序列化到 json 字典(或者 json NSData,如果你愿意的话) 并发送。这是我制作的 github project,它会自动将您的 swift 对象序列化为 json(特别是考虑到这个用例)。
我用 "NSKeyedArchiver/NSKeyedUnarchiver"
试过了,效果很好。
无需进行 序列化 等等。
你的字典应该有相同类型的数据,Archiver 做得很好。