Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I open the parent app on iPhone from my WatchKit app?

I'm trying to open the parent application of my Apple Watch app.

In Xcode Beta 2 we could use this code:

WKInterFaceController.openParentApplication

However, in Xcode beta 3 I couldn't found that code any longer. Now I don't know how to open the parent application from the watch app. Please help.

like image 488
Hieu Duc Pham Avatar asked Jan 11 '15 05:01

Hieu Duc Pham


People also ask

What is WatchKit app?

The WatchKit framework provides infrastructure for creating watchOS apps, including an extension delegate that manages background tasks, extended runtime sessions, and Siri intents. The framework also performs other support tasks, such as accessing information about the user's Apple Watch.

How do you make a watch app on IOS?

To build a watch-only app, start a new project in Xcode, select the Watch App template, and click Next. Provide a name, and choose the interface, life cycle, and language for your watch app. Select the options to include a notification scene template or unit and user interface tests, and click Next.


2 Answers

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.

like image 86
Duncan Babbage Avatar answered Sep 20 '22 12:09

Duncan Babbage


If you need to open your parent app in the foreground, use 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)

enter image description here

like image 42
stk Avatar answered Sep 20 '22 12:09

stk