如何在Xcode 14的Mac CLI应用中访问通讯录并配置权限
Mac CLI应用访问通讯录权限配置方案
问题分析
Mac CLI项目默认未关联info.plist,导致系统读取不到通讯录权限的描述文本(NSContactsUsageDescription),因此不会触发权限请求弹窗;同时CLI项目的权限申请依赖正确的代码签名和plist绑定,这两个环节缺失都会导致权限请求失效。
解决步骤
1. 创建并配置info.plist
- 新建一个Property List文件(命名为
Info.plist),添加NSContactsUsageDescription键,值填写权限申请的说明(例如需要访问通讯录以获取联系人信息) - 关联到CLI Target:
- 选中项目的CLI Target,切换到Build Settings标签页
- 搜索
Info.plist File,设置为该文件的相对路径(比如$(SRCROOT)/YourProjectName/Info.plist) - 搜索
Copy Info.plist into Product Bundle,设置为YES
2. 开启代码签名
Mac权限系统要求可执行文件必须经过代码签名,哪怕是开发阶段:
- 选中CLI Target,切换到Signing & Capabilities标签页
- 勾选
Automatically manage signing,选择你的开发团队 - 确保签名证书为有效的开发证书
3. 验证代码逻辑
你的代码逻辑基本正确,但需要补充非权限申请分支的RunLoop停止操作,避免进程无限挂起:
#import <Foundation/Foundation.h> #import <Contacts/Contacts.h> int main(int argc, const char * argv[]) { @autoreleasepool { CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]; if (status == CNAuthorizationStatusNotDetermined) { NSLog(@"Contact access not determined."); CNContactStore *contactStore = [[CNContactStore alloc] init]; [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) { NSLog(@"Got response"); NSLog(granted ? @"Yes" : @"No"); if (error) { NSLog(@"Error: %@", error.localizedDescription); } CFRunLoopStop(CFRunLoopGetCurrent()); }]; } else if (status == CNAuthorizationStatusAuthorized) { NSLog(@"Access granted"); CFRunLoopStop(CFRunLoopGetCurrent()); } else { NSLog(@"Access to contacts is denied or restricted."); CFRunLoopStop(CFRunLoopGetCurrent()); } } CFRunLoopRun(); return 0; }
关键说明
info.plist完全适用于Mac CLI项目,但必须正确关联到Target并复制到产物中,否则系统无法读取权限描述,不会触发弹窗- 权限弹窗只会在首次请求时出现,如果之前已经拒绝过,需要到系统设置 > 隐私与安全性 > 通讯录中手动开启权限
内容的提问来源于stack exchange,提问作者branisha
相关产品推荐
相关产品推荐

