updateApplicationContext -- what can be passed and how?

So I'm learning about updateApplicationContext the hard way here (mostly due to the fact that there it's extremely hard to debug what's happening on my phone app while running the watch app). The problem I have is this: If I say the following, I get regular updates:

try self.session.updateApplicationContext([MessageKey.LocationCount.rawValue: String(self.receivedLocationCount)])

(straight out of potloc)

If however I try this, I get no updates. I assume something has crashed but there are no logs to let me know:

//currentLocation is a CLLocation
try self.session.updateApplicationContext([MessageKey.LocationCount.rawValue: currentLocation])


My understanding is that I should be able to pass any object to updateApplicationContext, but passing a CLLocation seems to break it, whereas passing a String is fine. Interestingly if I do this, the call does in fact work (though I don't get what I want on the other end, as I want a CLLocation object):

try self.session.updateApplicationContext([MessageKey.LocationCount.rawValue: String(currentLocation)])


There is so little documentation I'm not sure how to go about solving this problem. I really wish potloc's code did smoething more than just pass a string, as it's not trivial to go from a string to a general object here.

It's an ugly hack, but I got around this problem (at least til someone shows me how to do it better) by just having a dictionary entry for each element in the CLLocation object. Not very elegant, but it works for now.

Hi,


you're not able to use any object but property list values only. If you want to transfer a non property list object just wrap it into an NSData object:

            NSData* data = [NSKeyedArchiver archivedDataWithRootObject:someObject];
            [[WCSession defaultSession] updateApplicationContext:@{@"data": data}
                                                           error:&error];


That's it. On the other side of the line you have to unarchive the received data:

    id newData = [applicationContext objectForKey:@"data"];
    if ((newData != nil) && ([newData isKindOfClass:[NSData class]]))
    {
        @try {
            id someObject = [NSKeyedUnarchiver unarchiveObjectWithData:newData];
            if ([someObject isKindOfClass:[WhatEverClassYouNeed class]])
            {


You just need to check if the class you want to archive conforms to NSCoding protocol.


Dirk

As was mentioned at the WWDC session Introducing Watch Connectivity, NSKeyedUnarchiver is not optimized for compactness. Ideally you want to use a serialization method that can fit the object in the least amount of bytes. As an example, converting the object to a dictionary of property list types will produces a pretty good result!

Thanks--though as Viking points out, sounds like it's not the most compact way to go. I guess my hack was the proper workaround for the issue, as I pass only the exact data I want/need. The bigger problem, honestly, was the lack of error messages: everything appeared to be working just fine, only nothing was being passed. I guess with more time and documentation it'll be easier to understand.

By the by, is an array (used to be NSMutableArray, but in Swift it's now just an Array right?) a plist type? And if it is, can I store non-plist items within the array? I'm just trying to figure out how much hacking away at these data sets I'm going to have to do. I think I might use the NSArchiver method even if it's not super compact just for ease's sake since I have objects that need to be transferred that are custom (conform to NSCoding but aren't plist types).

the array should be fine, but it has to be an array containing only plist types. It's a "recursive" requirement 🙂

updateApplicationContext -- what can be passed and how?
 
 
Q