You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apple PTP设备withCompleteContentCatalog不触发问题(Rust + Obj-C)

是需要使用带回调的requestOpenSession(completion:)接口的

你当前遇到的仅触发didOpenSessionWithError回调、媒体文件数组为空的问题,主要由两个错误导致:

  • 你使用的无参数requestOpenSession()已经是macOS 10.15之后的废弃接口,官方明确要求替换为带completion回调的版本,旧接口的会话状态回调逻辑存在兼容问题,容易出现资源枚举失败的情况。
  • 你注册的资源枚举完成回调选择器写错了,正确的ICCameraDeviceDelegate资源枚举完成方法签名是device:didBecomeReadyWithCompleteContentCatalog:,你当前写的sel!(withCompleteContentCatalog:)参数结构完全不匹配,系统无法识别这个回调,自然不会在资源枚举完成后通知你,你在didOpenSessionWithError里直接读取mediaFiles的时候,系统还没完成资源扫描,数组自然是空的。

修复步骤如下:

  1. 修正回调选择器和对应函数的参数结构,示例代码如下:
// 修正后的枚举完成回调函数,参数匹配正确的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),
);
  1. 替换会话打开接口,删掉你代码里重复的两次无参数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()];
}
  1. 不要在didOpenSessionWithError回调中读取mediaFiles属性,该回调仅代表会话建立成功,此时系统还未开始扫描设备上的媒体资源,必须等待didBecomeReadyWithCompleteContentCatalog回调触发后再读取资源列表。

内容的提问来源于stack exchange,提问作者Mikeumus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 17:45:03