从 Apple Watch 发起呼叫

Initiate call from apple watch

我正在为现有的应用程序开发 Apple Watch 扩展。

我的手表应用程序有联系我们部分,客户可以拨打免费电话。

我的问题是如何通过单击按钮在 Apple Watch 中开始通话,而不是将我的应用程序保持在前台并开始通话。

目前我正在使用此代码开始通话

+ (void)callWithNumberWithoutPrompt:(NSString *)phoneNo {
    NSString *prefixedMobileNumber = [phoneNo hasPrefix:@"+"]?phoneNo:[NSString stringWithFormat:@"+%@",phoneNo];
    NSString *phoneNumber = [@"tel://" stringByAppendingString:prefixedMobileNumber];
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumber]];
}

注意:这在 WatchOS 1 上是正确的,并且可能随着 WatchOS 2 的发布而改变。


来自Ray Wenderlich WatchKit FAQ

Can third-party apps make phone calls from a watch app?

No. There is no public API that lets you initiate a phone call directly from a WatchKit extension. Since the companion iPhone app can’t be brought to the foreground either, the system silently ignores all phone call or openURL: requests from the companion iPhone app.

WatchOS2 中使用 WatchConnectivity 您可以将数据从手表应用发送回父应用,然后尝试从父应用发起调用。这是一个例子:

//App Delegate in iOS Parent App 

#pragma mark Watch Kit Data Sharing

-(void)initializeWatchKit{
    if ([WCSession isSupported]){
        WCSession *session = [WCSession defaultSession];
        session.delegate = self;
        [session activateSession];
    }
}

- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message{
    DLog(@"%@", message);
    [self callRestaurantWithNumber:[NSString formattedPhoneNumber:[message valueForKey:@"phone_number"]]];
}

-(void)callRestaurantWithNumber:(NSString *)formattedPhoneNumber{
    [[UIApplication sharedApplication]
     openURL:[NSURL URLWithString:[NSString stringWithFormat:@"tel:%@",
                                   formattedPhoneNumber]]];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [self initializeWatchKit];

    return YES;
}

现在在 watchKit 扩展中,您可以像这样将数据发送回父应用程序:

 override func willActivate() {
        super.willActivate()

    if WCSession.isSupported() {

        let defaultSession = WCSession.defaultSession()
        defaultSession.delegate = self
        defaultSession.activateSession()
        if defaultSession.reachable == true {
            let phoneNumberDict = [ "phone_number": "123-456-7890"]

            defaultSession.sendMessage(phoneNumberDict, replyHandler: nil, errorHandler: { (error) -> Void in
                print("THERE WAS AN ERROR SENDING DATA TO THE IOS APP: \(error.localizedDescription)")
            })

        } 
    }
}

然而,我在使用这种方法时遇到的一个限制是父应用程序需要打开才能实际接收数据并进行调用。文档似乎说明当您从手表向 ios 父应用程序发送消息时,该应用程序将在后台打开。然而,到目前为止,在我的测试中,在真实设备(手表和 iphone)和模拟器上,父应用仅在父 ios 应用打开并置于前台时才接收数据。即使 ios 父应用程序处于后台状态,它似乎仍未发起调用。我在 watch os2iOS 9.0.2 上 运行。

从另一个 post 看来也是 运行 进入同样的问题。 Another watchKit SO post

Link Apple 文档: Apple Doc sendMessage: