Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call a method defined on the iPhone from the Apple Watch

Is there any way to call a defined method in a class on the iPhone from the Watchkit extension?

From my understanding currently one of the ways to communicate locally between Watch kit and the iPhone is by using NSUserDefaults, but are there other ways?

A simple example would be great.

like image 854
Ravin Sardal Avatar asked Jan 03 '15 09:01

Ravin Sardal


3 Answers

You can add the class to both targets (main iOS app and WatchKit extention) and use methods in WatchKit Extention directly.

Uncluding to targets

Conveniently add classes (preferable utilities or categories) with few dependencies. If file is already added to project, you can delete it (remove reference) and add it once again with including to multiple targets.

For example, my category NSString+color in project works correctly in iOS app and Watch App.

Upd: You can also do it in right panel (Utilities). See the link bellow: cs621620.vk.me/v621620973/13f86/9XYDH1HL5BI.jpg

like image 70
KepPM Avatar answered Oct 21 '22 04:10

KepPM


There are two main ways to 'communicate' between your WatchKit Extension and iOS application depending on the what you are trying to accomplish.

1. openParentApplication:reply:
This will open your iOS application in the background and allow you to perform logic from your iOS code and send a response back to your Extension. For example -

    [InterfaceController openParentApplication:@{ @"command": @"foo" }
                                         reply:^(NSDictionary *replyInfo, NSError *error) {
                                         self.item = replyInfo[@"bar"];
    }];

Checkout the Framework Reference -https://developer.apple.com/library/prerelease/ios/documentation/WatchKit/Reference/WKInterfaceController_class/index.html#//apple_ref/occ/clm/WKInterfaceController/openParentApplication:reply:

MMWormhole is a library that you can use to manage these communications

2. Shared Container
If you just need access to the same data that your iOS application has access to you can implement shared containers across both targets.

This could range from just using accessing a shared NSUserDefaults, as you've mentioned or all the way up to using Core Data and accessing a shared persistence stack across both iOS and WatchKit.

Programming Reference - https://developer.apple.com/library/ios/technotes/tn2408/_index.html

3. Singleton
Perhaps you just need to access shared logic from your WatchKit Extension but don't need the complexity of the above two options. As long as you're not persisting any data across both targets you could create a Singleton class that you can call from your Extension to perform the methods you need.

like image 4
phillfarrugia Avatar answered Oct 21 '22 04:10

phillfarrugia


According to Apple's WatchKit Programming Guide you can communicate with the iOS app on the iPhone by using openParentApplication and pass a dictionary. The parent application handles this call via handleWatchKitExtensionsRequest in its AppDelegate. From there you can call other methods depending on the passed parameters.

handleWatchKitExtensionRequest then calls the reply method to pass back parameters to the WatchKit Extension:

Watchkit Extension:

// 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 App:

// 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)
}

Note that this seems to be broken in Xcode 6.2 Beta 3.

like image 3
zisoft Avatar answered Oct 21 '22 06:10

zisoft