我们可以在手表扩展上打开联系人吗

Can we open the contacts on watch extension

如何像在 iOS 中那样使用 AddressBook 以编程方式在 watch 扩展程序中打开 iPhone 的联系人。

提前致谢

通常从您使用的 WatchKit 扩展与 iPhone 通信

+ (BOOL)openParentApplication:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo, NSError *error)) reply;    // launches containing iOS application on the phone. userInfo must be non-nil

WKInterfaceControllerclass.

的方法

例如,您可以将 Storyboard 中按钮的 IBAction 附加到此方法

- (IBAction)callPhoneAppButtonTapped
{
    NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"text to display on iPhone", @"key", nil];

    [InterfaceController openParentApplication:dictionary reply:^(NSDictionary *replyInfo, NSError *error) {
        NSLog(@"Reply received by Watch app: %@", replyInfo);
    }];
}

注意:为了从地址簿中获取数据,用户需要授予您的应用权限。但应用程序将在后台启动,用户将专注于 Watch,因此最好在您的 iPhone 应用程序中请求此权限。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
        ABAddressBookRequestAccessWithCompletion(ABAddressBookCreateWithOptions(NULL,  nil), ^(bool granted, CFErrorRef error) {
    if (!granted){
        NSLog(@"Access denied");
        return;
    }
    NSLog(@"Access granted");
});
}

为了在您的 AppDelegate 工具中处理 openParentApplication:reply 发送的消息

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
{
    NSLog(@"Request received by iOS app");
    NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"your value to return to Apple Watch", @"key", nil];

    // Here your app will be launch in background. Fetch AddressBook or other data you need.
    // Remember to call reply block in the end.  

    // Example of saving data to Address Book
    NSString *firstName;
    NSString *lastName;

    firstName = @"Maggie";
    lastName = @"Peggie";

    ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, nil);
    ABRecordRef contact = ABPersonCreate();

    ABRecordSetValue(contact, kABPersonFirstNameProperty, (__bridge CFStringRef) firstName, nil);
    ABRecordSetValue(contact, kABPersonLastNameProperty, (__bridge CFStringRef)lastName, nil);

    ABAddressBookAddRecord(addressBookRef, contact, nil);
    ABAddressBookSave(addressBookRef, nil);

    reply(dictionary);
}

虽然当前版本的 Apple Watch 应用程序本身无法执行代码,但您的 WatchKit 扩展 运行 在 phone 上可以访问所有 iPhone API,标准 iOS 应用即可。作为开发人员,我们在如何以编程方式更改界面方面受到更多限制,但在访问服务方面所做的事情却不受限制。

因此,通过您的 iOS 应用程序访问地址簿数据没有技术要求 — 您可以直接对地址簿数据提出这些请求。如果这些方法执行速度很快,那么选择是直接在扩展程序中还是在您的 iPhone 应用程序中执行此操作将归结为决定如何最大限度地降低代码复杂性,从而最大限度地提高代码可维护性。 Apple 表示 iPhone 应用程序和 WatchKit Extension 之间的通信延迟在很大程度上可以忽略,因为它是微不足道的。 (它是 phone 上的 运行ning 扩展和我们需要关注的 Watch 应用程序之间的延迟。)

但是,我们也被告知 WatchKit Extensions 可能会在 Watch 应用程序终止时立即终止,我们需要为以秒而不是分钟为单位的参与时间做好准备。 WatchKit Extensions 没有给予 iPhone 应用程序在用户界面终止后在后台完成事情的那种自由度。因此,建议任何可能更耗时或需要为数据完整性完成的事情都应在 iPhone 应用程序中 运行。 lvp 的回答给出了可以帮助解决这个问题的代码。

您的应用在 phone 上运行,因此您可以获取联系人并将其发送到手表