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

Swift开发iOS应用如何检测USB闪存盘的连接与断开?

iOS USB闪存盘连接/断开检测实现及相关问题解答

用户问题

我正在使用Swift开发一款iOS应用,需要实现检测USB闪存盘与设备连接或断开的功能,请问该如何实现?我已了解过External Accessory框架,但不清楚上手方法,能否提供实现指导或相关资源?此外,我有一段在macOS上可获取卷列表的代码,在iOS中却返回nil,代码如下:

let keys: [URLResourceKey] = [
    .volumeNameKey, .volumeIsRemovableKey, 
    .volumeIsEjectableKey, .volumeAvailableCapacityKey,
    .volumeTotalCapacityKey, .volumeUUIDStringKey, 
    .volumeIsBrowsableKey, .volumeIsLocalKey, .isVolumeKey
]
let manager = 
    FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: keys)

if let urls = manager {
    print(urls)
}

一、使用External Accessory框架实现USB设备连接检测

1. 项目配置

  • 在Info.plist中添加UISupportedExternalAccessoryProtocols数组键,填入目标USB设备支持的协议字符串(通常由设备厂商提供,例如com.example.usbdevice)。
  • iOS 13及以上版本,若设备依赖蓝牙配对,需添加NSBluetoothAlwaysUsageDescription权限描述,说明应用使用蓝牙的原因。

2. 监听设备连接/断开事件

通过系统通知监听设备状态变化,示例代码如下:

import ExternalAccessory

class USBMonitor {
    private let accessoryManager = EAAccessoryManager.shared()
    private var notificationTokens: [NSObjectProtocol] = []

    init() {
        setupNotifications()
    }

    private func setupNotifications() {
        // 监听设备连接
        let connectToken = NotificationCenter.default.addObserver(
            forName: .EAAccessoryDidConnect,
            object: nil,
            queue: .main
        ) { [weak self] notification in
            guard let accessory = notification.object as? EAAccessory else { return }
            self?.handleAccessoryConnected(accessory)
        }
        notificationTokens.append(connectToken)

        // 监听设备断开
        let disconnectToken = NotificationCenter.default.addObserver(
            forName: .EAAccessoryDidDisconnect,
            object: nil,
            queue: .main
        ) { [weak self] notification in
            guard let accessory = notification.object as? EAAccessory else { return }
            self?.handleAccessoryDisconnected(accessory)
        }
        notificationTokens.append(disconnectToken)
    }

    private func handleAccessoryConnected(_ accessory: EAAccessory) {
        print("设备已连接:\(accessory.name ?? "未知设备"),支持协议:\(accessory.protocolStrings)")
        // 可在此处初始化设备会话,进行数据交互
    }

    private func handleAccessoryDisconnected(_ accessory: EAAccessory) {
        print("设备已断开:\(accessory.name ?? "未知设备")")
    }

    deinit {
        notificationTokens.forEach(NotificationCenter.default.removeObserver)
    }
}

3. 注意事项

  • External Accessory框架仅支持MFi认证且实现EA协议的USB设备,普通消费级U盘(如FAT32格式)无法被直接检测,需通过UIDocumentPickerViewController让用户手动选择文件。
  • 若需要与设备进行数据交互,可通过EASession建立流会话,实现数据的读写。

二、macOS卷列表代码在iOS返回nil的原因

iOS的FileManager.mountedVolumeURLs方法受沙盒机制限制,无法获取系统级或外部存储的卷信息,仅能返回应用沙盒内无实际意义的卷数据,因此返回nil是正常行为。

如果需要访问外部USB存储的内容:

  • 对于普通U盘:使用UIDocumentPickerViewController引导用户选择文件。
  • 对于MFi认证设备:通过External Accessory框架建立会话进行数据交互。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 21:10:28