简体   繁体   中英

Upload files with parameters from multipartformdata using alamofire 5 in ios swift

I am trying upload files with parameters (multipartformdata) but i can't do it with new version Alamofire 5, if you have some experience with Alamofire 5 please share it with me.

 func uploadPluckImage(imgData : Data, imageColumnName : String,  url:String,httpmethod:HTTPMethod,completionHandler: @escaping (NSDictionary?, String?) -> ()){
    let token = UserDefaults.standard.string(forKey: PrefKeys.loginToken) ?? ""
    let authorization = ["Authorization" : "Bearer \(token)"]
    let parameters: Parameters?
    parameters = [
        "garbageCollector": 0,
        "stuff_uuid": "2b4b750a-f4a6-4d61-84ce-7c42b5c030ee",
        "delete_file" : ""
    ]
    let headers : HTTPHeader?
    headers = ["Authorization" : "Bearer \(token)"]
    let imageURl = "http://68.183.152.132/api/v1/stuff/uploader"


    AF.upload(multipartFormData: { (multipart: MultipartFormData) in
        let imageData = self.firstImage.image?.jpegData(compressionQuality: 0.7)
            multipart.append(imageData, withName: "file", fileName: "file.png", mimeType: "image/png")

        for (ker, value) in parameters!{
            multipart.append(value as! String).data(using: .utf8)!, withName: key)
        }
    },usingThreshold: UInt64.init(),
       to: imageURl,
       method: .post,
       headers: headers,
       encodingCompletion: { (result) in
        switch result {
        case .success(let upload, _, _):
            upload.uploadProgress(closure: { (progress) in
              print("Uploading")
            })
            break
        case .failure(let encodingError):
            print("err is \(encodingError)")
                break
            }
        })
}

Upload method slightly changed in Alamofire 5

func upload(image: Data, to url: Alamofire.URLRequestConvertible, params: [String: Any]) {
    AF.upload(multipartFormData: { multiPart in
        for (key, value) in params {
            if let temp = value as? String {
                multiPart.append(temp.data(using: .utf8)!, withName: key)
            }
            if let temp = value as? Int {
                multiPart.append("\(temp)".data(using: .utf8)!, withName: key)
            }
            if let temp = value as? NSArray {
                temp.forEach({ element in
                    let keyObj = key + "[]"
                    if let string = element as? String {
                        multiPart.append(string.data(using: .utf8)!, withName: keyObj)
                    } else
                        if let num = element as? Int {
                            let value = "\(num)"
                            multiPart.append(value.data(using: .utf8)!, withName: keyObj)
                    }
                })
            }
        }
        multiPart.append(image, withName: "file", fileName: "file.png", mimeType: "image/png")
    }, with: url)
        .uploadProgress(queue: .main, closure: { progress in
            //Current upload progress of file 
            print("Upload Progress: \(progress.fractionCompleted)")
        })
        .responseJSON(completionHandler: { data in
            //Do what ever you want to do with response
        })
}

Hope this will help you

EDIT: In case you don't quite get the above, here is an expansion:

let uploadRequest: UploadRequest = AF.upload(multipartFormData: multipartFormData, with: ...)
let completionHander: (AFDataResponse<Any>) -> Void) = { result in
    //Do what ever you want to do with response, which is a DataResponse<Success, AFError>
}
// Adds that completion hander to the UploadRequest
uploadRequest.responseJSON(completionHandler: completionHander)

This how I upload images and videos from a swift 5 app with Alamofire 5.

Images

    /**
     Send Image to server
     */

    func Post(imageOrVideo : UIImage?){  

    let headers: HTTPHeaders = [
        /* "Authorization": "your_access_token",  in case you need authorization header */
        "Content-type": "multipart/form-data"
    ]


        AF.upload(
            multipartFormData: { multipartFormData in
                multipartFormData.append(imageOrVideo!.jpegData(compressionQuality: 0.5)!, withName: "upload_data" , fileName: "file.jpeg", mimeType: "image/jpeg")
        },
            to: "http://ip.here.--.--/new.php", method: .post , headers: headers)
            .response { resp in
                print(resp)               

        }
}

You can create a temporary resource and use the temporary url (good for videos):

/**
 Send video to server
 */
func PostVideoUrl(url : URL){

    let headers: HTTPHeaders = [
        "Content-type": "multipart/form-data"
    ]        

    AF.upload(
        multipartFormData: { multipartFormData in
            multipartFormData.append(url, withName: "upload_data" , fileName: "movie.mp4", mimeType: "video/mp4")
    },
        to: "http://ip.here.--.--/newVideo.php", method: .post , headers: headers)
        .response { resp in
            print(resp)

    }

}

This Is work for me Using Swift 4.2 Please try this

let url = "http://google.com" /* your API url */

let headers: HTTPHeaders = [
    /* "Authorization": "your_access_token",  in case you need authorization header */
    "Content-type": "multipart/form-data"
]

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", fileName: "image.png", mimeType: "image/png")
    }
    
}, usingThreshold: UInt64.init(), to: url, method: .post, headers: headers) { (result) in
    switch result{
    case .success(let upload, _, _):
        upload.responseJSON { response in
            print("Succesfully uploaded")
            if let err = response.error{
                onError?(err)
                return
            }
            onCompletion?(nil)
        }
    case .failure(let error):
        print("Error in upload: \(error.localizedDescription)")
        onError?(error)
    }
}
func upload(image: Data, to url: URL, params: [String: Any]) {
    let block = { (multipart: MultipartFormData) in
        URLEncoding.default.queryParameters(params).forEach { (key, value) in
            if let data = value.data(using: .utf8) {
                multipart.append(data, withName: key)
            }
        }
        multiPart.append(image, withName: "file", fileName: "file.png", mimeType: "image/png")
    }


    AF.upload(multipartFormData: block, to: url)
        .uploadProgress(queue: .main, closure: { progress in
            //Current upload progress of file 
            print("Upload Progress: \(progress.fractionCompleted)")
        })
        .responseJSON(completionHandler: { data in
            //Do what ever you want to do with response
        })
}
extension URLEncoding {
    public func queryParameters(_ parameters: [String: Any]) -> [(String, String)] {
        var components: [(String, String)] = []
        
        for key in parameters.keys.sorted(by: <) {
            let value = parameters[key]!
            components += queryComponents(fromKey: key, value: value)
        }
        return components
    }
}
// I am using Alamofire  method
 func sendIMAGeAndParamsAndDoc(urlString:String,imageData:[String:Data],documentData : [String:Data],params:[String:AnyObject], success: @escaping (AnyObject) -> Void,failure: @escaping(Error)  -> Void) {
        if (NetworkReachabilityManager()?.isReachable)!{
            let url = try! URLRequest.init(url: urlString, method: .post, headers: nil)
            Alamofire.upload(multipartFormData: { (formdata) in
                for (key, value) in params {
                    formdata.append(value.data(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue).rawValue)!, withName: key)
                }
                for (key,value) in imageData{
                    formdata.append(value, withName: key, fileName: "a.jpeg", mimeType: "image/jpeg")
                }

                for (key,value) in documentData{
                    if self.ofExtension(ext: "pdf") == true{
                        formdata.append(value, withName: key, fileName: "a.pdf", mimeType: "application/pdf")
                    }else{
                        formdata.append(value, withName: key, fileName: "a.xls", mimeType: "application/octet-stream")}
                }

            }, with: url) { (encodingResult) in
                switch encodingResult{
                case .success(let upload,_,_):
                    upload.responseJSON(completionHandler: { (response) in
                        switch response.result{
                        case .success(_):
                            if (response.response?.statusCode == 200){
                                if let value = response.result.value {
                                    success(value as AnyObject)
                                    print(value)
                                }
                            }
                            else{
                                let value = response.result.value as? [String:Any]
                                let message = value!["error_message"] as? String

                            }
                            break
                        case .failure(let error):
                            print(error)
                            break
                        }
                    })
                    break
                case .failure(let error):
                    print(error)
                    break
                }
            }
        }
        else{
        }

    }
// and use this func like this

sendIMAGeAndParams(urlString: "baseUrl", imageData: ["images" : imageArr as! Array<Data>], header: "", params: ["":""], success: { (success) in
            print(success)

        }) { (failure) in
            print(failure)

        }

Upload two images with parameters with Headers , Using Alamofire 5

i solve this issue try this code ..

//MARK: Upload Images with Params API's

