简体   繁体   中英

Failed to send custom object using WatchConnectivity (swift)

I was trying to pass my swift object from the iOS app to the Watch. However, I found it works for basic types like NSString, but my custom object type.

My custom object is able to cast to NSData

I've made my object implement NSObject and NSCoding, which works well. I can do following without problem:

let encodedChordProgression = NSKeyedArchiver.archivedDataWithRootObject(chordProgressions[1])
let decodedChordProgression = NSKeyedUnarchiver.unarchiveObjectWithData(encodedChordProgression) as! ChordProgression
NSLog("get decodedChordProgression = \(decodedChordProgression.description)")

WatchConnectivity code works for NSString

In iPhone:

try WatchSessionManager.sharedManager.updateApplicationContext(["data": "mystringishere"])

with Watch:

dispatch_async(dispatch_get_main_queue()) { [weak self] in
    self?.dataSourceChangedDelegates.forEach { $0.dataSourceDidUpdate(applicationContext["data"] as! NSString)}
}

works.

My custom object with WatchConnectivity Failed

However, when I switch the object to my own object, it failed by not calling the dataSourceChangedDelegates callback function. That is:

In iPhone:

let encodedChordProgression = NSKeyedArchiver.archivedDataWithRootObject(chordProgressions[1])
try WatchSessionManager.sharedManager.updateApplicationContext(["data": encodedChordProgression])

with Watch:

dispatch_async(dispatch_get_main_queue()) { [weak self] in
    self?.dataSourceChangedDelegates.forEach { $0.dataSourceDidUpdate(applicationContext["data"] as! NSData)}
}

and

func dataSourceDidUpdate(encodedChordProgression: NSData) {
    let chordProgression = NSKeyedUnarchiver.unarchiveObjectWithData(encodedChordProgression) as! ChordProgression
    NSLog("get something here: \(chordProgression.description)")
}

What I've tried & my problem

I've tried to read the system.log of both the iPhone app and Watch app, but I couldn't find any clue, which is the biggest problem I have now.

The full code is: here (checkout 7f2a72c6004f6580e2a38a2d7fd0ed2cef8a2b2e )

NSKeyedArchiver/NSKeyedUnarchiver won't work in this way unfortunately. This is because even though you may share class files between your watchkit and iOS targets, they are essentially different classes to the compiler because they are compiled for different architectures.

What I have done to get around this issue myself (because I initially tried to do the same thing) is serialize my custom objects to a json dictionary (or json NSData if you like) and send that. Here is a github project I have made that automatically serializes your swift objects to json for you (specifically with this use case in mind).

I tried with "NSKeyedArchiver/NSKeyedUnarchiver" and this is working perfectly. no need to go for serialization and all. your dictionary should have same type of data and Archiver is doing it very well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM