【问题标题】:Alamofire - Image Upload fails when using photosAlamofire - 使用照片时图像上传失败
【发布时间】:2017-06-23 12:41:26
【问题描述】:

尊敬的 stackoverflow 社区,

我正在使用 Alamofire 将 JSON 和图像发送到 REST API 的 iOS 应用程序中工作。使用图像选择器检索图像并存储在数组中。问题是,只要我使用从互联网等下载的图像,图像上传就可以工作。一旦我尝试上传一张照片,这张照片是用我当前使用的手机拍摄的(从照片库中选择),上传失败并抛出 400 - Bad Request 错误。奇怪的是,当我可以上传照片时,这些照片是从另一部 iPhone 拍摄的,但已发送给我,但是用手机本身拍摄的照片却无法正常工作......有人知道为什么会出现这个问题发生?我怀疑 iPhone 照片的格式或数据可能与下载的照片不同,因为 HDR 和其他东西,但我不确定这是否是问题所在。

这是我使用的代码,但它非常标准:

func POST_WITH_ATACHMENTS(description: String, attachments: [UIImage], returnCompletion: @escaping (Bool) -> ()) {
    let parameters = ["ticket":"{ \"description\" : \"" + description + "\"}"]

    APIManager.Manager.upload(multipartFormData: { multipartFormData in
        for (key, value) in parameters {
            multipartFormData.append((value.data(using: .utf8)!), withName: key, mimeType: "application/json")
        }

        var counter = 1
        for image in attachments {
            multipartFormData.append(UIImagePNGRepresentation(image)!, withName: "attachments", fileName: "attachment" + String(counter) + ".png", mimeType: "image/png")
            counter += 1
        }
    },
                     to: restURL!,
                     method: .post,
                     headers:["Authorization" : loginString],
                     encodingCompletion: { encodingResult in
                        switch encodingResult {
                        case .success(let upload, _, _):
                            upload.responseJSON { response in
                                debugPrint(response)
                                if (upload.response?.statusCode == 201) {
                                    returnCompletion(true)
                                } else {
                                    returnCompletion(false)
                                }
                            }
                        case .failure(let encodingError):
                            print(encodingError)
                            returnCompletion(false)
                        }
    })
}

【问题讨论】:

  • 尝试使用 image/jpeg 作为 mime 类型。因为这对于大多数图像格式都很常见,例如.jpg.jpeg.jfif
  • 我尝试了您的解决方案并发现,这取决于我认为的图像大小...如果我将调整大小因子设置为 0.5,则照片上传有效,但未压缩它会失败... . 奇怪,服务器可能不支持那么大的图像。谢谢!
  • Alamofire 中有一个选项可用于流式传输您的内容。看看它。可能对上传大尺寸图片有用。
  • @RobertBarta 使用我的方法使用 AlamoFire 上传图片

标签: ios swift rest alamofire multipart


【解决方案1】:

这是使用 AlamoFire 上传图片的网络服务

class WebServiceHandler: AnyObject {

    func uploadWithAlamofire(Parameters params : [NSObject : AnyObject]?,ImageParameters imgparams :  [NSObject : AnyObject]?,Action action : NSString, success: @escaping (AnyObject) -> Void, failure: @escaping (AnyObject) -> Void)
    {
        var base_url = "YOUR BASE_URL"
        base_url.append(action as String)

        Alamofire.upload(multipartFormData: { multipartFormData in
            if imgparams != nil{
                for (key, value) in imgparams! {
                    if let imageData = UIImageJPEGRepresentation(value as! UIImage, 1) {
                        multipartFormData.append(imageData, withName: key as! String, fileName: "\(NSDate().timeIntervalSince1970 * 1000)).jpg", mimeType: "image/jpg")
                    }
                }
            }

            if params != nil
            {
                for (key, value) in params! {
                    multipartFormData.append((value as! String).data(using: .utf8)!, withName: key as! String)
                }

            } }, to: base_url, method: .post, headers: nil,
                 encodingCompletion: { encodingResult in
                    switch encodingResult {
                    case .success(let upload, _, _):
                        upload.uploadProgress { progress in
                            print(progress.fractionCompleted)
                        }
                        upload.response { [weak self] response in
                            guard self != nil else {
                                return
                            }
                            let responseString = String(data: response.data!, encoding: String.Encoding.utf8)
                            return success(responseString as AnyObject)

                        }
                    case .failure(let encodingError):
                        print("error:\(encodingError)")
                        return failure(encodingError as AnyObject)
                    }
        })
    }
    func convertToDictionary(text: String) -> [String: Any]? {
        if let data = text.data(using: .utf8) {
            do {
                return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
            } catch {
                print(error.localizedDescription)
            }
        }
        return nil
    }
}


----------------------------USAGE-----------------------------

let dict_params = NSMutableDictionary()
dict_params.set("123", forKey:"YourKey")
dict_params.set("123", forKey:"YourKey")
.
.
.and so on

let imgparam = NSMutableDictionary()
imgparam.set(YourImagetoUpload, forKey: "YourKey")
//here YourImagetoUpload is like imageview.image or UIImage(named: "123.png")
imgparam.set(YourImagetoUpload, forKey: "YourKey")
.
.
.and so on


self.webservice.uploadWithAlamofire(Parameters: dict_params as [NSObject : AnyObject], ImageParameters: imgparam as [NSObject : AnyObject], Action: "API_ACTION_CALL", success: { (success) in
        print(success)
}) { (error) in
        print(error)
}

【讨论】:

  • 谢谢!该方法与我的相似,所以我认为问题确实出在服务器端,REST API 不支持那么大的图像,我可能会尝试建议的流版本,或者缩小图像,因为它们不需要完全解决我的项目。
猜你喜欢
  • 2017-02-22
  • 2018-07-17
  • 2016-11-26
  • 2015-07-11
  • 2018-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多