func upload(icon: Data, image : Data, params: [String: Any]) {
    let urlString = "Your URL String "
    let headers: HTTPHeaders =
        ["Content-type": "multipart/form-data",
        "Accept": "application/json"]
    AF.upload(
        multipartFormData: { multipartFormData in
            for (key, value) in params {
                if let temp = value as? String {
        multipartFormData.append(temp.data(using: .utf8)!, withName: key)}

    if let temp = value as? Int {
    multipartFormData.append("(temp)".data(using: .utf8)!, withName: key)}

    if let temp = value as? NSArray {
        temp.forEach({ element in
            let keyObj = key + "[]"
            if let string = element as? String {
                multipartFormData.append(string.data(using: .utf8)!, withName: keyObj)
            } else
                if let num = element as? Int {
                    let value = "(num)"
                    multipartFormData.append(value.data(using: .utf8)!, withName: keyObj)
            }
        })
    }
}
            multipartFormData.append(icon, withName: "icon", fileName: "icon.png", mimeType: "icon/png")

            multipartFormData.append(image, withName: "registerImage", fileName: "registerImage.png", mimeType: "registerImage/png")
    },
        to: urlString, //URL Here
        method: .post,
        headers: headers)
        .responseJSON { (resp) in
            defer{SVProgressHUD.dismiss()}
            print("resp is \(resp)")
    }
}## 
  1. Heading

    #

You can do that using Router URLRequestConvertible

static func performMultiPartFile<T:Decodable>(imageData: Data, route:APIRoute,decoder: JSONDecoder = JSONDecoder(), completion: @escaping (_ result: T?, _ error: String?) -> ()) {
    Alamofire.upload(multipartFormData: { (multipartFormData) in
        multipartFormData.append(imageData, withName: "image", fileName: "iosImage.jpg", mimeType: "image/jpg")
    }, with: route) { (encodingResult) in
        switch encodingResult {

        case .success(let upload, _, _):
            upload.responseString { (response) in
                if response.result.isSuccess {
                    if let JSON = response.result.value {

                        debugPrint("✅ Respons Object >>>> " + String(describing: JSON))
                        do {
                            let result = try JSONDecoder().decode(T.self, from: JSON.data(using: .utf8)!)
                            debugPrint("✍️ Result: " + String(describing: result))
                            completion(result, nil)
                        } catch let error { // mapping fail
                            debugPrint("❌ Error in Mapping" + String(describing: error))
                            completion(nil, String(describing: error))
                        }
                    }
                } else {
                    debugPrint("❌ 😝 Response fail : \(response.result.description)")
                    completion(nil, (response.result.error?.localizedDescription)!)
                }
            }
        case .failure(let encodingError):
            completion(nil, String(describing: encodingError))
        }

    }
}

This is work with params.

func uploadImage(isUser:Bool, endUrl: String, imageData: Data?, parameters: [String : Any], onCompletion: ((_ isSuccess:Bool) -> Void)? = nil, onError: ((Error?) -> Void)? = nil){

headers = [
        "Accept": "application/json",
        "Content-type": "multipart/form-data"
  ]

AF.upload(multipartFormData: { multipartFormData in
    
    for (key, value) in parameters {
        if let temp = value as? String {
            multipartFormData.append(temp.data(using: .utf8)!, withName: key)
        }
        if let temp = value as? Int {
            multipartFormData.append("\(temp)".data(using: .utf8)!, withName: key)
        }
        if let temp = value as? NSArray {
            temp.forEach({ element in
                let keyObj = key + "[]"
                if let string = element as? String {
                    multipartFormData.append(string.data(using: .utf8)!, withName: keyObj)
                } else
                    if let num = element as? Int {
                        let value = "\(num)"
                        multipartFormData.append(value.data(using: .utf8)!, withName: keyObj)
                }
            })
        }
    }
    
    if let data = imageData{
        multipartFormData.append(data, withName: "file", fileName: "\(Date.init().timeIntervalSince1970).png", mimeType: "image/png")
    }
},
          to: endUrl, method: .post , headers: headers)
    .responseJSON(completionHandler: { (response) in
        
        print(response)
        
        if let err = response.error{
            print(err)
            onError?(err)
            return
        }
        print("Succesfully uploaded")
        
        let json = response.data
        
        if (json != nil)
        {
            let jsonObject = JSON(json!)
            print(jsonObject)
        }
    })
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM