Passing Dictionary to Watch

一曲冷凌霜 提交于 2019-12-23 04:31:59

问题


I'm trying to pass data from iPhone -> Watch via Watch Connectivity using background transfer via Application Context method.

iPhone TableViewController

private func configureWCSession() {
    session?.delegate = self;
    session?.activateSession()
    print("Configured WC Session")
}

func getParsePassData () {
    let gmtTime = NSDate()

    // Query Parse
    let query = PFQuery(className: "data")
    query.whereKey("dateGame", greaterThanOrEqualTo: gmtTime)

    query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error:NSError?) -> Void in
        if error == nil
        {
            if let objectsFromParse = objects as? [PFObject]{
                for MatchupObject in objectsFromParse
                {
                    let matchupDict = ["matchupSaved" : MatchupObject]

                    do {
                        try self.session?.updateApplicationContext(matchupDict)
                        print("getParsePassData iPhone")
                    } catch {
                        print("error")
                    }
                }
            }
        }
    }

}

I'm getting error twice printed in the log (I have two matchups in Parse so maybe it knows there's two objects and thats why its throwing two errors too?):

Configured WC Session
error
error

So I haven't even gotten to the point where I can print it in the Watch app to see if the matchups passed correctly.

Watch InterfaceController:

func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) {
    let matchupWatch = applicationContext["matchupSaved"] as? String

    print("Matchups: %@", matchupWatch)
}

Any ideas? Will post any extra code that you need. Thanks!

EDIT 1:

Per EridB answer, I tried adding encoding into getParsePassData

func getParsePassData () {
    let gmtTime = NSDate()

    // Query Parse
    let query = PFQuery(className: "data")
    query.whereKey("dateGame", greaterThanOrEqualTo: gmtTime)

    query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error:NSError?) -> Void in
        if error == nil
        {
            if let objectsFromParse = objects as? [PFObject]{
                for MatchupObject in objectsFromParse
                {
                    let data = NSKeyedArchiver.archivedDataWithRootObject(MatchupObject)

                    let matchupDict = ["matchupSaved" : data]

                    do {
                        try self.session?.updateApplicationContext(matchupDict)
                        print("getParsePassData iPhone")
                    } catch {
                        print("error")
                    }
                }
            }
        }
    }

}

But get this in the log:

-[PFObject encodeWithCoder:]: unrecognized selector sent to instance 0x7fbe80d43f30

*** -[NSKeyedArchiver dealloc]: warning: NSKeyedArchiver deallocated without having had -finishEncoding called on it.

EDIT 2:

Per EridB answer, I also tried just pasting the function into my code:

func sendObjectToWatch(object: NSObject) {
    //Archiving
    let data = NSKeyedArchiver.archivedDataWithRootObject(MatchupObject)

    //Putting it in the dictionary
    let matchupDict = ["matchupSaved" : data]

    //Send the matchupDict via WCSession
    self.session?.updateApplicationContext(matchupDict)
}

But get this error on the first line of the function:

"Use of unresolved identifer MatchupObject"

I'm sure I must not be understanding how to use EridB's answer correctly.

EDIT 3:

NSCoder methods:

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)!
    //super.init(coder: aDecoder)

    configureWCSession()

    // Configure the PFQueryTableView
    self.parseClassName = "data"
    self.textKey = "matchup"
    self.pullToRefreshEnabled = true
    self.paginationEnabled = false
}

回答1:


Error

You are getting that error, because you are putting a NSObject (MatchupObject) which does not conform to NSCoding inside the dictionary that you are going to pass.

From Apple Docs

For most types of transfers, you provide an NSDictionary object with the data you want to send. The keys and values of your dictionary must all be property list types, because the data must be serialized and sent wirelessly. (If you need to include types that are not property list types, package them in an NSData object or write them to a file before sending them.) In addition, the dictionaries you send should be compact and contain only the data you really need. Keeping your dictionaries small ensures that they are transmitted quickly and do not consume too much power on both devices.

Details

You need to archive your NSObject's to NSData and then put it in the NSDictionary. If you archive a NSObject which does not conform to NSCoding, the NSData will be nil.

This example greatly shows how to conform a NSObject to NSCoding, and if you implement these things then you just follow the code below:

//Send the dictionary to the watch
func sendObjectToWatch(object: NSObject) {
    //Archiving
    let data = NSKeyedArchiver.archivedDataWithRootObject(MatchupObject)

    //Putting it in the dictionary
    let matchupDict = ["matchupSaved" : data]

    //Send the matchupDict via WCSession
    self.session?.updateApplicationContext(matchupDict)
}

//When receiving object from the other side unarchive it and get the object back
func objectFromData(dictionary: NSDictionary) ->  MatchupObject {
    //Load the archived object from received dictionary
    let data = dictionary["matchupSaved"]

    //Deserialize data to MatchupObject
    let matchUpObject = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! MatchupObject

    return matchUpObject
}

Since you are using Parse, modifying an object maybe cannot be done (I haven't used Parse in a while, so IDK for sure), but from their forum I found this question: https://parse.com/questions/is-there-a-way-to-serialize-a-parse-object-to-a-plain-string-or-a-json-string which can help you solve this problem easier than it looks above :)



来源:https://stackoverflow.com/questions/32442129/passing-dictionary-to-watch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!