How to Open the Parent App on iPhone from My Watchkit App

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)

Sample Image



Related Topics



Leave a reply



Submit