有没有办法从iPhone通讯录API中获取“Me”卡片?

24

我对这个问题感到困惑。

在 Mac OS X 中,有一种简单的方法可以从内置地址簿 API 中获取“我的”名片(Mac/账户的所有者)。

有没有人找到了一种方法来确定哪个联系人(如果存在)属于 iPhone 的所有者?


1
根据@wilshipley的说法似乎不是这样的:http://twitter.com/wilshipley/status/1369679612 - Loïc Wolff
请问如何在Mac电脑上读取我的SD卡? - Johnykutty
在Mavericks上,选择您的卡,然后使用 卡片 > 将此设置为我的卡片 菜单项。 - bneely
@bneely 没问题。但我需要代码...我已经找到了解决方案。谢谢。 - Johnykutty
有一个简单的方法可以做到这一点。请查看我的答案并更改已接受的答案。 - Kugutsumen
5个回答

5
您可以使用未记录的用户默认设置:
[[NSUserDefaults standardUserDefaults] objectForKey:@"SBFormattedPhoneNumber"];

然后在通讯录中搜索具有该电话号码的卡片。请记住,由于用户默认设置未经记录,苹果公司随时可能更改,您可能会在进入应用商店时遇到麻烦。另一种方法是查看设备名称,虽然这种方法非常脆弱。如果用户没有将其更改为默认的“用户名的iPhone”,并且他们正在使用自己的真实姓名作为iPhone,您可以从中获取用户名。同样,并不是最好的解决方案,但它确实给您尝试其他方法的机会。对于这个问题,通常接受的答案是向苹果提交一个Radar以获取此功能,并提示用户选择他们的卡片。

应用程序因此被商店拒绝。无论如何,这并不可靠--如果用户将他们的电话号码从另一个手机运营商转移过来,这个调用几乎肯定会给出错误的结果。 - Tom Harrington
感谢您的帮助。在发布这个问题后,我考虑了SBFormattedPhoneNumber方法。它可以很容易地以“安全”的方式实现,但听起来苹果可能因为各种原因而不鼓励使用它。此外,Tom,感谢您的提醒。 - amattn
这个不再返回一个值。 - Brian

4

iOS上的联系人容器有一个名为 "me identifier" 的属性,可以使用 container.value(forKey: "meIdentifier") 进行访问。

if let containers = try? CNContactStore().containers(matching: nil) {
  containers.forEach { container in
  if let meIdentifier = container.value(forKey: "meIdentifier") as? String {
    print("Contacts:", "meIdentifier", meIdentifier)
  }
}

这个标识符是在旧的AddressBook框架中使用的遗留标识符。您仍然可以在CNContact中访问它:

let iOSLegacyIdentifier = contact.value(forKey: "iOSLegacyIdentifier")

2

在3.1 SDK中,这仍然是真的吗? - Steven Fisher
4.2 版本中有任何改进吗? - adib

2

编辑:[过时的答案]

获取“我”卡片的API不存在,因为不存在“我”卡片。iPhone的联系人应用程序无法将卡片标记为“我”,而API也反映了这一点。


这并不完全正确。当然,联系人应用程序无法做到这一点,但是您可以在“设置”>“邮件、联系人、日历”>“我的信息”中设置您的“我”卡片。 - CIFilter
@LucasTizma:你回复这个问题的时间比上面的答案早了近三年。当时它是正确的,但事情当然会发生变化。 - Tom Harrington
啊,我甚至没有注意到你回答的日期。对此感到抱歉! - CIFilter

-3
我想出了一个部分解决方案。
你可以按以下方式获取设备名称。
NSString *ownerName = [[UIDevice currentDevice] name];

在英语中,设备最初被称为,例如,“乔·布洛格的 iPhone”

然后分离出名称

 NSRange t = [ownerName rangeOfString:@"’s"];
    if (t.location != NSNotFound) {
        ownerName = [ownerName substringToIndex:t.location];
    }

你可以使用这个名称来搜索联系人。
CNContactStore *contactStore = [CNContactStore new];
 NSPredicate *usersNamePredicate = [CNContact predicateForContactsMatchingName:usersName];

    NSArray * keysToFetch = @[[CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName],CNContactPhoneNumbersKey,CNContactEmailAddressesKey,CNContactSocialProfilesKey, ];

 NSArray * matchingContacts = [contactStore unifiedContactsMatchingPredicate:usersNamePredicate keysToFetch:keysToFetch error:nil];

当然,其他语言的设备名称字符串不同,例如“Johann Schmidt的iPhone”,因此需要进行更多的解析以适应其他语言,并且仅在用户未将设备名称更改为iTunes中的“Joes phone”之类的内容时才有效,但它为您提供了一个起点

好吧...它为您提供了一组匹配项 :) 因此,如果有多个联系人与该数组匹配,则只需使用随机选择并选择第一个或处理多个名片并从每个名片中获取所需内容。

我确实说过这是部分解决方案,即使它不能适用于所有用户情况,您可能会发现它适用于许多用户并减少了一些摩擦


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接