"Create New Contact" 和 "Add to Existing Contact" 用于 CNContactViewController()

"Create New Contact" and "Add to Existing Contact" for CNContactViewController()

使用 ABAddressBook,当我希望用户能够为他们以前从未见过的联系人提供 "Create New Contact" 和 "Add to Existing Contact" 选项时,我会创建并显示一个 ABUnknownPersonViewController.

我找不到在 CNContacts 框架中复制此功能的方法。在我看来 CNContactViewController(forUnknownContact: contact) 可以工作,但不幸的是这只允许用户 "Send Message" 或 "Share Contact."

如何允许用户在 CNContacts 中将联系人作为新联系人或现有联系人的一部分保存到他们的地址簿中?

func presentContact() {

    let status = CNContactStore.authorizationStatusForEntityType(.Contacts)

    switch status {
    case .Authorized: ()
    case .NotDetermined: requestAccess()
    case .Denied, .Restricted: accessDenied()
    }

    print("authorized? \(status == .Authorized)") //prints "authorized? true"

    let unknown = CNContactViewController(forUnknownContact: contact!)

    unknown.delegate = self

    self.navigationController?.pushViewController(unknown, animated: false)

}

即使我尝试请求访问权限,用户仍然无法保存联系人。

你一直不显示你的真实代码,所以无法帮助你。所以我失去了兴趣。我将只向您展示 我的 真实代码,让您研究它并思考我正在做的事情和您正在做的事情之间的区别。这是实际的工作代码;去你做同样的事情:

let con = CNMutableContact()
con.givenName = "Johnny"
con.familyName = "Appleseed"
con.phoneNumbers.append(CNLabeledValue(
    label: "woods", value: CNPhoneNumber(stringValue: "555-123-4567")))
let unkvc = CNContactViewController(forUnknownContact: con)
unkvc.message = "He knows his trees"
unkvc.contactStore = CNContactStore()
unkvc.delegate = self
unkvc.allowsActions = false
self.navigationController?.pushViewController(unkvc, animated: true)

您的代码中缺少的是将 unknown 变量的 contactStore 属性 设置为 CNContactStore.

的句柄
[...]

unknown.contactStore = CNContactStore()

[...]
CNContactStore *store = [[CNContactStore alloc] init];
CNMutableContact *contact = [[CNMutableContact alloc] init];
CNPhoneNumber * number  = [[CNPhoneNumber alloc] initWithStringValue:@"1234567890"];
CNLabeledValue * labelValue = [[CNLabeledValue alloc]initWithLabel:CNLabelPhoneNumberMobile value:number];
NSMutableArray<CNLabeledValue *> *phoneNumbers = [NSMutableArray new];
[phoneNumbers addObject:labelValue];
contact.phoneNumbers = phoneNumbers;
CNContactViewController *controller = [CNContactViewController viewControllerForNewContact:contact];

controller.contactStore = store;
controller.delegate = self;

[self presentViewController:[[UINavigationController alloc] initWithRootViewController:controller] animated:YES completion:nil];

此代码适用于 "Create New Contact",对于 "Add to Existing Contact",我们将不得不使用 CNContactPickerViewController

CNContactPickerViewController * picker = [[CNContactPickerViewController alloc] init];
                                    picker.delegate = self;
                                    [self presentViewController:picker animated:YES completion:nil];

和委托方法中的

- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact
{
    CNContactStore *store = [[CNContactStore alloc] init];
    CNMutableContact *existingContact = [(CNMutableContact*)contact mutableCopy];
    CNPhoneNumber * number  = [[CNPhoneNumber alloc] initWithStringValue:@"1234567890"];
    CNLabeledValue * labelValue = [[CNLabeledValue alloc]initWithLabel:CNLabelPhoneNumberMobile value:number];
    NSMutableArray<CNLabeledValue *> *phoneNumbers = [NSMutableArray new];
    [phoneNumbers addObject:labelValue];
    [phoneNumbers addObjectsFromArray:existingContact.phoneNumbers];
    existingContact.phoneNumbers = phoneNumbers;
    CNContactViewController *controller = [CNContactViewController viewControllerForNewContact:existingContact];

    controller.contactStore = store;
    controller.delegate = self;

    dispatch_async(dispatch_get_main_queue(), ^
    {
        [self presentViewController:[[UINavigationController alloc] initWithRootViewController:controller] animated:YES completion:nil];
    });

}

虽然它会显示“完成”按钮,而不是“更新”按钮,但它确实会按照 iPhone 在联系人应用程序中的默认行为来执行该功能。