Flutter中如何跳转至iOS原生添加联系人页面
iOS Swift 唤起原生添加联系人页面实现方案
1. 前置配置
首先需要在项目的Info.plist中添加联系人写入权限声明:
配置key:
NSContactsUsageDescription,值填写你需要向用户说明的权限用途,例如「需要访问通讯录以添加联系人」
如果缺失该配置,应用调用通讯录相关接口时会直接崩溃。
2. Swift 侧代码实现
需要引入系统自带的Contacts和ContactsUI框架,遵循CNContactViewControllerDelegate协议处理用户操作回调。
完整实现示例:
import UIKit import Flutter import Contacts import ContactsUI @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { let controller : FlutterViewController = window?.rootViewController as! FlutterViewController let methodChannel = FlutterMethodChannel(name: "com.yourapp.contact_channel", binaryMessenger: controller.binaryMessenger) methodChannel.setMethodCallHandler({ [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in guard call.method == "openAddContactPage" else { result(FlutterMethodNotImplemented) return } self?.openAddContactPage(result: result) }) GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } private func openAddContactPage(result: @escaping FlutterResult) { // 先检查通讯录权限 let status = CNContactStore.authorizationStatus(for: .contacts) let contactStore = CNContactStore() if status == .notDetermined { contactStore.requestAccess(for: .contacts) { [weak self] granted, error in DispatchQueue.main.async { if granted { self?.presentAddContactController(result: result) } else { result(false) } } } } else if status == .authorized { presentAddContactController(result: result) } else { result(false) } } private func presentAddContactController(result: @escaping FlutterResult) { let contact = CNMutableContact() let addContactVC = CNContactViewController(forNewContact: contact) addContactVC.delegate = self // 用导航控制器包装后弹出 let navController = UINavigationController(rootViewController: addContactVC) window?.rootViewController?.present(navController, animated: true) // 保存回调给后续代理方法使用 self.addContactResult = result } // 定义属性存储Flutter回调 private var addContactResult: FlutterResult? } // 实现CNContactViewControllerDelegate协议 extension AppDelegate: CNContactViewControllerDelegate { func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) { viewController.dismiss(animated: true) // 有contact返回代表用户点击了保存,否则是取消 addContactResult?(contact != nil) addContactResult = nil } func contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty) -> Bool { return true } }
3. 注意事项
- 代码中的通道名
com.yourapp.contact_channel需要和Flutter侧调用时的通道名保持一致 - 如果你需要给新建联系人预设字段,直接修改
CNMutableContact实例的对应属性即可,比如contact.givenName = "预设名" - 权限申请和UI操作必须在主线程执行,否则会出现系统报错
内容的提问来源于stack exchange,提问作者claudiuh
相关产品推荐
相关产品推荐

