如何使用 Swift 检索通讯录联系人?

2024-02-19

我不明白为什么我的代码不能用 Swift 编译。

我正在尝试转换这个 Objective-C 代码:

CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);

  if (addressBook != nil) { 
    NSLog(@"Succesful."); 

    NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
}

这是我当前在 Swift 中的表现:

var error:CFErrorRef
var addressBook = ABAddressBookCreateWithOptions(nil, nil);

if (addressBook != nil) {
    println("Succesful.");

    var allContacts:CFArrayRef = ABAddressBookCopyArrayOfAllPeople(addressBook);
}

但是,Xcode 报告:

“非托管”无法转换为“CFArrayRef”

你们有主意吗?


显然,如果针对 iOS 版本 9 或更高版本,则不应使用AddressBook根本没有框架,而是使用Contacts框架代替。

So,

  1. Import Contacts:

    import Contacts
    
  2. 确保提供一个NSContactsUsageDescription在你的Info.plist.

  3. 然后,您就可以访问联系人了。例如。在斯威夫特 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) ?? "???")
        }
    }
    

    Where

    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: UIApplication.openSettingsURLString)!
            UIApplication.shared.open(url)
        })
        alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
        present(alert, animated: true)
    }
    

我对 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
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Swift 检索通讯录联系人? 的相关文章

  • CustomNSError 协议有什么作用以及为什么我应该采用它?

    什么是CustomNSError协议的用途以及为什么我应该采用它 Apple提供的文档仅指出 描述错误类型 具体提供域 代码和 用户信息字典 我已经在谷歌上搜索过 但找不到与我的问题相关的任何内容 每种类型都符合Error协议是隐含地桥接的
  • let/var 如何解决可变性? [复制]

    这个问题在这里已经有答案了 我没有任何问题 我只是想对有关可变性的问题进行一些澄清 在 Objective C 中我们会使用例如NSMutableArray得到一个可变数组和NSArray得到一个不可变的 我对两者的内部运作了解不多 但据我
  • 如何组合两个 SwiftyJSON 对象

    我有一个 swiftyJSON 对象 例如 location http img http commentCount 0 timestamp 1432460217550 我希望能够向其附加另一个 swiftyJSON 对象 使其看起来像 lo
  • 保存来自 TrueDepth 相机的深度图像

    我正在尝试保存 iPhone X TrueDepth 相机的深度图像 使用AVCam照片滤镜 https developer apple com library content samplecode AVCamPhotoFilter Lis
  • 在 Xcode 6 中定位 iOS 7.1 或 7.0 时,应用程序中出现黑条

    重现步骤 使用Xcode6创建一个新项目 单视图模板 仅限iPhone Objective C 导航到项目设置并将部署目标从 8 0 更改为 7 1 在安装了 7 1 的 iPhone5 S 或 iPhone5 s 7 1 模拟器中运行应用
  • iOS Swift 在后台下载大量小文件

    在我的应用程序中 我需要下载具有以下要求的文件 下载大量 例如 3000 个 小 PNG 文件 例如 5KB 逐个 如果应用程序在后台继续下载 如果图像下载失败 通常是因为互联网连接丢失 请等待 X 秒然后重试 如果失败Y次 则认为下载失败
  • 带约束的嵌套集合视图的意外行为 (Swift 4)

    我的表格视图中有一个单元格 其中包含水平分页集合视图 该集合视图的每个页面内都有一个垂直集合视图 为了避免 滚动滚动 问题 我在垂直集合视图中禁用了垂直滚动 垂直集合视图的单元格计数不是静态的 可以是任意数字 因此 这会产生一个问题 集合视
  • NSURLCache 不缓存

    我正在使用 Xcode 6 1 6A1030 iOS7 和 iOS8 模拟器 NSURLCache 似乎没有缓存任何东西 我使用 Cache Control 标头 我的服务器返回带有 max age 6000 的 Cache Control
  • 循环多个 UIAlertController

    在某些情况下 我的应用程序需要显示多个警报消息 错误消息在启动时收集 并且需要一次向用户显示一条 当第一个被确认后 应该呈现下一个 问题在于 显然 它们都试图同时执行 有没有一种聪明的方法可以同步执行此操作 这是一些简单描述我想要做的事情的
  • 在 UITableView 的部分标题文本下方添加一些边距

    我已经设计了标题文本的样式 func tableView tableView UITableView cellForRowAtIndexPath indexPath NSIndexPath gt UITableViewCell let ce
  • 调用 SwiftUI 中位置 #11、#12 处的额外参数 [重复]

    这个问题在这里已经有答案了 我在 SwiftUI 中的切换开关上不断收到 调用中位置 11 12 处有额外参数 错误 我见过其他人有 调用中的额外参数 错误 但答案似乎没有帮助 另外 我的错误是 位置 11 12 我还没有看到其他人发生这种
  • 在 swift 中将简单字符串转换为 JSON 字符串

    我知道有一个同标题的问题here https stackoverflow com questions 30825755 convert string to json string in swift 但在那个问题中 他试图将字典转换为 JSO
  • ios - Gamekit 的 GKOctree 未找到元素

    我正在尝试使用GKOctree https developer apple com documentation gameplaykit gkoctree用于高效检索 3D 空间中的对象 然而 以下代码似乎没有按预期工作 import Gam
  • 设置/覆盖 UICollectionView 中单元格之间的填充

    我有一个 UICollectionView 但在获取单元格之间的填充时遇到了问题 理论上 我应该能够将屏幕除以 4 并且我可以获得包含 4 个图像的单元格大小 完美地占据屏幕宽度 但是 它选择不这样做 相反 它会创建 3 个具有巨大填充的图
  • Swift:如何减少 didupdatelocations 调用

    我想出了一些代码来打印我所在位置的地址和邮政编码 这是在 didupdatelocation 函数中完成的 我遇到的唯一问题是 didupdatelocation 函数每秒都会更新该地址 因为这电池效率非常低 所以我一直在寻找使用间隔的方法
  • 为什么我不能在 Realm 属性上使用 private

    我正在尝试在 RealmSwift 中存储一个枚举案例 但 Realm 不支持枚举 本文 https medium com it works locally persisting swift enumerations with realm
  • 如何防止Apple Watch进入睡眠状态?

    我们正在开发一个 Apple Watch 项目 但如果不被打扰 手表就会进入睡眠状态 有什么办法可以阻止它进入睡眠状态吗 据我所知和有关该主题的其他搜索 目前还没有api可通过编程方式启用或禁用 Apple Watch 的睡眠模式
  • 为什么这个谓词格式会变成 '= nil'

    有人建议这个线程 https stackoverflow com questions 40686005 nspredicate crash after swift 3 migration与我的问题完全相同 但是 我的应用程序没有崩溃 并且我
  • NVActivityIndi​​catorView 仅适用于特定视图

    我正在使用这个库https github com ninjaprox NVActivityIndi catorView https github com ninjaprox NVActivityIndicatorView用于显示加载指示器
  • Swift C 回调 - Swift 类指针的 takeUnretainedValue 或 takeRetainedValue

    我有一些UIView or UITableViewCell 里面我有 C 回调 例如 CCallback bridge self observer data gt Void in let mySelf Unmanaged

随机推荐