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

Swift中使用documentpicker选取文档后如何获取文件并上传至服务器

解决方案

核心问题说明

你当前的实现已经拿到了选中文件的有效URL,两个核心问题导致无法完成上传:

  • 保留了不需要的webview预览加载逻辑,没有针对文件本身做持久化/数据读取处理
  • 你开启了多文件选择allowsMultipleSelection = true,但现有代码仅处理了第一个选中的文件

修改步骤

1. 移除预览逻辑

删除documentPicker方法中的doc_webview.load(URLRequest(url: filepathurl))这行代码。

2. 处理选中的文件

你可以二选一处理文件:

方案A:直接读取文件为二进制数据用于上传

public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
    // 遍历所有选中的文件(如果不需要多文件可以关闭allowsMultipleSelection,只取first)
    for fileURL in urls {
        do {
            // 读取文件二进制数据,可直接用于上传接口请求
            let fileData = try Data(contentsOf: fileURL)
            let fileName = fileURL.lastPathComponent
            print("读取文件成功:\(fileName),大小:\(fileData.count)字节")
            
            // 此处添加你的上传逻辑,把fileData和fileName传给服务器接口即可
            // 示例:调用你封装的上传方法
            // uploadFileToServer(data: fileData, fileName: fileName)
            
            // 你的原有业务逻辑保留
            bio_no_file_choosen_lbl.text = fileName
            //let items = TableViewItem()
            //items?.documentname = fileName
            //self.TableView_item.append(items!)
        } catch {
            print("读取文件失败:\(error.localizedDescription)")
        }
    }
    print("import result : \(urls)")
    self.bio_documentview_tvc.reloadData()
}

方案B:先把文件拷贝到App沙盒持久化再后续处理

如果需要后续还能访问该文件,建议先拷贝到App自己的Documents目录,避免临时目录文件被系统清理:

public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
    let docDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    for fileURL in urls {
        let fileName = fileURL.lastPathComponent
        let targetURL = docDir.appendingPathComponent(fileName)
        do {
            // 如果同名文件已存在先删除
            if FileManager.default.fileExists(atPath: targetURL.path) {
                try FileManager.default.removeItem(at: targetURL)
            }
            // 拷贝文件到沙盒
            try FileManager.default.copyItem(at: fileURL, to: targetURL)
            print("文件保存成功,沙盒路径:\(targetURL.path)")
            
            // 此处用targetURL做后续上传、展示逻辑即可
            bio_no_file_choosen_lbl.text = fileName
        } catch {
            print("文件保存失败:\(error.localizedDescription)")
        }
    }
    self.bio_documentview_tvc.reloadData()
}

补充说明

你初始化UIDocumentPickerViewController用的.import模式是符合需求的,系统会自动把外部文件复制到App的临时目录供你访问,不需要额外申请权限,直接读取即可。
如果需要上传表单格式的文件,按照你后端接口要求把二进制数据放到对应请求参数里即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 16:54:00