【问题标题】:How to upload image with parameters using Alamofire in Swift如何在 Swift 中使用 Alamofire 上传带参数的图像
【发布时间】:2014-12-17 07:53:25
【问题描述】:

我正在用 swift 开发一个 iPhone 应用程序。我正在使用Alamofire framework 处理http 请求。我将Alamofire.request 用于 POST 、 GET 等,如下所示:

Alamofire.request(.POST, myURL , parameters: ["a": "1", "b" : "2" ])
        .response { (request, response, data, error) in
}  

我使用Alamofire.upload 将图像上传到服务器:

Alamofire.upload(.POST, uploadURL , fileURL)

两者都完美运行,但现在我想上传一张图片并发送一些参数,我的内容类型应该是multipart/form-dataAlamofire.upload 不接受参数。

关于 swift 的这个问题还有两个关于 SO 的问题,first one 没有使用 Alamofire(真的,为什么不呢?)和在 second onemattt(Alamofire 开发人员)中引用使用编码参数.

我查看了他的示例,但仍然不知道该怎么做。

谁能帮我解决这个问题?

谢谢! :)

【问题讨论】:

  • 这是我找到的解决方案,发布到另一个问题:stackoverflow.com/questions/26121827/…
  • Reza_Rg 你能帮帮我吗?我也使用'Alamofire.upload(.POST,uploadURL,fileURL)',但我必须如何构造php文件来接收文件?通过 .POST 发送的文件在我的 php 文件中在哪里可用?
  • @Reza_Rg 你的问题解决了吗,如果解决了,你能分享一个答案吗?
  • @user2363025 是的,但我最终更改了 Alamofire 库上的一些代码,我知道这样做是不正确的。

标签: xcode swift upload alamofire


【解决方案1】:

你可以在下面的代码中使用Alamofire 3.0+

func uploadImageAndData(){
    //parameters
    let gender    = "M"
    let firstName = "firstName"
    let lastName  = "lastName"
    let dob       = "11-Jan-2000"
    let aboutme   = "aboutme"
    let token     = "token"

    var parameters = [String:AnyObject]()
    parameters = ["gender":gender,
                  "firstName":firstName,
                  "dob":dob,
                  "aboutme":about,
                  "token":token,
                  "lastName":lastName]

    let URL = "http://yourserviceurl/"
    let image = UIImage(named: "image.png")

    Alamofire.upload(.POST, URL, multipartFormData: {
        multipartFormData in

        if let imageData = UIImageJPEGRepresentation(image, 0.6) {
            multipartFormData.appendBodyPart(data: imageData, name: "image", fileName: "file.png", mimeType: "image/png")
        }

        for (key, value) in parameters {
            multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
        }
    }, encodingCompletion: {
        encodingResult in

        switch encodingResult {
        case .Success(let upload, _, _):
            print("s")
            upload.responseJSON { 
                response in
                print(response.request)  // original URL request
                print(response.response) // URL response
                print(response.data)     // server data
                print(response.result)   // result of response serialization

                if let JSON = response.result.value {
                    print("JSON: \(JSON)")
                }
            }
        case .Failure(let encodingError):
            print(encodingError)
        }
    })
}

【讨论】:

  • HTTP 错误 415 不支持的媒体类型请检查图像类型@chamathjeevan
  • 如果下面的参数中有一个关键的“image” ["gender":gender,"firstName":firstName,"dob":dob,"aboutme":aboutme,"token":token, "lastName":lastName, "image": imageData] 那么 multipartFormData.appendBodyPart(data: imageData, name: "image", fileName: "file.png", mimeType: "image/png") 会追加参数吗?跨度>
  • @amitgupta 我希望你有我的问题
  • 效果很好,一个问题如果我从相机拍照并执行 UIImage 上的 UIImagePNGRepresentation 函数,我如何保持方向?
  • 即使将语法 a/c 更改为 swift 3,它也不适用于 swift 3
【解决方案2】:

SWIFT 2 AlamoFire 简单图像上传(REST API)

