1

I have an app that I want to behave a bit differently when it comes to updates and caching if a WatchKit extension is installed on your paired Apple Watch than if it is not. If the watchkit extension has any chance of launching (you have paired a watch and the app is installed) then I want to do more heavy caching.

Is there any way I can detect whether an Apple WatchKit Extension is installed on the Apple Watch from my iOS app? Other than setting a flag first time it is launched and hope it isn't deleted thereafter?

Cheers

Nik

niklassaers
  • 8,480
  • 20
  • 99
  • 146
  • 1
    Just to be clear, the WatchKit extension is never installed on the Apple Watch. The WatchKit extension runs on the iPhone, while the bundle of assets and storyboards that we call the WatchKit app is installed on the actual hardware. – Mike Swanson May 15 '15 at 21:38
  • Correct, that was me not being precise :-) – niklassaers May 16 '15 at 10:42

4 Answers4

2

I'll reiterate the answer I gave here. There's no way to detect whether or not a Watch has been paired with the phone programmatically.

Community
  • 1
  • 1
bgilham
  • 5,909
  • 1
  • 24
  • 39
  • 1
    This is not true anymore. https://developer.apple.com/documentation/watchconnectivity/wcsession/1615665-ispaired – AW5 Aug 05 '20 at 21:14
1

As of iOS 9, WCSession offers isWatchAppInstalled. You can use it by importing WatchConnectivity (@import WatchConnectivity;), starting the session ([[WCSession defaultSession] activateSession]) and calling [[WCSession sharedSession] isWatchAppInstalled]. See here: https://developer.apple.com/documentation/watchconnectivity/wcsession/1615623-iswatchappinstalled

SushiGrass Jacob
  • 19,425
  • 1
  • 25
  • 39
0

I don't know if this will work for you but what I have done is used userDefaults (group) to set a flag when the watch app is launched. Then I can check it in the main app. If the flag is set, I know the app has been installed. Of course this is not bulletproof but it was the best I could come up with given the current limits of WatchKit. It doesn't tell you if the phone has been paired but it tells you that your app has been installed on the watch and therefore the phone itself must be (or was at onetime) paired.

rmp
  • 3,503
  • 1
  • 17
  • 26
  • This is like I mentioned in my question, right? The drawbacks are that on first launch on your watch, it will not have data in time, thus making for a bad first experience. And, when the user deletes the watch extention based on this bad experience, it will keep data for the watch, even though the watch won't ask for it again. Or does your check come before the first launch? – niklassaers May 16 '15 at 10:42
  • 1
    Yea this like you mentioned and there are drawbacks. As for knowing if the user deleted the watch app you can use a time stamp as the flag and update it every time the watch app is opened. You can then set a time span that you would consider long enough to to assume the watch app has been deleted or is no longer being used. Again this on not a great solution but given the current state it's about all you can do. If anyone else has a better solution please post it. – rmp May 16 '15 at 14:48
0

With WatchConnectivity framework you can check if your paired device is available and the app is running.

  • activate App Groups from "target -> Capabilities"
  • try this code on the device that needs to know the companion app is running.

objective C:

#import <WatchConnectivity/WatchConnectivity.h>

yourClass : Superclass <WCSessionDelegate>

WCSession* session = [WCSession defaultSession];
session.delegate = self;
[session activateSession];

-(void)session:(WCSession *)session activationDidCompleteWithState:(WCSessionActivationState)activationState error:(NSError *)error
{
  if (activationState == WCSessionActivationStateActivated) {
      [[WCSession defaultSession] sendMessage:@{@"fromThisDevice":@"hello"} replyHandler:^(NSDictionary<NSString *,id> * _Nonnull replyMessage) {
          NSLog(@"reply %@", replyMessage[@"fromOtherDevice"]);
      } errorHandler:^(NSError * _Nonnull error) {
          NSLog(@"error %@", error.userInfo);
      }];
  }
}

- (void) session:(nonnull WCSession *)session didReceiveMessage:(nonnull NSDictionary<NSString *,id> *)message replyHandler:(nonnull void (^)(NSDictionary<NSString *,id> * __nonnull))replyHandler{
   NSLog(@"message %@", message[@"fromOtherDevice"]);
   replyHandler(@{@"fromThisDevice":@"hello"});
}

Swift:

import WatchConnectivity

yourClass : Superclass, WCSessionDelegate

let session = WCSession.default()
session.delegate = self
session.activate()

func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
    if activationState == WCSessionActivationState.activated{
        WCSession.default().sendMessage(["fromThisDevice" : "hello"], replyHandler: { (reply:[String : Any]) -> Void in
            print(reply["fromOtherDevice"] as Any)
        }, errorHandler: { (error) -> Void in
            print(error)
        })
    }
}

func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
    print(message["fromOtherDevice"] as Any)
    replyHandler(["fromThisDevice" : "hello"])
}
Enrico Cupellini
  • 447
  • 7
  • 14