如何将参数为 api 的带有表单数据的图像上传到 api?

how to upload image with form data which image is on parameter to api?

我需要上传带有表单数据的图片,但我的图片总是无法发送到 api

我的参数像

nickname": "carex",
password: "mantap",
name : "Kopral Kapten",
nickname : "cobra",
email : "ularkobra@gmail.com",
birth_date : "1980-09-29",
gender : "m",
phone : "081908908890",
password : "Vb+2fzEf/kXZuHUPenfT+Q==",
city : "Malang",
picture: upload file

我的代码:

if let data = imageData {

            let imageURL = imageUrl
            let fileName = imageURL.absoluteString

            let userId = UserDefaults.standard.object(forKey: "id") as! String
            let token =  UserDefaults.standard.object(forKey: "token") as! String

            let Params : Parameters = [
                "picture" : fileName
            ]

            //filename is image

            let headersku: HTTPHeaders = [
                "Content-Type":"application/x-www-form-urlencoded",
                "Authorization": "Bearer \(token)"
            ]

            let base_Url = "https://dev.lenna.ai/lenna/public/api/dBmK5m/users/\(userId)"

            // Start Alamofire

            Alamofire.upload(multipartFormData:{ multipartFormData in
                multipartFormData.append(data, withName: "image", fileName: fileName, mimeType: "image/jpeg")
                for (key, value) in Params {
                        multipartFormData.append((value as! String).data(using: String.Encoding.utf8)!, withName: key )
                }

                },
                             usingThreshold:UInt64.init(),
                             to: base_Url,
                             method:.post,
                             headers: headersku,
                             encodingCompletion: { encodingResult in
                                switch encodingResult {
                                case .success(let upload, _, _):
                                    upload.responseJSON { response in
                                        print(response)

                                        self.userImg.image = image
                                    }
                                case .failure(let encodingError):
                                    print(encodingError)
                                }
            })

        }

试试这个,您需要将图像作为多部分发送,或者您需要将图像作为数据格式附加到参数字典中

let image: UIImage? = self.uploadImg.image

let uploadDict = ["key":val] as [String:String]

Alamofire.upload(multipartFormData: { MultipartFormData in

        let image :Data = (image?.jpegData(compressionQuality: 1))!

        MultipartFormData.append(image, withName: "image" , fileName: "image.jpeg" , mimeType: "image/jpeg")
        for(key,value) in uploadDict{

            MultipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)}

    }, to: "http://XXXXXXXXXXXXXXXX/uploadImage", encodingCompletion: {
        EncodingResult in
        switch EncodingResult{
        case .success(let upload, _, _):
            upload.responseJSON { response in
                debugPrint("SUCCESS RESPONSE: \(response)")
            }
        case .failure(let encodingError):

            print("ERROR RESPONSE: \(encodingError)")

        }            
    })

你能试试这个吗,它会对你有帮助。

创建图像字典:-


  let dictimage = NSMutableDictionary()
  dictimage.setValue("pass here Image data", forKey: "pass your image parameter name")

你的其他字段参数如

  let dictparam = NSMutableDictionary()
  dictparam.setValue("carex", forKey:"nickname")
  dictparam.setValue("mantap", forKey:"password")

调用这个函数

class func callAPIWithMultiPart(_ url: String,
                                   image:NSDictionary,
                                    param: NSDictionary,
                                    type : HTTPMethod,
                                    controller: UIViewController,
                                    header : [String: String]?,
                                    callSilently : Bool = false,
                                    successBlock: @escaping (_ responseDict: NSDictionary? , _ response: NSArray?) -> Void,
                                    failureBlock: @escaping (_ error: Error? , _ isTimeOut: Bool) -> Void) {


        if isNetworkAvailable() {

            if !callSilently {
                MBProgressHUD.showAdded(to: (UIApplication.shared.delegate?.window!)! , animated: true)
            }

            let urlWithUTF8 =  url.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)

            print("**************************************************")
            print("URL : \(urlWithUTF8!)")
            print("Header : \(String(describing: header))")
            print("Parameter For video : \(video.count)")
            print("Parameter  : \(param)")


            Alamofire.upload(multipartFormData: { (multipartFormData) in

                let arrParametersKey = NSMutableArray(array: param.allKeys)
                let arrParametersValues = NSMutableArray(array: param.allValues)

                //For normal Parameters
                for index in 0 ..< arrParametersKey.count {

                    if let strKey = arrParametersKey.object(at: index) as? String , let strValue = arrParametersValues.object(at: index) as? String {

                        print("********************* MultiPart ******************")
                        print("strKey : \(strKey)")
                        print("strValue : \(strValue)")
                        multipartFormData.append(strValue.data(using: .utf8)!, withName: strKey)
                    }
                }

                //For File
                if let strFileKeyForWebservices = video.value(forKey: "FileKeyForWebservices") as? String, let strFileName = video.value(forKey: "FileName") as? String, let dataForWebservices = video.value(forKey: "FileData") as? Data, let strFileMineType = video.value(forKey: "FileMineType") as? String {

                    print("********************* MultiPart File ******************")
                    print("FileKeyForWebservices : \(strFileKeyForWebservices)")
                    print("strFileName : \(strFileName)")
                    print("dataForWebservices : \(dataForWebservices.count)")
                    print("strFileMineType : \(strFileMineType)")

                    multipartFormData.append(dataForWebservices, withName: strFileKeyForWebservices, fileName: strFileName, mimeType: strFileMineType)
                }


            }, usingThreshold: UInt64.init(), to: urlWithUTF8!, method: type, headers: header) { (encodingResult) in

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

                    if !callSilently {
                        DispatchQueue.main.async {
                            MBProgressHUD.hide(for: ((UIApplication.shared.delegate?.window)!)!, animated: true)
                        }
                    }

                    upload.responseJSON { response in

                        print("Response : \(String(describing: response.response?.statusCode))");

                        if let aDict = response.result.value as? NSDictionary {
                            successBlock(aDict,nil)
                        } else if let aArray = response.result.value as? NSArray {
                            successBlock(nil,aArray)
                        } else {
                            failureBlock(nil, true)
                        }

                    }
                    break
                case .failure(let encodingError):

                    if !callSilently {
                        DispatchQueue.main.async {
                            MBProgressHUD.hide(for: ((UIApplication.shared.delegate?.window)!)!, animated: true)
                        }
                    }

                    UIAlertController.showAlertWithOkButton(controller, aStrMessage: Localization("alert_SomethingWentWrong") , completion: nil)
                    failureBlock(encodingError, false)
                    break
                }

            }

        } else {
            // Internet is not connected
            UIAlertController.showAlertWithOkButton(controller, aStrMessage: "Internet is not available", completion: nil)
            let aErrorConnection = NSError(domain: "InternetNotAvailable", code: 0456, userInfo: nil)
            failureBlock(aErrorConnection as Error , false)
        }

    }

