Apple PTP设备withCompleteContentCatalog不触发问题(Rust + Obj-C)
是需要使用带回调的requestOpenSession(completion:)接口的
你当前遇到的仅触发didOpenSessionWithError回调、媒体文件数组为空的问题,主要由两个错误导致:
- 你使用的无参数
requestOpenSession()已经是macOS 10.15之后的废弃接口,官方明确要求替换为带completion回调的版本,旧接口的会话状态回调逻辑存在兼容问题,容易出现资源枚举失败的情况。 - 你注册的资源枚举完成回调选择器写错了,正确的
ICCameraDeviceDelegate资源枚举完成方法签名是device:didBecomeReadyWithCompleteContentCatalog:,你当前写的sel!(withCompleteContentCatalog:)参数结构完全不匹配,系统无法识别这个回调,自然不会在资源枚举完成后通知你,你在didOpenSessionWithError里直接读取mediaFiles的时候,系统还没完成资源扫描,数组自然是空的。
修复步骤如下:
- 修正回调选择器和对应函数的参数结构,示例代码如下:
// 修正后的枚举完成回调函数,参数匹配正确的selector extern "C" fn device_did_become_ready( _: &Object, _: Sel, _device: id, _content_catalog: id, ) { println!(" 🤩📷 设备资源枚举完成"); unsafe { let media_files = _device.mediaFiles(); println!(" 媒体文件总数: {}", media_files.count()); } } // 注册方法时使用正确的selector decl.add_method( sel!(device:didBecomeReadyWithCompleteContentCatalog:), device_did_become_ready as extern "C" fn(&Object, Sel, id, id), );
- 替换会话打开接口,删掉你代码里重复的两次无参数
requestOpenSession调用,改为使用带回调的版本:
unsafe { let completion_block = block::ConcreteBlock::new(move |error: id| { if error != nil { println!("会话打开失败,错误信息: {:?}", error); return; } println!("会话打开成功,等待系统枚举媒体资源"); }); let _: () = msg_send![device_self, requestOpenSessionWithCompletion: completion_block.copy()]; }
- 不要在
didOpenSessionWithError回调中读取mediaFiles属性,该回调仅代表会话建立成功,此时系统还未开始扫描设备上的媒体资源,必须等待didBecomeReadyWithCompleteContentCatalog回调触发后再读取资源列表。
内容的提问来源于stack exchange,提问作者Mikeumus
相关产品推荐
相关产品推荐

