How can I open the parent app on iPhone from my WatchKit app?
The Objective-C method is:
+ (BOOL)openParentApplication:(NSDictionary *)userInfo
reply:(void (^)(NSDictionary *replyInfo,
NSError *error))reply
The Swift method is:
class func openParentApplication(_ userInfo: [NSObject : AnyObject]!,
reply reply: (([NSObject : AnyObject]!,
NSError!) -> Void)!) -> Bool
So you need to pass the iPhone application a reply() block in order to have activate it from your WatchKit extension. Here's one way it could be implemented, for instance:
NSString *requestString = [NSString stringWithFormat:@"executeMethodA"]; // This string is arbitrary, just must match here and at the iPhone side of the implementation.
NSDictionary *applicationData = [[NSDictionary alloc] initWithObjects:@[requestString] forKeys:@[@"theRequestString"]];
[WKInterfaceController openParentApplication:applicationData reply:^(NSDictionary *replyInfo, NSError *error) {
NSLog(@"\nReply info: %@\nError: %@",replyInfo, error);
}];
Your iPhone application's AppDelegate needs to implement the following method:
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply {
NSString * request = [userInfo objectForKey:@"requestString"];
if ([request isEqualToString:@"executeMethodA"]) {
// Do whatever you want to do when sent the message. For instance...
[self executeMethodABC];
}
// This is just an example of what you could return. The one requirement is
// you do have to execute the reply block, even if it is just to 'reply(nil)'.
// All of the objects in the dictionary [must be serializable to a property list file][3].
// If necessary, you can covert other objects to NSData blobs first.
NSArray * objects = [[NSArray alloc] initWithObjects:myObjectA, myObjectB, myObjectC, nil];
NSArray * keys = [[NSArray alloc] initWithObjects:@"objectAName", @"objectBName", @"objectCName", nil];
NSDictionary * replyContent = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];
reply(replyContent);
}
The WKInterfaceController method openParentApplication:reply: launches the containing app in the background when the iPhone (or iOS Simulator) is unlocked or locked. Note that statements from Apple indicate that the WatchKit extension was always intended to launch your iPhone application in the background, and it was only an implementation detail of the simulator that it appeared to launch your iPhone application in the foreground in previous betas.
If you want to test your WatchKit app and your iPhone app running at the same time, simply launch the WatchKit app from Xcode under the Schemes menu, and then manually launch your iPhone app in the simulator by clicking on its springboard icon.
Launching the parent application from the watch app
Just use WatchConnectivity WCSession->sendMessage
Calling this method from your WatchKit extension while it is active and running wakes up the corresponding iOS app in the background and makes it reachable.
offical doc
How can I get the REAL apple watch to open parent application
There is no method in WatchKit to open an iPhone app in the foreground from the Watch (other than Handoff). While you can do this in the simulator, it isn't supported on the actual hardware. That's why you're seeing this behavior.
How to open a watch app from parent iOS app?
As @abjurato said, you can only launch it in a "workout mode"
import HealthKit
import WatchConnectivity
let healthStore = HKHealthStore()
func startWatchApp() {
print("method called to open app ")
getActiveWCSession { (wcSession) in
print(wcSession.isComplicationEnabled, wcSession.isPaired)
if wcSession.activationState == .activated && wcSession.isWatchAppInstalled {
print("starting watch app")
self.healthStore.startWatchApp(with: self.configuration, completion: { (success, error) in
// Handle errors
})
}
else{
print("watch not active or not installed")
}
}
}
func getActiveWCSession(completion: @escaping (WCSession)->Void) {
guard WCSession.isSupported() else { return }
let wcSession = WCSession.default()
wcSession.delegate = self
if wcSession.activationState == .activated {
completion(wcSession)
} else {
wcSession.activate()
wcSessionActivationCompletion = completion
}
}
Launch host app from watch app
If you need to open your parent app in the foreground, use Handoff!
https://developer.apple.com/handoff/
Example:
Somewhere shared for both:
static let sharedUserActivityType = "com.yourcompany.yourapp.youraction"
static let sharedIdentifierKey = "identifier"
on your Watch:
updateUserActivity(sharedUserActivityType, userInfo: [sharedIdentifierKey : 123456], webpageURL: nil)
on your iPhone in App Delegate:
func application(application: UIApplication, willContinueUserActivityWithType userActivityType: String) -> Bool {
if (userActivityType == sharedUserActivityType) {
return true
}
return false
}
func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]!) -> Void) -> Bool {
if (userActivity.activityType == sharedUserActivityType) {
if let userInfo = userActivity.userInfo as? [String : AnyObject] {
if let identifier = userInfo[sharedIdentifierKey] as? Int {
//Do something
let alert = UIAlertView(title: "Handoff", message: "Handoff has been triggered for identifier \(identifier)" , delegate: nil, cancelButtonTitle: "Thanks for the info!")
alert.show()
return true
}
}
}
return false
}
And finally (this step is important!!!): In your Info.plist(s)
Related Topics
Swift - Get Nsbundle for Test Target
How to Convert Delegate to Observable Rxswift
How to Animate Transition Between Views in Swiftui
How Is a Return Value of Anyobject! Different from Anyobject
How to Remove Numbers from a String in Swift
Adding a View to the Window Hierarchy
Swiftui - Foreach Deletion Transition Always Applied to Last Item Only
Why Do I Need to Declare an Optional Value as Nil Explicitly in Struct - Swift
How to Filter on an Array of Objects in Swift
How Use and Run Swift 2.3 on Command Line
Is It Possible in Swift to Add Variables to an Object at Runtime
How to Detect a 'Click' Gesture in Swiftui Tvos
Avspeechutterance - Swift - Initializing with a Phrase