【问题标题】:"Create New Contact" and "Add to Existing Contact" for CNContactViewController()CNContactViewController() 的“创建新联系人”和“添加到现有联系人”
【发布时间】:2016-08-28 14:16:22
【问题描述】:

使用 ABAddressBook,当我希望用户能够为他们以前从未见过的联系人选择“创建新联系人”和“添加到现有联系人”时,我会创建并显示一个 ABUnknownPersonViewController .

我无法在 CNContacts 框架中复制此功能。在我看来CNContactViewController(forUnknownContact: 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)

}

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

【问题讨论】:

  • 因为你没有显示真实的代码。显示您的代码!您仍然遗漏了各种重要的部分,我不知道这是因为您不知道应该执行它们还是因为您只是懒惰地将代码粘贴到 Stack Overflow。 contact 是什么?显示您设置unknowncontactStore 的行。这些东西都很重要。 显示。您的。真实的。代码。
  • 我还遗漏了哪些重要的部分? contact 是任意的CNContact,具有任意数量的属性集。我不确定这会对未显示的操作按钮产生什么影响。除了unknowncontactStore 属性被设置,一切都在这里,这被证明是问题所在。谢谢你的帮助。如果我在制作一个最小的可重现示例时偷工减料,我很抱歉;我试图让它尽可能简单易懂。
  • 我会接受这个答案——或者你发布的答案,如果它仍然存在的话——因为正确设置 contactStore 确实解决了这个问题。

标签: ios swift contacts cncontact


【解决方案1】:

您一直没有显示您的真实代码,因此无法为您提供帮助。所以我失去了兴趣。我将向您展示我的真实代码,然后让您研究它并思考我正在做的事情和您正在做的事情之间的区别。这是实际的工作代码;去吧,照样做:

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)

【讨论】:

  • 但是,请注意我在这里描述的错误:stackoverflow.com/q/32973254/341994
  • 上面发布的真的其实是我的真实代码。逐行逐字逐句,这就是我的.swift 文件之一。没有设置contactStore 是问题;你确实帮了我。
  • 为我工作!!
  • '返回'按钮不显示!其他一切都很好。你能给我一个关于如何显示后退按钮的解决方法吗?我的应用程序仅在此屏幕上显示。
  • @ZahurafzalMirza 因为您不在导航控制器中。
【解决方案2】:
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];

此代码适用于“创建新联系人”,对于“添加到现有联系人”,我们将不得不使用 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 在联系人应用程序中的默认行为执行该功能。

【讨论】:

  • 问题被标记为 Swift,而不是 Objective-C。请发布一个 Swift 示例。谢谢。
  • @Moritz 只是知道要做什么,Objective-C 代码就足够了,作为开发人员,无论是 Swift 还是 Objective-C 代码,理解代码都不是什么大不了的事,另外有可以转换代码的工具,所以请..
  • 我刚搞定这个,分享一下我最近实现的东西,等有空的时候,我也会做的。
【解决方案3】:

您在代码中缺少的是将unknown 变量的contactStore 属性设置为CNContactStore 的句柄。

[...]

unknown.contactStore = CNContactStore()

[...]

【讨论】:

    猜你喜欢
    • 2014-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多