iOS:如何获取系统通讯录中的姓名排序与显示设置?
嘿,这个问题问得很到位!确实自从iOS 9之后,旧的ABAddressBook框架就被全新的Contacts框架取代了,之前的defaultNameOrdering()方法自然也被弃用了。我来帮你理清楚怎么在CNContactStore里获取你需要的这两个设置:
1. 获取排序顺序(Sort Order)
这个有直接的公开API可以用,CNContactStore提供了defaultSortOrder属性,它会返回CNContactSortOrder枚举值,直接对应用户设置的排序规则:
.givenName:对应「First, Last(名在前,姓在后)」的排序.familyName:对应「Last, First(姓在前,名在后)」的排序
代码示例很简单:
let contactStore = CNContactStore() let sortOrder = contactStore.defaultSortOrder switch sortOrder { case .givenName: print("当前排序规则:名在前,姓在后") case .familyName: print("当前排序规则:姓在前,名在后") @unknown default: // 处理未来可能新增的枚举值 break }
2. 获取显示顺序(Display Order)
这里要注意,Contacts框架并没有提供直接获取显示顺序的公开属性,但我们有两种可靠的方式来获取:
方式一:利用CNContactFormatter自动适配(推荐)
如果你只是想在应用里按照用户的设置显示联系人姓名,其实根本不用手动获取显示顺序——直接用CNContactFormatter来格式化姓名就好,它会自动遵循用户在系统通讯录里设置的显示规则。比如:
let formatter = CNContactFormatter() formatter.style = .fullName // 或者 .middleName,根据你的需求 if let contact = someCNContact, let displayName = formatter.string(from: contact) { // displayName 就是符合用户设置的姓名格式 print(displayName) }
方式二:主动判断显示顺序
如果确实需要明确获取显示顺序的设置值,可以创建一个测试联系人,用CNContactFormatter格式化后根据结果反推:
let formatter = CNContactFormatter() formatter.style = .fullName // 创建一个测试用的联系人 let testContact = CNMutableContact() testContact.givenName = "John" testContact.familyName = "Doe" if let formattedName = formatter.string(from: testContact) { if formattedName == "John Doe" { print("当前显示规则:名在前,姓在后") } else if formattedName == "Doe, John" { print("当前显示规则:姓在前,名在后") } }
另外,也有开发者会通过读取UserDefaults中的ABPersonNameDisplayOrder键来获取(值1对应First, Last,值2对应Last, First),但这个键属于旧框架的遗留,苹果没有公开文档保证它的兼容性,所以更推荐上面两种方式。
总结一下,如果只是同步显示效果,用CNContactFormatter是最省心且符合苹果规范的做法;如果需要明确获取设置值,就结合defaultSortOrder和测试联系人的方式来实现。
内容的提问来源于stack exchange,提问作者Libor Zapletal

