[[WCSession defaultSession] sendMessage:applicationData replyHandler:^(NSDictionary *reply) {}
我只得到第一个视图控制器的响应,并在第二个viewcontroller中得到错误
Error Domain=WCErrorDomain Code=7011 "Message reply Failed." UserInfo={NSUnderlyingError=0x79f1f100 {Error Domain=WCErrorDomain Code=7010 "Payload contains unsupported type." UserInfo={NSLocalizedRecoverySuggestion=Only pass valid types.,NSLocalizedDescription=Payload contains unsupported type.}},NSLocalizedDescription=Message reply Failed.}
WCSession在app和watch扩展中启动.任何建议?
解决方法
- session:didReceiveMessage:replyHandler:
方法中,replyHandler参数定义为[String:AnyObject]. AnyObject部分具有误导性.它只能包含
property list数据类型:
NSData
,NSString
,NSArray
,NSDictionary
,NSDate
,and NSNumber
.(在这种情况下,为什么选择AnyObject是有道理的,因为除了NSObject之外,这6种数据类型不会从公共子类继承.)
通常有人提到NSCoding and NSKeyedArchiver可以解决这个问题,但除此之外我还没有看到更多的例子/解释.
需要注意的是,replyHandler字典并不关心序列化.您可以使用NSKeyedArchiver,JSON,您自己的自定义编码等.只要字典只包含那6种数据类型,replyHandler就会很高兴.否则,您将看到Payload包含不受支持的类型.错误.
因此,您永远不能像这样调用回复处理程序:replyHandler([“response”:myCustomObject),即使myCustomObject完美地实现了NSCoding协议.
编码选择摘要:
> NSCoding:主要优点是当你取消归档时,它会自动找到正确的类并为你实例化它,包括其子图中的任何对象.
> JSON
>自定义编码:一个优点是您的对象不会被强制从NSObject继承,这在Swift中有时很有帮助.
如果您使用NSCoding,这就是它的样子:
iPhone App:
func session(session: WCSession,didReceiveMessage message: [String : AnyObject],replyHandler: ([String : AnyObject]) -> Void) { let data = NSKeyedArchiver.archivedDataWithRootObject(myCustomObject) replyHandler(["response": data]) }
观看应用:
WCSession.defaultSession().sendMessage([],replyHandler: { response -> Void in let myCustomObject = NSKeyedUnarchiver.unarchiveObjectWithData(response["response"]) },errorHandler: nil )
请注意,如果要在取消归档对象时从崩溃中恢复,则需要使用新的iOS 9 API,unarchiveTopLevelObjectWithData,如果出现问题则会抛出错误.
注意:您的自定义对象必须从NSObject继承,否则归档时会出现以下错误:
*** NSForwarding: warning: object … of class ‘Foo’ does not implement methodSignatureForSelector: — trouble ahead Unrecognized selector -[Foo replacementObjectForKeyedArchiver:]