SwiftUI PhotosPicker如何获取选中项的KB大小?
如何直接获取SwiftUI PhotosPicker选中项的大小(KB单位)?
相关代码
var body: some View { PhotosPicker(selection: $selectedItem, matching: .any(of: [.images, .videos]), photoLibrary: .shared()){ Image(systemName: "camera.fill") .resizable() .aspectRatio(contentMode: .fit) .frame(height: 20) .padding(2) } .onChange(of: selectedItem) { newItem in // item size in kilobytes? } }
问题描述
是否有方法直接获取selectedItem的大小(以KB为单位)?我知晓可先获取文件URL再计算大小,但该方法繁琐且速度较慢,希望找到更优方案。
解决方案
PhotosPickerItem本身并没有直接暴露文件大小的属性,无法一步获取,但可以用更高效的方式替代“存URL再计算”的方案:
- 小文件优先选择:直接加载数据计算大小
通过loadTransferable(type: Data.self)直接在内存中加载选中项的数据,然后通过data.count获取字节数,再转换为KB单位。这种方式不需要写入临时文件,速度更快,代码也更简洁:
.onChange(of: selectedItem) { newItem in guard let item = newItem else { return } Task { do { if let data = try await item.loadTransferable(type: Data.self) { let sizeInKB = Double(data.count) / 1024 // 这里可以使用计算出的大小,比如打印或更新UI print("选中项大小:\(String(format: "%.2f", sizeInKB)) KB") } } catch { print("加载数据失败:\(error.localizedDescription)") } } }
- 大文件场景:加载文件URL计算大小
如果选中的是超大文件(比如4K视频),直接加载Data可能会占用较多内存。这种情况下可以使用loadFileRepresentation方法,直接在闭包内获取文件URL并计算大小,比手动处理文件路径更简洁:
.onChange(of: selectedItem) { newItem in guard let item = newItem else { return } Task { do { try await item.loadFileRepresentation(for: .image) { fileURL, _ in let fileSize = try FileManager.default.attributesOfItem(atPath: fileURL.path)[.size] as? Int64 ?? 0 let sizeInKB = Double(fileSize) / 1024 print("选中项大小:\(String(format: "%.2f", sizeInKB)) KB") } } catch { print("获取文件失败:\(error.localizedDescription)") } } }
前者适合小文件,速度更快;后者适合大文件,内存占用更低,你可以根据实际场景选择。
内容的提问来源于stack exchange,提问作者TheGreatCornholio
相关产品推荐
相关产品推荐

