How to upload multipart image to server using Alamofire

十年热恋 提交于 2019-12-11 14:34:07

问题


Below mentioned is my method to upload a multipart image to the server but when I am trying to do so the app is crashing "unexpectedly found nill"

But value of image is there as I am selecting it from photo library.

func createCoupon(_ code: String, storeID: Int, description: String, terms: String, image: UIImage, startDate: String, endDate: String, couponDiscount: String, minimumDiscount: String, percentage: String, maximumDiscount: String){
    let urlString = BaseURL + "create-coupon"
    let params =
        [
            "code"               :  code,
            "store_id"           :  storeID,
            "type"               :  "merchant",
            "description"        :  description,
            "terms"              :  terms,
            "start_date"         :  startDate,
            "end_date"           :  endDate,
            "coupon_discount"    :  couponDiscount,
            "minimum_total"      :  minimumDiscount,
            "percentage"         :  percentage,
            "maximum_discount"   :  maximumDiscount
            ] as [String : Any]

    let manager = Alamofire.SessionManager.default
    manager.session.configuration.timeoutIntervalForRequest = 30000
    Alamofire.upload(multipartFormData: { (multipartFormData) in
        multipartFormData.append(UIImageJPEGRepresentation(image, 0.2)!, withName: "image", fileName: "swift_file.jpeg", mimeType: "image/jpeg")
        for (key, value) in params {
            multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
        }
    }, to:urlString)
    {
        (result) in
        switch result {
        case .success(let upload, _, _):

            upload.uploadProgress(closure: { (progress) in
                //Print progress
            })
            upload.responseJSON { response in
                let resJson = response.result.value
                print(resJson)
                NotificationCenter.default.post(name: Notification.Name(rawValue: NotifRequestSuccess.createCoupon.rawValue), object: nil, userInfo: ["data": resJson!])
            }

        case .failure(let encodingError):
            NotificationCenter.default.post(name: Notification.Name(rawValue: NotifRequestError.createCoupon.rawValue), object: encodingError, userInfo: nil)
        }
    }

回答1:


Alamofire.upload(multipartFormData: { (multipartFormData) in
            multipartFormData.append(UIImageJPEGRepresentation(self.photoImageView.image!, 0.5)!, withName: "photo_path", fileName: "swift_file.jpeg", mimeType: "image/jpeg")
            for (key, value) in parameters {
                multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
            }
            }, to:"http://server1/upload_img.php")
        { (result) in
            switch result {
            case .success(let upload, _, _):

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

                upload.responseJSON { response in
                    //self.delegate?.showSuccessAlert()
                    print(response.request)  // original URL request
                    print(response.response) // URL response
                    print(response.data)     // server data
                    print(response.result)   // result of response serialization
                    //                        self.showSuccesAlert()
                    //self.removeImage("frame", fileExtension: "txt")
                    if let JSON = response.result.value {
                        print("JSON: \(JSON)")
                    }
                }

            case .failure(let encodingError):
                //self.delegate?.showFailAlert()
                print(encodingError)
            }

        }



回答2:


Just simple Use this Function as

/// Data for image
var userImageString = Data()

/// Convert Image to Data
func convertImageToData(image: UIImage) -> Data {            
     let imageData = UIImageJPEGRepresentation(image, 0.1)!
     return imageData
 }

 ///Conversion Method - with target size if required
 userImageString = convertImageToData(image: resizeImage(image: img, targetSize: CGSize.init(width: 600, height: 600)))

//MARK: Data to server
func imageDataToServer(parameters: [String : AnyObject])
{
    Alamofire.upload(multipartFormData: { (multipartFormData) in
        multipartFormData.append(self.userImageString, withName: "parameter_name", fileName: "image.jpeg", mimeType: "image/jpeg")
        for (key, value) in parameters
        {
            multipartFormData.append(value.data(using: String.Encoding.utf8.rawValue)!, withName: key)
        }

    }, to:"url", method: .post,
                     encodingCompletion: { encodingResult in
                         switch encodingResult {
                         case .success(let upload,_,_):

                             upload.responseJSON { (response:DataResponse<Any>) in
                                 print("RRRRR: \(response)")
                                 if response.result.isSuccess
                                 {
                                     /// Success
                                 }
                                 else
                                 {
                                     /// Failure
                                 }
                             }
                             upload.uploadProgress(closure: {
                                 progress in
                                 print(progress.fractionCompleted)
                             })
                         case .failure(let encodingError):
                             print(encodingError)
                         }
                     })
}

Function Usage

if you have parameters send Parameters else nil or [:]

self.imageDataToServer(parameters: parameters)



回答3:


I've created a func to satisfy thy needs in this case. Pass the UIImage in 'image' param in the below request.

multipartUploadRequestWith(imageData: UIImageJPEGRepresentation(image, 1.0), parameters: params, onCompletion: {
        print("Upload Successful")
    }) { (error) in
        print(error.debugDescription)
}

Below is the code for the function.

func multipartUploadRequestWith(imageData: Data?, parameters: [String : Any], onCompletion: (() -> Void)? = nil, onError: ((Error?) -> Void)? = nil){

    let url =  /* your API url */

    let headers: HTTPHeaders = [
        /* "Authorization": "your_access_token",  in case you need authorization header */
        "Content-type": "multipart/form-data",
    ]
    print(headers)
    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: "photo", fileName: "photo.jpeg", mimeType: "image/jpeg")
        }

    }, usingThreshold: UInt64.init(), to: url, method: .post, headers: headers) { (result) in
        switch result{
        case .success(let upload, _, _):
            upload.response { response in
                if let err = response.error{
                    print("This error")
                    let alert = UIAlertController(title: "Upload Failed", message: "The image upload failed. Check your internet connection", preferredStyle: .alert)
                    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
                    UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true, completion: nil)
                    onError?(err)
                    return
                }
                if response.response?.statusCode == 200 {
                    print("Succesfully uploaded")
                    onCompletion?()
                } else {
                    print("Error " )
                }
            }
        case .failure(let error):
            print("Error in upload: \(error.localizedDescription)")
            onError?(error)
        }
    }
}



回答4:


Try This

func callAPI( _ parameters:[String:Any] , url:String) {


        print(parameters)

        let uploadImageProfileURL = url

        var urlRequest = URLRequest(url: URL(string:uploadImageProfileURL)!)
        urlRequest.httpMethod = "POST"

        urlRequest.allHTTPHeaderFields = [
            "content-type": "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
            "cache-control": "no-cache",
        ]

        Alamofire.upload(multipartFormData: { multipartFormData in

            for (key, value) in parameters {
                if value is String {
                    multipartFormData.append((value as! String).data(using: String.Encoding.utf8)!, withName: key )
                }

                if value is UIImage {

                    let imgData = UIImageJPEGRepresentation(value as! UIImage, 1)!

                    multipartFormData.append(imgData, withName: key  ,fileName: "file.jpg", mimeType: "image/jpg")
                }

                if value is Array<UIImage> {

                    let arrayValue = value as! [UIImage]

                    for image in arrayValue {

                        let fileName = "file\(arc4random()%1000).jpg"
                        let mimeType = "application/octet-stream" ?? "image/jpg"
                        let data = UIImageJPEGRepresentation(image, 1)

                        multipartFormData.append(data!, withName: "\(key)", fileName:fileName, mimeType: mimeType)
                    }

                }

            }},to:url,method: .post)
        { (result) in

            switch result {

            case .success(let upload, _, _):

                upload.responseJSON { response in

                    if let JSON = response.result.value {

                    }
                }




            case .failure(let encodingError):
               print(encodingError.localizedDescription)
            }

        }
    }



回答5:


Use Below code for single Image Upload using Alamofire : Swift 3.0

