use*_*810 13 contacts addressbook swift ios8
我不明白为什么我的代码不能用Swift编译.
我试图转换这个Objective-C代码:
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (addressBook != nil) {
NSLog(@"Succesful.");
NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
}
Run Code Online (Sandbox Code Playgroud)
这是我目前在Swift中的演绎:
var error:CFErrorRef
var addressBook = ABAddressBookCreateWithOptions(nil, nil);
if (addressBook != nil) {
println("Succesful.");
var allContacts:CFArrayRef = ABAddressBookCopyArrayOfAllPeople(addressBook);
}
Run Code Online (Sandbox Code Playgroud)
但是,Xcode报道:
'Unmanaged'不能转换为'CFArrayRef'
你们有个主意吗?
Rob*_*Rob 30
显然,如果针对iOS 9或更高版本,您根本不应该使用AddressBook
框架,而是使用Contacts
框架.
所以,
进口Contacts
:
import Contacts
Run Code Online (Sandbox Code Playgroud)一定要提供NSContactsUsageDescription
你的Info.plist
.
然后,您可以访问联系人.例如在Swift 3中:
let status = CNContactStore.authorizationStatus(for: .contacts)
if status == .denied || status == .restricted {
presentSettingsActionSheet()
return
}
// open it
let store = CNContactStore()
store.requestAccess(for: .contacts) { granted, error in
guard granted else {
DispatchQueue.main.async {
self.presentSettingsActionSheet()
}
return
}
// get the contacts
var contacts = [CNContact]()
let request = CNContactFetchRequest(keysToFetch: [CNContactIdentifierKey as NSString, CNContactFormatter.descriptorForRequiredKeys(for: .fullName)])
do {
try store.enumerateContacts(with: request) { contact, stop in
contacts.append(contact)
}
} catch {
print(error)
}
// do something with the contacts array (e.g. print the names)
let formatter = CNContactFormatter()
formatter.style = .fullName
for contact in contacts {
print(formatter.string(from: contact) ?? "???")
}
}
Run Code Online (Sandbox Code Playgroud)
哪里
func presentSettingsActionSheet() {
let alert = UIAlertController(title: "Permission to Contacts", message: "This app needs access to contacts in order to ...", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Go to Settings", style: .default) { _ in
let url = URL(string: UIApplicationOpenSettingsURLString)!
UIApplication.shared.open(url)
})
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
present(alert, animated: true)
}
Run Code Online (Sandbox Code Playgroud)我对AddressBook框架的原始答案如下.
几点意见:
如果要使用error
参数ABAddressBookCreateWithOptions
,请将其定义为Unmanaged<CFError>?
.
如果失败,请查看错误对象(这样takeRetainedValue
做不会泄漏).
确保takeRetainedValue
通讯录也是如此,这样你就不会泄漏.
你可能不应该只是抓住联系人,但你可能应该首先请求许可.
拉出所有这些你得到:
// make sure user hadn't previously denied access
let status = ABAddressBookGetAuthorizationStatus()
if status == .Denied || status == .Restricted {
// user previously denied, so tell them to fix that in settings
return
}
// open it
var error: Unmanaged<CFError>?
guard let addressBook: ABAddressBook? = ABAddressBookCreateWithOptions(nil, &error)?.takeRetainedValue() else {
print(error?.takeRetainedValue())
return
}
// request permission to use it
ABAddressBookRequestAccessWithCompletion(addressBook) { granted, error in
if !granted {
// warn the user that because they just denied permission, this functionality won't work
// also let them know that they have to fix this in settings
return
}
if let people = ABAddressBookCopyArrayOfAllPeople(addressBook)?.takeRetainedValue() as? NSArray {
// now do something with the array of people
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
22643 次 |
最近记录: |