Rud*_*.kh 5 iphone objective-c ios apple-watch wcsession
我有一个 iOS 应用程序,我在 appleWatch 上为它编写了一个扩展程序。我正在使用 transferUserInfo 方法将数据(NSDictionary)发送到 appleWatch 扩展。一切都在模拟器中运行,但是当我尝试在真实设备上运行应用程序时,虽然 iPhone 正在发送数据,但 iWatch 似乎没有收到任何信息(我发现这是因为我调试了发送方)。
我已经在两边配置了 WCSession。我已经在我应该接收数据的类中符合 WCSessionDelegate 。我正在使用 session:didReceiveUserInfo: 方法在 ExtensionDelegate 中接收数据,但仍然像我说的那样在模拟器中一切正常,但在真实设备上没有传输任何内容。
有没有人知道问题是什么?
这是代码:在发送方:
在我的班级 MensaViewController.m 中
- (void)viewDidLoad
if ([WCSession isSupported]) {
session = [WCSession defaultSession];
session.delegate = self;
[session activateSession];
}
NSLog(@"A dish is being sent");
[session transferUserInfo:dishDictionary];
}
Run Code Online (Sandbox Code Playgroud)
discDictionary 在 viewDidLoad 方法中声明,它包含数据。
在接收器端(Watch Extension),我配置 WCSession 并在 ExtensionDelegate.m 中接收数据,如下所示:
- (void)applicationDidBecomeActive {
if ([WCSession isSupported]) {
session = [WCSession defaultSession];
session.delegate = self;
[session activateSession];
NSLog(@"Session activated in iWatch");
}
}
Run Code Online (Sandbox Code Playgroud)
我有这个方法来接收数据:
- (void)session:session didReceiveUserInfo:(NSDictionary<NSString *,id> *)userInfo{
NSLog(@"Received data from the iPhone");
NSArray<NSString*> *dictionaryKeys = userInfo.allKeys;
for(int i = 0; i < dictionaryKeys.count; i++){
Boolean equalsMensaString = [dictionaryKeys[i] isEqualToString:@"beilagen"];
if(equalsMensaString)
[self handleTransferredDish:userInfo];
Boolean equalsNewsString = [dictionaryKeys[i] isEqualToString:@"article"];
if(equalsNewsString)
[self handleTransferredNews:userInfo];
Boolean equalsEventString = [dictionaryKeys[i] isEqualToString:@"description"];
if(equalsEventString)
[self handleTransferredEvents:userInfo];
}
}
Run Code Online (Sandbox Code Playgroud)
如果您查看sources函数描述,您可以看到用于传输数据的方法的描述:
public func transferUserInfo(userInfo: [String : AnyObject]) -> WCSessionUserInfoTransfer
Run Code Online (Sandbox Code Playgroud)
系统会将用户信息字典入队,并在适当的时候将其传输到对应的应用程序。发送应用程序退出后,用户信息的传输将继续。如果文件成功到达,对应的应用程序将在下次启动时收到委托回调。userInfo 字典只能接受属性列表类型。
所以..不能保证系统会userInfo在您实际使用该应用程序时发送此信息。
请改用以下方法:
public func sendMessage(message: [String : AnyObject], replyHandler: (([String : AnyObject]) -> Void)?, errorHandler: ((NSError) -> Void)?)
Run Code Online (Sandbox Code Playgroud)
客户端可以使用此方法向对方应用程序发送消息。希望接收特定消息回复的客户端应传入replyHandler 块。如果无法发送消息或无法接收回复,则将调用 errorHandler 块并出现错误。如果同时指定了replyHandler和errorHandler,那么将调用其中之一。消息只能在发送应用程序运行时发送。如果发送应用程序在消息发送之前退出,则发送将失败。如果对应应用程序未运行,则对应应用程序将在收到消息后启动(仅限 iOS 对应应用程序)。消息字典只能接受属性列表类型。
并用于接收:
func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void)
Run Code Online (Sandbox Code Playgroud)
请注意: 如果对方应用程序未打开或会话未配对且未激活,则此发送可能会失败。因此,如果您不能错过任何应该使用的数据
updateApplicationContext或transferUserInfo(我实际上更喜欢updateApplicationContext)
session.sendMessage(messageData, replyHandler: { (replyData) -> Void in
replyHandler?(replyData)
}, errorHandler: { (error) -> Void in
print("error: code:\(error.code) - \(error.localizedDescription)")
errorHandler?(error)
do {
try session.updateApplicationContext(messageData)
} catch {
print("There was an error trying to update watchkit app on the background")
}
})
Run Code Online (Sandbox Code Playgroud)
并确保您收到此案例时正确实施了
func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject])