iOS 13 Image Capture API 用于访问外部相机的文件系统?

iOS 13 Image Capture API for accessing external camera's filesystem?

Apple's iOS 13 feature list page 他们有以下宣传语:

Image Capture API

The Image Capture API allows developers to leverage the Camera Connection Kit to import photos directly into their apps.

我一直在寻找,但我似乎找不到关于此更改的任何实际文档,以及它在 API 中的位置。我还记得在 WWDC 19 的 keynote/state 联盟中听过一两次关于它的讨论,但在我迄今为止发现的任何 session 中也没有任何细节。

您似乎可以将相机或其 SD 卡插入 iOS 设备上的 USB-C/Lightning 端口,并能够从第 3 方应用程序中访问它。我知道您可以导入系统照片库,但这已经存在多年了。我也知道 ExternalAccessory MiFi 硬件框架,但我没有看到任何重大变化,而且它似乎没有公开所描述的功能。

我确实看到 UIDocumentPicker 可以显示,它允许用户 select 可能位于已连接 USB 设备上的位置。虽然这可行,但它不是特定于相机的,如果用户没有 select 有效的相机位置,则很容易出错。

有人知道我在哪里可以找到有关此更改的更多信息或如何以编程方式访问相机的文件系统吗?相机将具有标准相机文件夹结构 DCIM 和内容,因此它被许多 Mac 应用程序识别为相机文件系统。

您正在寻找 ImageCaptureCore 框架。这与 macOS 上存在的用于从 SD 卡和相机导入的框架相同。它现在在 iOS 13.2 中可用。

更新:

ImageCaptureCore API 从 iOS 13.2 开始工作。

但是,请注意,从 iOS/iPadOS 13.1 Beta 3 (17A5837a) 开始,我还无法让它正常工作(已向 Apple FB6799036 报告)。它现在在 iPadOS Features page 上以星号列出,表示它将是 "Coming later this year".

我能够启动 ICDeviceBrowser,但是当设备连接时我看到权限错误并且没有收到任何委托消息。因此在它开始工作之前可能需要一些许可或权利。

遗憾的是,Apple 的开发者网站上没有文档或示例代码(即使是 macOS)。但该框架确实存在于 iOS 13 SDK 中,您可以查看那里的 header 文件。

我们在我们的 macOS 应用程序中使用这个框架,并且仅使用 headers 来解决问题也不错。您首先要创建一个 ICDeviceBrowser (ICDeviceBrowser.h),设置它的委托,然后启动浏览器:

@interface CameraManager() : NSObject <ICDeviceBrowserDelegate>
{
    ICDeviceBrowser* _deviceBrowser;
}
@end

@implementation CameraManager
- (id) init
{
    self = [super init];
    _deviceBrowser = [[ICDeviceBrowser alloc] init];
    _deviceBrowser.delegate = self;
    [_deviceBrowser start];

    return self;
}
...
@end

您应该在连接相机设备时开始接收委托消息:

- (void)deviceBrowser:(ICDeviceBrowser*)browser didAddDevice:(ICDevice*)addedDevice moreComing:(BOOL)moreComing;
- (void)deviceBrowser:(ICDeviceBrowser*)browser didRemoveDevice:(ICDevice*)removedDevice moreGoing:(BOOL)moreGoing;

当您收到 didAddDevice: 消息时,您会想要使用 ICDevice (ICDevice.h) 和 ICCameraDevice (ICCameraDevice.h) APIs 设置委托并启动 session。 session 启动后,您将开始接收委托消息:

- (void)deviceBrowser:(ICDeviceBrowser*)browser didAddDevice:(ICDevice*)addedDevice moreComing:(BOOL)moreComing
{
    if ((addedDevice.type & ICDeviceTypeMaskCamera) == ICDeviceTypeCamera)
    {
        ICCameraDevice* camera = (ICCameraDevice *) addedDevice;
        camera.delegate = self;
        [camera requestOpenSession];
        //  probably want to save 'camera' to a member variable
    }
}

您可以使用委托方法:

- (void)cameraDevice:(nonnull ICCameraDevice *)camera
         didAddItems:(nonnull NSArray<ICCameraItem *> *)items;

要获取由 API 枚举的项目列表或等待:

- (void)deviceDidBecomeReadyWithCompleteContentCatalog:(ICDevice*)device;

然后在ICCameraDevice上使用.contents属性得到全部内容。

从那里您可以使用 ICCameraDevice 请求缩略图、元数据和下载特定文件。我将把它留给 reader.

作为练习

正如我上面提到的,这似乎在 iOS/iPadOS 13.1 Beta 3 中不起作用。希望这一切都能尽快开始工作,因为我真的很想自己开始测试它.

现在可以在 iOS 13.2 中使用。