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
相关产品推荐
相关产品推荐

