Detect WatchKit extension presence in app

2019-08-16 08:43发布

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

4条回答
虎瘦雄心在
2楼-- · 2019-08-16 09:06

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.

查看更多
爷、活的狠高调
3楼-- · 2019-08-16 09:10

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

查看更多
戒情不戒烟
4楼-- · 2019-08-16 09:18

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"])
}
查看更多
劳资没心,怎么记你
5楼-- · 2019-08-16 09:20

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.

查看更多
登录 后发表回答