修改相册权限后Image PickerViewController卡顿触发NSXPCConnection异常
问题分析与解决方案
我之前在开发中也碰到过一模一样的场景:刚修改完相册权限就立刻调用图片选择器,结果应用卡顿、系统抛出NSXPCConnection异常,图片选择器的代理方法完全没触发。结合你给出的日志和症状,问题根源其实是权限变更后系统的相册服务还没完成状态同步,这时候你的图片选择器请求直接打断了XPC连接的状态更新流程,导致连接失效,进而代理回调无法正常触发。
日志里的<NSXPCConnection: 0x1c41153c0>异常就是关键信号——系统相册选择器是通过XPC和系统级的相册服务通信的,权限刚变更完,服务端的状态还没跟上客户端的请求,就会出现这种连接异常并丢弃消息的情况。
给你几个亲测有效的解决方案:
延迟调用图片选择器:在权限确认授权后,不要立刻弹出选择器,给系统留200-300ms的同步时间。用主队列的延迟异步任务包裹选择器的present代码,比如:
PHPhotoLibrary.requestAuthorization { status in guard status == .authorized else { return } // 延迟0.3秒再启动选择器 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { let picker = UIImagePickerController() picker.delegate = self picker.sourceType = .photoLibrary self.present(picker, animated: true) } }监听权限变更通知:不要依赖权限请求的回调直接触发选择器,而是注册
PHPhotoLibraryAuthorizationStatusDidChange通知,等系统明确发出权限状态变更完成的信号后再启动选择器:// 先注册通知 NotificationCenter.default.addObserver(self, selector: #selector(handlePhotoAuthChange), name: NSNotification.Name.PHPhotoLibraryAuthorizationStatusDidChange, object: nil) // 处理通知的方法 @objc func handlePhotoAuthChange(_ notification: Notification) { let status = PHPhotoLibrary.authorizationStatus() if status == .authorized { // 启动图片选择器 let picker = UIImagePickerController() picker.delegate = self picker.sourceType = .photoLibrary self.present(picker, animated: true) // 记得用完移除通知 NotificationCenter.default.removeObserver(self, name: NSNotification.Name.PHPhotoLibraryAuthorizationStatusDidChange, object: nil) } }二次校验权限状态:在present选择器前,再次主动检查权限状态,确保确实是
.authorized状态再执行操作,避免因为状态同步不及时导致的无效请求。
这些方案的核心都是给系统足够的时间完成权限状态的跨进程同步,避免请求和系统状态更新冲突,从而解决XPC连接异常和代理方法不触发的问题。
内容的提问来源于stack exchange,提问作者Nijosh
相关产品推荐
相关产品推荐

