iOS 中文件的下载,预览,分享,上传总结

2020-03-06  本文已影响0人  SoaringHeart

思路:开始想将下载的文档存到特定位置,然后上传到的时候去取文件的本体,转为NSData,然后上传,后来发现实现太过麻烦,随弃之。重新思考需求是什么?需求本质是对下载的文档可以分享出去(到PC端,打印盖章),然后上传PDF到服务器进行人工审核(图片的话体积会大会自动压缩,压缩无法保证清晰度,随弃之),最终实现:通过文件链接下载——存储到沙盒文件夹——通过文件的NSURL分享到微信——文件PC端编辑——传到iCloud——从ICloud选择该文件上传到服务器并获得文件的最新链接——...

🔥:图片上传一般转为NSData,文件上传传的是本地存储位置的NSURL,这种方式的优点是可以一次性多张图片,多文档,多字符串参数,多对多混搭上传,成倍缩减工作量,优势极其明显。
项目中需要进行文档的操作:

需求一: 通过网络连接下载文档并分享到微信,airdop等等,进行编辑(签字盖章)

1.下载文档

/// AFN 下载文件
func requestDownload(_ URL: URL) {
    NNProgressHUD.showLoading("载入中...")
    
    let config = URLSessionConfiguration.default
    let manager = AFHTTPSessionManager(sessionConfiguration: config)
    
    let request = URLRequest(url: URL)
    let task = manager.downloadTask(with: request, progress: { (progress) in
        let current = progress.completedUnitCount/progress.totalUnitCount
        DDLog("current:\(current)")
        
    }, destination: { (url, response) -> URL in
        let documentsDirectoryURL = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
        let docURL: URL = (documentsDirectoryURL?.appendingPathComponent(response.suggestedFilename!))!
        return docURL
    }) { (response, url, error) in
        DDLog("File downloaded to:\(url?.path ?? "地址错误")")
        self.localFileUrl = url as NSURL?
        
        if error != nil {
            NNProgressHUD.showError(error?.localizedDescription)
        } else {
            NNProgressHUD.dismiss()
        }
    }
    task.resume()
}

2.预览下载的文件,看是否正确

var localFileUrl: NSURL?{
    willSet{
        if newValue == nil {
            return
        }
        DispatchQueue.main.async {
            self.preController.reloadData()
        }
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    edgesForExtendedLayout = []
    view.backgroundColor = UIColor.white
    // Do any additional setup after loading the view.

    preController.view.frame = self.view.bounds
    self.addChild(preController)
    preController.didMove(toParent: self)
    self.view.addSubview(preController.view)
}

/// 预览视图
lazy var preController: QLPreviewController = {
    let controller = QLPreviewController()
    controller.edgesForExtendedLayout = []
    controller.dataSource = self
    controller.delegate = self
    controller.currentPreviewItemIndex = 0
    
    return controller
}()

3.确定是需要下载的文档,分享到分享到微信,airdop等等,进行编辑(签字盖章)

///展示文件分享弹窗
func presentOptionsMenu() {
    guard let url = localFileUrl as URL? else {
        NNProgressHUD.showText("文件链接不能为空")
        return
    }
    delegate?.fileShare?(url.path, forKey: key)

    docController.url = url
    let result = docController.presentOptionsMenu(from: self.view.bounds, in: self.view, animated: true)
    if result == false {
        DDLog("没有程序可以打开要分享的文件")
    }
}
/// 文件分享弹窗
lazy var docController: UIDocumentInteractionController = {
    let controller = UIDocumentInteractionController()
    controller.delegate = self;
    controller.presentPreview(animated: true)
    return controller
}()

需求二:选择之前(签字盖章)的本地文档并上传到服务器端
首先将文档保存在你熟悉的位置,iCloud, Documents
1.选择某一文档

func showDocmentPicker() {
    present(docPickVC, animated: true, completion: nil)
}

static let docTypes = ["com.microsoft.word.doc",
    "com.adobe.pdf",
    "public.text",
    ]

/// 文件选择器
lazy var docPickVC: UIDocumentPickerViewController = {
    let controller = UIDocumentPickerViewController(documentTypes: IOPFileUploadController.docTypes, in: .import)
    controller.modalPresentationStyle = .fullScreen
    controller.delegate = self
    return controller
}()

2.预览文件(同上)

3.上传文档(成功后接口返回对应url)

/// AFN上传文件
func requestUpload() {
    NNProgressHUD.showLoading("上传中...")
    
    let urlString = "*/img_upload"
    let parameters: [String: Any] = ["token": "680b2275a2318b076a6c883908bae43e",
                                     "file": localFileUrl as Any,
    ]

    let config = URLSessionConfiguration.default
    let manager = AFHTTPSessionManager(sessionConfiguration: config)
    manager.requestSerializer.setValue("multipart/form-data", forHTTPHeaderField: "Content-Type")
    manager.requestSerializer.setValue("IOP/iOS", forHTTPHeaderField: "User-Agent")
    manager.requestSerializer.setValue("3.3.1", forHTTPHeaderField: "Accept-Version")
    
    manager.post(urlString, parameters: nil, constructingBodyWith: { (formData) in
        for (key, value) in parameters {
            switch value {
            case is String:
                if let data = (value as! String).data(using: .utf8) {
                    formData.appendPart(withForm: data, name: key)
                }
                
            case is Data:
                formData.appendPart(withForm: value as! Data, name: key)
                
            case is URL, is NSURL:
                do{
                    try formData.appendPart(withFileURL: value as! URL, name: key)
                } catch {
                    DDLog("error:\(error.localizedDescription)")
                }
                
            default:
                break
            }
        }
        
    }, progress: { (progress) in
        let currentValue = progress.completedUnitCount/progress.totalUnitCount
        DDLog("currentValue_\(currentValue)")
        
    }, success: { (task, responseObject) in
        NNProgressHUD.showSuccess("请求成功")
        let dic = (responseObject as! [String: Any])["data"] as! [String: Any]
        self.delegate?.fileUpload?(dic["url"] as! String, forKey: self.key)
        
    }) { (task, error) in
        NNProgressHUD.showError(error.localizedDescription)

    }
}

IOPFileUploadController.swift

上一篇 下一篇

猜你喜欢

热点阅读