如何使用


  self.callAPIWithMultiPart("here apiURL", image: dictimage, param: dictparam, type: .post, controller: controller, header: requestHeader, successBlock: successBlock, failureBlock: failureBlock)

试试这个,你可以在正文中添加其他参数

    func uploadImage(image: UIImage)
{

    let url = URL(string: "URL_TO_PHP_SERVER");
    let request = NSMutableURLRequest(url: url!)
    request.httpMethod = "POST"

    let boundary = generateBoundaryString()

    //define the multipart request type

    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

    let image_data = UIImageJPEGRepresentation(image, 1)


    if(image_data == nil)
    {
        print("problem occurred")
        return;
    }


    let body = NSMutableData();

    let date = Date();
    let fname = "\(Int64(date.timeIntervalSince1970*1000)).jpg"
    print("file name: \(fname)");
    let mimetype = "image/jpeg"

    //define the data post parameter

    body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
    body.append("Content-Disposition:form-data; name=\"test\"\r\n\r\n".data(using: String.Encoding.utf8)!)
    body.append("hi\r\n".data(using: String.Encoding.utf8)!)

    body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
    body.append("Content-Disposition:form-data; name=\"file\"; filename=\"\(fname)\"\r\n".data(using: String.Encoding.utf8)!)
    body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
    body.append(image_data!)
    body.append("\r\n".data(using: String.Encoding.utf8)!)


    body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)



    request.httpBody = body as Data


    //        let session = NSURLSession.sharedSession()
    var configuration = URLSessionConfiguration.default;
    var session = URLSession(configuration: configuration, delegate: self, delegateQueue: OperationQueue.main);


    let task = session.dataTask(with: request as URLRequest) {
        (
        data, response, error) in

        guard let _:Data = data, let _:URLResponse = response, error == nil else {
            print("error")
            DispatchQueue.main.async {
                print("Problem occurred in uploading");
                // DO your stuff in UI Thread
            }
            return
        }

        DispatchQueue.main.async {
            print("uploading success");
            // DO your stuff in UI Thread
        }

        let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
        print(dataString)

    }

    task.resume()


}

您需要在参数字典中将图像作为多部分发送

    import Alamofire

    func tempImageShareToApi(){

        let apiURL = "http://testApp/public/api/user/profile"
        let params : [String: String] = [
            "id"             : "\(UserId)"
        ]

        print(params)
        Alamofire.upload(multipartFormData: { (multipartFormData) in

            if let normalImg = self.userImageView {
                if  let imgValue = (self.pickedImage?.jpegData(compressionQuality: 0.75)) {
                    let r = arc4random()
                    let str = "file"+String(r)+".jpg"
                    let parameterName = "image"
                    multipartFormData.append(imgValue, withName:parameterName, fileName:str, mimeType: "image/jpeg")
                }
            }else{}
            for (key, value) in params {
                multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key )
            }

        }, to: apiURL,encodingCompletion: { encodingResult in
            switch encodingResult {
            case .success(let upload, _, _):
                upload.responseJSON { response in

                    if let Json = response.result.value as? Dictionary<String,AnyObject> {
                        print(Json)
                        if let responcCode = Json["data"] as?  Dictionary<String,AnyObject>{
                            print(responcCode)
                        }
                    }
                }
            case .failure(let encodingError):
                print(encodingError)
            }})
        }