@amit gupta 似乎答案包含很大的开销。 AlamoFire 包含大量简化的解决方案。 Alamofire.request 方法包含几个简化的重载,可以用来以简单的方式上传。通过使用 Alamofire.request( 方法,开发者可以摆脱编码开销。

由于未指定正确的媒体类型,HTTP 状态 415。

请在下面查看我的解决方案。

import UIKit
import Alamofire

class ViewController: UIViewController {

    @IBOutlet var imageView: UIImageView!
    @IBOutlet var btnUpload: UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func successDataHandler(responseData:String){

        print ("IMAGE UPLOAD SUCCESSFUL    !!!")

    }

    func failureDataHandler(errorData:String){

        print ("  !!!   IMAGE UPLOAD FAILURE   !!! ")

    }

    @IBAction func actionUpload(sender: AnyObject) {

        let URL = "http://m8coreapibeta.azurewebsites.net/api/cards/SaveImages"

        let postDataProlife:[String:AnyObject] = ["CardId":(dataCardDetail?.userId)!,"ImageType":1,"ImageData":imageView.image!]

        uplaodImageData(URL, postData: postDataProlife, successHandler: successDataHandler, failureHandler: failureDataHandler)
    }

    func uplaodImageData(RequestURL: String,postData:[String:AnyObject]?,successHandler: (String) -> (),failureHandler: (String) -> ()) -> () {

        let headerData:[String : String] = ["Content-Type":"application/json"]

        Alamofire.request(.POST,RequestURL, parameters: postData, encoding: .URLEncodedInURL, headers: headerData).responseString{ response in
            switch response.result {
            case .Success:
                print(response.response?.statusCode)
                successHandler(response.result.value!)
            case .Failure(let error):
                failureHandler("\(error)")
            }
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

【讨论】:

    【解决方案3】:

    Almaofire 与 swift 3.0

    Alamofire.upload(multipartFormData: { multipartFormData in
        var index = 1
        for image in imageArray {
            let imageData: Data = (UIImageJPEGRepresentation(image, 1.0) as Data?)!
    
            multipartFormData.append(imageData, withName: "home-\(index)", fileName: "home-\(index)", mimeType: "image/jpeg")
    
            index += 1
        }
        }, with: requestName, encodingCompletion: { result in
            switch result {
            case .success(let upload, _, _):
    
                upload.responseJSON { response in
                    print("Image(s) Uploaded successfully:\(response)")
                }
            case .failure(let encodingError):
                print("encodingError:\(encodingError)")
            }
    })
    

    【讨论】:

    • 我的问题是图片名称和目录如何实现图片库目录及其名称?
    【解决方案4】:

    Swift 4 与 Alamofire 4

    let isConnected = connectivity.isConnectedToInternet()
    
      func updateProfile(firstName:String,lastName:String ,imageData:Data?,completion: @escaping (isValidUser)->()) {
    
    
        if self.isConnected {
    
            var parameters : [String:String] = [:]
            parameters["auth_key"] = loginUser?.authKey!
            parameters["first_name"] = firstName
            parameters["last_name"] = lastName
    
            let url = "\(baseUrl)\(basicAuthenticationUrl.updateProfile)"
            print(url)
    
    
            Alamofire.upload(multipartFormData: { (multipartFormData) in
                for (key, value) in parameters {
                    multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
                }
    
                if let data = imageData {
                    multipartFormData.append(data, withName: "image_url", fileName: "image.png", mimeType: "image/png")
                }
    
            }, usingThreshold: UInt64.init(), to: url, method: .post) { (result) in
                switch result{
                case .success(let upload, _, _):
                    upload.responseJSON { response in
                        print("Succesfully uploaded  = \(response)")
                        if let err = response.error{
    
                            print(err)
                            return
                        }
    
                    }
                case .failure(let error):
                    print("Error in upload: \(error.localizedDescription)")
    
                }
            }
        }
    
    }
    

    【讨论】:

      【解决方案5】:

      Almaofire with swift 2.0 只需复制并粘贴以下代码即可。这里是来自服务器的 JSON 响应的汇总

       func uploadImageRemote (imageData : NSData?) -> Dictionary <String,AnyObject>{
          var imageDictionary = Dictionary<String,AnyObject>()
      
            var tokenHeaders:[String:String]! = ["x-access-token":Constants.kUserDefaults.stringForKey("userToken")!]
          Alamofire.upload(
              .POST,
              "http://52.26.230.146:3300/api/profiles/imageUpload",headers:tokenHeaders,
              multipartFormData: { multipartFormData in
                  multipartFormData.appendBodyPart(data: imageData!, name: "upload", fileName: "imageFileName.jpg", mimeType: "image/jpeg")
              },
              encodingCompletion: { encodingResult in
                  switch encodingResult {
                  case .Success(let upload, _, _):
                      upload.progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in
                          print("Uploading Avatar \(totalBytesWritten) / \(totalBytesExpectedToWrite)")
                          dispatch_async(dispatch_get_main_queue(),{
      
                          })
                      }
                      upload.responseJSON { response in
                          guard response.result.error == nil else {
                              print("error calling GET \(response.result.error!)")
                              return
                          }
      
                          if let value = response.result.value {
                             print("Success JSON is:\(value)")
                              if let result = value as? Dictionary<String, AnyObject> {
                                  imageDictionary["imageUrl"] = result["url"]
                              }
                          }
      
                          dispatch_async(dispatch_get_main_queue(),{
                              //Show Alert in UI
                              print("Avatar uploaded");
                          })
                      }
      
                  case .Failure(let encodingError):
                      //Show Alert in UI
                      print("Avatar not uploaded \(encodingError)");
                  }
              }
          );
      
      
      
      return imageDictionary
      }
      

      【讨论】:

        【解决方案6】:

        要使用编码参数,请创建一个 ParameterEncoding 变量,为其分配编码类型(包括 .JSON、.URL 的枚举的情况),然后将编码函数与您的 NSURLRequest 和参数一起使用。这个函数返回一个包含两个元素的元组,第一个是产生的 NSURLRequest,第二个是产生的可能的 NSError。

        这是我如何将它用于项目中所需的自定义标题

         var parameterEncoding:ParameterEncoding!
            switch method {
                case .POST, .PUT :
                    parameterEncoding = ParameterEncoding.JSON
                default :
                    parameterEncoding = ParameterEncoding.URL
            }
            var alamoRequest = Alamofire.Manager.sharedInstance.request(parameterEncoding.encode(mutableURLRequest, parameters: parameters).0)
        

        【讨论】:

          猜你喜欢
          • 2017-07-25
          • 1970-01-01
          • 2023-03-22
          • 2017-07-14
          • 2020-07-10
          • 2019-03-16
          • 1970-01-01
          • 1970-01-01
          • 2018-02-14
          相关资源
          最近更新 更多