将字典传递给手表

Passing Dictionary to Watch

我正在尝试 通过 Application Context 方法使用后台传输通过 Watch Connectivity 从 iPhone -> Watch 传递数据。

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")
                    }
                }
            }
        }
    }

}

我在日志 中得到 error 两次 print(我在 Parse 中有两个 matchup,所以也许它知道有两个对象,那就是为什么它也抛出两个错误?):

Configured WC Session
error
error

所以我什至还没有达到可以在 Watch 应用程序中 print 查看 matchup 是否正确通过的地步。

观看InterfaceController:

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

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

有什么想法吗?将 post 您需要的任何额外代码。谢谢!

编辑 1:

根据 EridB 的回答,我尝试将编码 添加到 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")
                    }
                }
            }
        }
    }

}

但是在日志中得到这个:

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

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

编辑 2:

根据 EridB 的回答,我还尝试将函数粘贴到我的代码中:

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)
}

但是在函数的第一行出现这个错误:

"Use of unresolved identifer MatchupObject"

我确定我一定没有理解如何正确使用 EridB 的答案。

编辑 3:

NSCoder 方法:

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
}

错误

您收到该错误,因为您将不符合 NSCodingNSObject (MatchupObject) 放入要传递的字典中。

来自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.

详情

您需要将 NSObject's 存档到 NSData,然后将其放入 NSDictionary。如果您存档一个不符合 NSCodingNSObject,则 NSData 将是 nil

这个 example 很好地展示了如何使 NSObject 符合 NSCoding,如果你实现这些东西,那么你只需遵循下面的代码:

//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
}

由于你使用的是Parse,修改对象可能无法完成(我已经有一段时间没有使用Parse,所以IDK 当然),但是从他们的论坛我发现了这个问题:https://parse.com/questions/is-there-a-way-to-serialize-a-parse-object-to-a-plain-string-or-a-json-string 比上面看起来的更容易帮助你解决这个问题 :)