如何从 Apple Watch 调用 iPhone 上定义的方法
How to call a method defined on the iPhone from the Apple Watch
是否有任何方法可以从 Watchkit 扩展中调用 iPhone 上的 class 中定义的方法?
据我了解,目前在 Watch kit 和 iPhone 之间进行本地通信的一种方法是使用 NSUserDefaults
,但还有其他方法吗?
一个简单的例子就好了。
根据 Apple 的 WatchKit Programming Guide,您可以使用 openParentApplication
并传递字典与 iPhone 上的 iOS 应用程序通信。父应用程序通过其 AppDelegate
中的 handleWatchKitExtensionsRequest
处理此调用。从那里你可以根据传递的参数调用其他方法。
handleWatchKitExtensionRequest
然后调用reply
方法将参数传回WatchKit扩展:
Watchkit 扩展:
// Call the parent application from Apple Watch
// values to pass
let parentValues = [
"value1" : "Test 1",
"value2" : "Test 2"
]
WKInterfaceController.openParentApplication(parentValues, reply: { (replyValues, error) -> Void in
println(replyValues["retVal1"])
println(replyValues["retVal2"])
})
iOS 应用程序:
// in AppDelegate.swift
func application(application: UIApplication!, handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]!, reply: (([NSObject : AnyObject]!) -> Void)!) {
// retrieved parameters from Apple Watch
println(userInfo["value1"])
println(userInfo["value2"])
// pass back values to Apple Watch
var retValues = Dictionary<String,String>()
retValues["retVal1"] = "return Test 1"
retValues["retVal2"] = "return Test 2"
reply(retValues)
}
请注意,这似乎在 Xcode 6.2 Beta 3 中被破坏了。
在 WatchKit 扩展和 iOS 应用程序之间 'communicate' 有两种主要方式,具体取决于您要完成的任务。
1. openParentApplication:reply:
这将在后台打开您的 iOS 应用程序,并允许您从 iOS 代码执行逻辑并将响应发送回您的扩展程序。例如 -
[InterfaceController openParentApplication:@{ @"command": @"foo" }
reply:^(NSDictionary *replyInfo, NSError *error) {
self.item = replyInfo[@"bar"];
}];
MMWormhole 是一个可以用来管理这些通信的库
2。共享容器
如果您只需要访问您的 iOS 应用程序可以访问的相同数据,您可以跨两个目标实施共享容器。
这可能包括仅使用访问共享的 NSUserDefaults,正如您所提到的,或者一直到使用 Core Data 并访问跨 iOS 和 WatchKit 的共享持久性堆栈。
编程参考 - https://developer.apple.com/library/ios/technotes/tn2408/_index.html
3。单例
也许您只需要从您的 WatchKit 扩展访问共享逻辑,而不需要上述两个选项的复杂性。只要您不在两个目标之间保留任何数据,您就可以创建一个 Singleton class,您可以从您的扩展中调用它来执行您需要的方法。
您可以将 class 添加到两个目标(主要 iOS 应用程序和 WatchKit 扩展)并直接使用 WatchKit 扩展中的方法。
方便地添加 classes(首选实用程序或类别),几乎没有依赖项。
如果文件已经添加到项目中,您可以将其删除(删除引用)并再次添加到多个目标中。
例如,我在项目中的类别 NSString+color 在 iOS app 和 Watch App 中工作正常。
更新:您也可以在右侧面板(实用程序)中执行此操作。请参阅下面的 link:cs621620.vk.me/v621620973/13f86/9XYDH1HL5BI.jpg
对于 WatchOS2 openParentApplication
已弃用。它的替代品是 WCSession
in Watch Connectivity Framework
首先,在 watch(ExtensionDelegate
) 和 iOS(AppDelegate
) 中初始化 WCSession
,代码如下
if WCSession.isSupported() {
let session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
}
使用
从手表向Phone发送通知
session.sendMessage(msg, replyHandler: { (responses) -> Void in
print(responses)
}) { (err) -> Void in
print(err)
}
使用
处理AppDelegate
中的消息
func session(_ session: WCSession,
didReceiveMessage message: [String : AnyObject],
replyHandler replyHandler: ([String : AnyObject]) -> Void)
{
//do something according to the message dictionary
responseMessage = ["key" : "value"] //values for the replyHandler
replyHandler(responseMessage)
}
是否有任何方法可以从 Watchkit 扩展中调用 iPhone 上的 class 中定义的方法?
据我了解,目前在 Watch kit 和 iPhone 之间进行本地通信的一种方法是使用 NSUserDefaults
,但还有其他方法吗?
一个简单的例子就好了。
根据 Apple 的 WatchKit Programming Guide,您可以使用 openParentApplication
并传递字典与 iPhone 上的 iOS 应用程序通信。父应用程序通过其 AppDelegate
中的 handleWatchKitExtensionsRequest
处理此调用。从那里你可以根据传递的参数调用其他方法。
handleWatchKitExtensionRequest
然后调用reply
方法将参数传回WatchKit扩展:
Watchkit 扩展:
// Call the parent application from Apple Watch
// values to pass
let parentValues = [
"value1" : "Test 1",
"value2" : "Test 2"
]
WKInterfaceController.openParentApplication(parentValues, reply: { (replyValues, error) -> Void in
println(replyValues["retVal1"])
println(replyValues["retVal2"])
})
iOS 应用程序:
// in AppDelegate.swift
func application(application: UIApplication!, handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]!, reply: (([NSObject : AnyObject]!) -> Void)!) {
// retrieved parameters from Apple Watch
println(userInfo["value1"])
println(userInfo["value2"])
// pass back values to Apple Watch
var retValues = Dictionary<String,String>()
retValues["retVal1"] = "return Test 1"
retValues["retVal2"] = "return Test 2"
reply(retValues)
}
请注意,这似乎在 Xcode 6.2 Beta 3 中被破坏了。
在 WatchKit 扩展和 iOS 应用程序之间 'communicate' 有两种主要方式,具体取决于您要完成的任务。
1. openParentApplication:reply:
这将在后台打开您的 iOS 应用程序,并允许您从 iOS 代码执行逻辑并将响应发送回您的扩展程序。例如 -
[InterfaceController openParentApplication:@{ @"command": @"foo" }
reply:^(NSDictionary *replyInfo, NSError *error) {
self.item = replyInfo[@"bar"];
}];
MMWormhole 是一个可以用来管理这些通信的库
2。共享容器
如果您只需要访问您的 iOS 应用程序可以访问的相同数据,您可以跨两个目标实施共享容器。
这可能包括仅使用访问共享的 NSUserDefaults,正如您所提到的,或者一直到使用 Core Data 并访问跨 iOS 和 WatchKit 的共享持久性堆栈。
编程参考 - https://developer.apple.com/library/ios/technotes/tn2408/_index.html
3。单例
也许您只需要从您的 WatchKit 扩展访问共享逻辑,而不需要上述两个选项的复杂性。只要您不在两个目标之间保留任何数据,您就可以创建一个 Singleton class,您可以从您的扩展中调用它来执行您需要的方法。
您可以将 class 添加到两个目标(主要 iOS 应用程序和 WatchKit 扩展)并直接使用 WatchKit 扩展中的方法。
方便地添加 classes(首选实用程序或类别),几乎没有依赖项。 如果文件已经添加到项目中,您可以将其删除(删除引用)并再次添加到多个目标中。
例如,我在项目中的类别 NSString+color 在 iOS app 和 Watch App 中工作正常。
更新:您也可以在右侧面板(实用程序)中执行此操作。请参阅下面的 link:cs621620.vk.me/v621620973/13f86/9XYDH1HL5BI.jpg
对于 WatchOS2 openParentApplication
已弃用。它的替代品是 WCSession
in Watch Connectivity Framework
首先,在 watch(ExtensionDelegate
) 和 iOS(AppDelegate
) 中初始化 WCSession
,代码如下
if WCSession.isSupported() {
let session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
}
使用
从手表向Phone发送通知session.sendMessage(msg, replyHandler: { (responses) -> Void in
print(responses)
}) { (err) -> Void in
print(err)
}
使用
处理AppDelegate
中的消息
func session(_ session: WCSession,
didReceiveMessage message: [String : AnyObject],
replyHandler replyHandler: ([String : AnyObject]) -> Void)
{
//do something according to the message dictionary
responseMessage = ["key" : "value"] //values for the replyHandler
replyHandler(responseMessage)
}