在 iOS 中使用 Alamofire 上传图像

Posted

技术标签:

【中文标题】在 iOS 中使用 Alamofire 上传图像【英文标题】:Uploading a image with Alamofire in iOS 【发布时间】:2019-05-01 14:40:09 【问题描述】:

我正在尝试使用 Alamofire 上传图片,但它似乎无法上传。

    Alamofire.upload(multipartFormData:  multipartFormData in
        multipartFormData.append(imgData, withName: "data", fileName: "\(Date().timeIntervalSince1970).jpg", mimeType: "image/jpg")
        multipartFormData.append(operaID.data, withName: "id")
    ,
                     to: URL_CORDINATE)
     (result) in
        switch result 
        case .success(let upload, _, _):

            upload.uploadProgress(closure:  (progress) in
                print("Upload Progress: \(progress.fractionCompleted)")
            )

            upload.responseJSON  response in
                print("Upload image response:", response.result.value)
            

        case .failure(let encodingError):
            print("Error while uploading image:", encodingError)
        

我期待看到图片上传,但是 body 似乎有问题(我应该将 body 中的 img 和 id 不作为参数传递!)

它在 Postman 中确实有效:https://i.stack.imgur.com/f0mUd.png

【问题讨论】:

有错误输出吗? 输出没有错误 【参考方案1】:

你可以试试这个:

Alamofire.upload(
                multipartFormData:  multipartFormData in
                    multipartFormData.append(imgData!, withName: "img", fileName: "jpg", mimeType: "image/jpeg")
            ,
                to: UPLOAD_IMAGE_URL,
                encodingCompletion:  (encodingResult) -> Void in
                    switch encodingResult 
                    case .success(let upload, _, _):
                        upload.responseJSON  response in
                            let result = response.data
                            do 
                                print("success")
                            catch 
                                print("error")
                            
                        
                    case .failure(let encodingError):
                        print(encodingError)

                    
            )

【讨论】:

【参考方案2】:

乍一看,它缺少 HTTP 方法:.post,mimeType 应该是 "image/jpeg",而不是 "image/jpg"

看这个:

    Alamofire.upload(multipartFormData:  multipartFormData in
        multipartFormData.append(imgData, withName: "data", fileName: "\(Date().timeIntervalSince1970).jpg", mimeType: "image/jpeg")
        multipartFormData.append(operaID.data, withName: "id")
    ,
    to: YOUR_URL_HERE,
    method: .post,
    encodingCompletion:  result in
        switch result 
        case .success(let upload, _, _):

            upload.uploadProgress(closure:  (progress) in
                print("Upload Progress: \(progress.fractionCompleted)")
            )

            upload.responseJSON  response in
                print("Upload image response:", response.result.value)
            

        case .failure(let encodingError):
            print("Error while uploading image:", encodingError)
        
    )

是否有任何服务器日志指示错误?您可以在服务器代码中添加断点并在 localhost 上运行它以检查您的控制器中的内容吗?

如果服务器端点是 http,请将其放入您的 Info.plist:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

【讨论】:

我已尝试进行您建议的更改,但它似乎仍然无法正常工作(当我打印 Alamofire 给出的结果时,我得到:“CredStore - performQuery - 复制匹配凭据时出错”)。不知道为什么! 你的网址是什么?是http还是https? http 服务器端点可能会发生此错误。 artaugmentedreality.com/api/postpreview 正文中带有“img”(图像)和“id”(例如 44)。 我将域添加到支持 HTTP 域的 info.plist 中的列表中,但仍然出现相同的错误! :( 您的Info.plist 怎么样?扩展我的答案。【参考方案3】:
        Alamofire.upload(multipartFormData:  multipartFormData in
            if let img = image, let imageData = img.jpegData(compressionQuality: 0.6) 
                multipartFormData.append(imageData, withName: imageName, fileName: "temp.jpg", mimeType: "image/jpg")
            
            for (key, value) in parameter ?? [:] 
                if value is String || value is Int 
                    multipartFormData.append("\(value)".data(using: .utf8)!, withName: key)
                
            
        , to: url, headers: headers, encodingCompletion:  encodingResult in
            switch encodingResult 
            case .success(let upload, _ , _ ):
                upload.responseJSON  response in
                    debugPrint(response)
                    if response.response?.statusCode == 200
                    
                        if let jsonData = try? JSONSerialization.data(withJSONObject: response.result.value!, options: .prettyPrinted) 
                            print("Response: \n",String(data: jsonData, encoding: String.Encoding.utf8) ?? "nil")
                        
                        success(response.result.value! as AnyObject)
                    else
                    
                        let res = response.result.value! as AnyObject
                        let msg = res["Message"] as? String
                        if msg != nil
                        
                            failure(msg!)
                        else
                        
                            failure("")
                        
                    
                
            case .failure(let encodingError):
                print(encodingError)
                failure(encodingError.localizedDescription)
            
        )

【讨论】:

以上是关于在 iOS 中使用 Alamofire 上传图像的主要内容,如果未能解决你的问题,请参考以下文章

Alamofire - 使用照片时图像上传失败

使用 PHP 在 Swift 5 中使用 Alamofire 接收图像上传

使用 Alamofire 上传图像不成功

使用 Alamofire 将图像作为 base64String 上传

如何在 Swift 中使用 Alamofire 上传带有 JSON 参数的图像?

如何在swift中使用alamofire上传图库图片