【问题标题】:Passing Dictionary to Watch传递字典观看
【发布时间】:2015-09-07 15:37:52
【问题描述】:

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

iPhoneTableViewController

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 printed (我在 Parse 中有两个 matchups,所以它可能知道有两个对象,这就是为什么它也会抛出两个错误?) em>:

Configured WC Session
error
error

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

观看InterfaceController

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

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

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

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

但是在函数的第一行得到这个错误:

“使用未解析的标识符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
}

【问题讨论】:

  • @Lamar 数据实际上并没有通过,我有一些小东西,我假设一定不对?
  • 其他 WCSession API 是否工作(sendMessage、transferFile)?如果您只发送字符串,applicationContext 是否有效?让 applicationDict = ["matchUp" : "test"]
  • @ccjensen 是的,应用程序上下文对我有用,但我只是没有设置完全适合它工作的东西。而且我不确定我的代码的哪一部分是错误的。
  • matchUp 变量是什么对象类型?我猜它不是property list types 之一
  • 是的,如果它是一个字符串,那么应该可以正常工作(尽管您可能应该将 TableViewController func sendMatchup(matchUp: AnyObject) 中的此方法更改为 func sendMatchup(matchUp: String)。不幸的是,这让我们无法弄清楚原因事情不适合你。你有没有机会提供一个完整的示例项目?

标签: xcode swift parse-platform watchkit watchos-2


【解决方案1】:

错误

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

来自Apple Docs

对于大多数类型的传输,您提供一个 NSDictionary 对象 您要发送的数据。字典的键和值必须 都是属性列表类型,因为数据必须被序列化并且 无线发送。 (如果您需要包含不是属性的类型 列出类型,将它们打包在 NSData 对象中或将它们写入文件 在发送它们之前。)此外,您发送的字典应该是 紧凑且仅包含您真正需要的数据。保持你的 小字典确保它们被快速传输并执行 不要在两台设备上消耗太多电量。

详情

您需要将您的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 它可以帮助您比上面看起来更容易解决这个问题:)

【讨论】:

  • 我在上面添加了“EDIT 1”和“EDIT 2”,这样您就可以确切地看到我做了什么。我确定我没有按照您的建议完全正确,否则它会起作用,所以我想知道您是否可以就我不理解的内容给我一些指导。谢谢!
  • 就像我在回答中提到的那样,您还没有实现我所指的 NSCoding 协议方法hackingwithswift.com/read/12/3/fixing-project-10-nscoding。这就是为什么你得到 -[PFObject encodeWithCoder:]: unrecognized selector sent to instance 0x7fbe80d43f30。至于第二次编辑,只需将 MatchupObject 更改为对象 l。
  • 如果您指的是使用 class Person: NSObject, NSCoding { 的示例,我试过了,但是当我这样做时,class TableViewController: PFQueryTableViewController, WCSessionDelegate, NSCoding { 它给了我一个错误,让我知道“TableViewController 与协议 NSCoding 的冗余一致性” .所以看起来我的班级已经支持NSCoding 协议了吧?
  • 您需要使PFObject 符合NSCoding 而不是viewController。如果您无权修改PFObject,请参考此链接:parse.com/questions/…
  • 所以parse.com/questions/… 意味着为PFObject 类创建一个单独的文件?我想我只是很惊讶通过字典会这么复杂。还是我误会了你?
猜你喜欢
  • 1970-01-01
  • 2021-11-25
  • 2012-12-10
  • 2010-09-29
  • 2015-03-07
  • 1970-01-01
  • 1970-01-01
  • 2015-11-30
  • 1970-01-01
相关资源
最近更新 更多