var strImagePicked = [UIImage]() // declared as global variable ... this will be image picked from ImagePickerController

Below is the function used for uploading single image from ImagePickerController and call this method when you click button to upload Image

func imageuploadAPI(){

    let params =
    [
        "code"               :  code,
        "store_id"           :  storeID,
        "type"               :  "merchant",
        "description"        :  description,
        "terms"              :  terms,
        "start_date"         :  startDate,
        "end_date"           :  endDate,
        "coupon_discount"    :  couponDiscount,
        "minimum_total"      :  minimumDiscount,
        "percentage"         :  percentage,
        "maximum_discount"   :  maximumDiscount
        ] as [String : Any]

    Alamofire.upload(
        multipartFormData: { MultipartFormData in

            for (key, value) in params {
                MultipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
            }

            for element in 0..<self.strImagePicked.count {

                let singleImage : Data? = self.strImagePicked[element].lowestQualityJPEGNSData as Data?

                MultipartFormData.append(singleImage!, withName: "image", fileName: "swift_file.jpg", mimeType: "image/jpeg")

                //"image" is the parameter for image 
            }
    }, to: "your_URL") { (result) in

        switch result {
        case .success(let upload, _, _):

            upload.responseJSON { response in
                print(response.result.value as Any)

            }
        case .failure(let encodingError):
             print(encodingError)
            break
        }
    }
}

// extension is used for image so that if image will be of hight quality it will reduce it's size
extension UIImage {

var highestQualityJPEGNSData: NSData { return UIImageJPEGRepresentation(self, 1.0)! as NSData }
var highQualityJPEGNSData: NSData    { return UIImageJPEGRepresentation(self, 0.75)! as NSData}
var mediumQualityJPEGNSData: NSData  { return UIImageJPEGRepresentation(self, 0.5)! as NSData }
var lowQualityJPEGNSData: NSData     { return UIImageJPEGRepresentation(self, 0.25)! as NSData}
var lowestQualityJPEGNSData: NSData  { return UIImageJPEGRepresentation(self, 0.0)! as NSData }

}



回答6:


Alamofire4 and Swift 4.1

1st Step: Take a imageView and pick the image by using imagepickerview After that take a button in which below function will be call

**

func uploadAvatar() {
            let id : String = UserDefaults.standard.value(forKey: "id") as! String
            let token : String = UserDefaults.standard.value(forKey: "token") as! String
            let url = "http://203.163.248.214:1357/api/user/update_image"
            let headers = ["x-access-token": token]
            showLoader(OnView: view)

        let imageData = self.imgView.image!.jpegData(compressionQuality: 0.7)

        let parameters: [String : AnyObject] = ["user_id": id as AnyObject]

            Alamofire.upload(multipartFormData:{ multipartFormData in
                multipartFormData.append(imageData!, withName: "file", fileName: "file.jpeg", mimeType: "image/jpeg")
                    for (key, value) in parameters
                    {
                        multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
                    }
            }, to: url, headers: headers)
            { (result) in
                switch result {
                case .success(let upload,_,_ ):
                    upload.uploadProgress(closure: { (progress) in
                        //Print progress
                    })
                    upload.responseJSON
                        { response in
                            let json = response.result.value as! [String:AnyObject]
                            print(json)
                            if response.result.value != nil
                            {
                                if json["status"] as! NSInteger == 200 {

                                    DispatchQueue.main.async(execute: {() -> Void in

                                        self.dismissLoader()
                                        self.userImage = json["data"] as! [String:AnyObject]

                                    })

                                }else{
                                    self.dismissLoader()
                                }
                            }
                    }
                case .failure( _):
                    self.dismissLoader()
                    break
                }
            }
        }*

*

userImage will be ur array or may be dictionary depends upon the response and declare it globally as var userImage = String: AnyObject



来源:https://stackoverflow.com/questions/50041287/how-to-upload-multipart-image-to-server-using-alamofire

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!