Загрузить изображение на сервер с помощью Alamofire

Это мой код, который я хочу загрузить изображение на сервер, используя Alamofire, это не ошибка, но он не может отправить изображение на сервер. что я должен делать? Заранее спасибо.

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

let parameters = ["name": rname]

do {
    urlRequest.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: [])
} catch {
    print(error)
}

urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
    let image = UIImage.init(named: "myImage")
    let imgData = UIImageJPEGRepresentation(image!, 0.2)!


Alamofire.upload(multipartFormData: { MultipartFormData in

        MultipartFormData.append(imgData, withName: "fileset", fileName: "name", mimeType: "image/jpg")


    },with: urlRequest,encodingCompletion: { encodingResult in

        switch encodingResult {

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

            upload.responseJSON { response in

                if let info = response.result.value as? Dictionary<String, AnyObject> {

                    if let links = info["links"] as? Dictionary<String, AnyObject> {

                        if let imgLink = links["image_link"] as? String {
                            print("LINK: \(imgLink)")
                        }
                    }
                }

            } case .failure(let error):
                print(error)
        }
    })

12 ответов

Решение

Попробуйте код ниже

 let image = UIImage.init(named: "myImage")
 let imgData = UIImageJPEGRepresentation(image!, 0.2)!

 let parameters = ["name": rname] //Optional for extra parameter

Alamofire.upload(multipartFormData: { multipartFormData in
        multipartFormData.append(imgData, withName: "fileset",fileName: "file.jpg", mimeType: "image/jpg")
        for (key, value) in parameters {
                multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
            } //Optional for extra parameters
    },
to:"mysite/upload.php")
{ (result) in
    switch result {
    case .success(let upload, _, _):

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

        upload.responseJSON { response in
             print(response.result.value)  
        }

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

Обновлен код до Swift 5.

В Swift 5 есть изменение в этой строке

let imageData = UIImageJPEGRepresentation(image!, 0.2)!

Нравится это

let imageData = image.jpegData(compressionQuality: 0.50)

Весь код для загрузки изображения

let param: [String:Any] = ["your_parameters"]
var image = UIImage()
image = UIImage(named: "edit.png")!
let imageData = image.jpegData(compressionQuality: 0.50)
print(image, imageData!)

Alamofire.upload(multipartFormData: { (multipartFormData) in
        multipartFormData.append(imageData!, withName: "file", fileName: "swift_file.png", mimeType: "image/png")
        for (key, value) in param {
            multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key)
        }
    }, to: "your_url")
    { (result) in
        switch result {
        case .success(let upload, _, _):

            upload.uploadProgress(closure: { (progress) in
                //Print progress
                print("uploading \(progress)")

            })

            upload.responseJSON { response in
                //print response.result

            }
        case .failure( _): break
            //print encodingError.description
        }
    }
}
let params: Parameters = ["name": "abcd" "gender": "Male"]
Alamofire.upload(multipartFormData:
    {
        (multipartFormData) in
        multipartFormData.append(UIImageJPEGRepresentation(self.yourimageView.image!, 0.1)!, withName: "image", fileName: "file.jpeg", mimeType: "image/jpeg")
        for (key, value) in params
        {
            multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
        }
}, to:yourUrl,headers:nil)
{ (result) in
    switch result {
    case .success(let upload,_,_ ):
        upload.uploadProgress(closure: { (progress) in
            //Print progress
        })
        upload.responseJSON
            { response in
                //print response.result
                if response.result.value != nil
                {
                    let dict :NSDictionary = response.result.value! as! NSDictionary
                    let status = dict.value(forKey: "status")as! String
                    if status=="1"
                    {  
                      print("DATA UPLOAD SUCCESSFULLY")
                    }
                }
        }                
    case .failure(let encodingError):
        break
    }   
}

Единственный, кто работает на меня на эту дату:

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://35.227.31.145/new.php", method: .post , headers: headers)
                .response { resp in
                    print(resp)


            }

Нужно указать name, fileName, mimeTypeэто важно для многих серверов

func upload(image: UIImage, completion: (URL?) -> Void) {
    guard let data = UIImageJPEGRepresentation(image, 0.9) else {
      return
    }

    Alamofire.upload(multipartFormData: { (form) in
      form.append(data, withName: "file", fileName: "file.jpg", mimeType: "image/jpg")
    }, to: "https://yourawesomebackend.com", encodingCompletion: { result in
      switch result {
      case .success(let upload, _, _):
        upload.responseString { response in
          print(response.value)
        }
      case .failure(let encodingError):
        print(encodingError)
      }
    })
  }

Хорошо, братан, я использую этот код со Swift 4 и Alamofire

import Foundation
import Alamofire

class UploadImageController: NSObject {

// MARK: - shared

static let shared  = UploadImageController()

// MARK: - init

let decoder = JSONDecoder()

// MARK: - uploadImageOnly

func uploadImageWith(endUrl: String, photo: UIImage?, parameters: [String : Any]?, headers: HTTPHeaders?, completion: @escaping (_ success: Bool, _ uploadImageResponse: UploadImageResponse?) -> Void ) {

    Alamofire.upload(multipartFormData: { (multipartFormData) in

        if let data = UIImageJPEGRepresentation(photo!, 0.5) {

            multipartFormData.append(data, withName: "invoice", fileName: "invoice.jpeg", mimeType: "invoice/jpeg")
        }

    }, usingThreshold: SessionManager.multipartFormDataEncodingMemoryThreshold, to: endUrl, method: .post, headers: headers) { (result) in

        switch result {

        case .failure(let error):
            print("UploadImageController.requestWith.Alamofire.usingThreshold:", error)
            completion(false, nil)

        case .success(request: let upload, streamingFromDisk: _, streamFileURL: _):

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

            upload.responseJSON(completionHandler: { (response) in

                switch response.result {

                case .failure(let error):

                    print("UploadImageController.requestWith.Alamofire.upload.responseJSON:", error)

                    completion(false, nil)

                case .success( _):

                    print("UploadImageController.requestWith.Alamofire.upload.responseJSON Succes")
                    guard let data = response.data else { return }

                    do {

                        let uploadImageResponse = try self.decoder.decode(UploadImageResponse.self, from: data)

                        completion(true, uploadImageResponse)

                    } catch let jsonError {

                        print("Error serializing json.ProfileController.getProfile:", jsonError)
                        completion(false, nil)
                    }
                }
            })
        }
    }
}

// MARK: - uploadImageWithParameters

func uploadImageWithParametersAnd(endUrl: String, photo: UIImage?, parameters: [String : Any]?, headers: HTTPHeaders?, completion: @escaping (_ success: Bool, _ addInvoiceResponse: AddInvoiceResponse?) -> Void ) {

    Alamofire.upload(multipartFormData: { (multipartFormData) in

        if let data = UIImageJPEGRepresentation(photo!, 0.5) {

            multipartFormData.append(data, withName: "invoicePicture", fileName: "invoicePicture.jpeg", mimeType: "invoice/jpeg")
        }

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


    }, usingThreshold: SessionManager.multipartFormDataEncodingMemoryThreshold, to: endUrl, method: .post, headers: headers) { (result) in

        switch result {

        case .failure(let error):
            print("UploadImageController.requestWith.Alamofire.usingThreshold:", error)
            completion(false, nil)

        case .success(request: let upload, streamingFromDisk: _, streamFileURL: _):

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

            upload.responseJSON(completionHandler: { (response) in

                switch response.result {

                case .failure(let error):

                    print("UploadImageController.requestWith.Alamofire.upload.responseJSON:", error)

                    completion(false, nil)

                case .success( _):

                    print("UploadImageController.requestWith.Alamofire.upload.responseJSON Succes")
                    guard let data = response.data else { return }

                    do {

                        let addInvoiceResponse = try self.decoder.decode(AddInvoiceResponse.self, from: data)

                        completion(true, addInvoiceResponse)

                    } catch let jsonError {

                        print("Error serializing json.ProfileController.getProfile:", jsonError)
                        completion(false, nil)
                    }
                }
            })
        }
    }
 }
}

Например, этот AddInvoiceResponse

import Foundation

struct AddInvoiceResponse: Decodable {
    let id, message: String?
}

а вот UploadImageResponse

import Foundation

struct UploadImageResponse: Codable {
    let id, message: String?
}

Попробуйте приведенный ниже код для загрузки нескольких изображений. спросил @Saurabh.

Однако лучше сделать загрузку 1 на 1, а не загружать все сразу.
потому что, если он потерпел неудачу, он потерпит неудачу только на 1 изображение но загрузить все сразу. Если 1 файл не удался, пользователь должен перезапустить процесс загрузки с самого начала.

тем не менее, вот что вам нужно сделать, если вы хотите загрузить несколько данных одновременно.

 let image1 = UIImage.init(named: "myImage1")
 let image2 = UIImage.init(named: "myImage2")
 let image3 = UIImage.init(named: "myImage3")
 let image4 = UIImage.init(named: "myImage4")
 let imgData1 = UIImageJPEGRepresentation(image!, 0.2)!
 let imgData2 = UIImageJPEGRepresentation(image!, 0.2)!
 let imgData3 = UIImageJPEGRepresentation(image!, 0.2)!
 let imgData4 = UIImageJPEGRepresentation(image!, 0.2)!


 let parameters = ["name": rname] //Optional for extra parameter

Alamofire.upload(multipartFormData: { multipartFormData in
        //loop this "multipartFormData" and make the key as array data
        multipartFormData.append(imgData1, withName: "fileset[0]",fileName: "file.jpg", mimeType: "image/jpg")
        multipartFormData.append(imgData2, withName: "fileset[1]",fileName: "file.jpg", mimeType: "image/jpg")
        multipartFormData.append(imgData3, withName: "fileset[2]",fileName: "file.jpg", mimeType: "image/jpg")
        multipartFormData.append(imgData4, withName: "fileset[3]",fileName: "file.jpg", mimeType: "image/jpg")
        for (key, value) in parameters {
                multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
            } //Optional for extra parameters
    },
to:"mysite/upload.php")
{ (result) in
    switch result {
    case .success(let upload, _, _):

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

        upload.responseJSON { response in
             print(response.result.value)  
        }

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

Отметил: multipartFormData использует append, что означает, что это массив запросов. Вы можете зациклить и добавить больше, если это необходимо.

    let url = BaseViewController.API_URL + "uploads"
    let image = info[UIImagePickerControllerEditedImage] as? UIImage
    let imgData = UIImageJPEGRepresentation(image!, 0.2)!

    let parameters = [
                            "user_id" : UserDefaults.standard.value(forKey: "userId")!
    ]

    Alamofire.upload(multipartFormData: { multipartFormData in
        multipartFormData.append(imgData, withName: "uload_data",fileName: "file.jpg", mimeType: "image/jpg")
        for (key, value) in parameters {
            multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
        } //Optional for extra parameters
    },
                     to:url)
    { (result) in
        switch result {
        case .success(let upload, _, _):

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

            upload.responseJSON { response in

                self.objHudHide()
                print(response.result.value)

                let jsonDict : NSDictionary = response.result.value as! NSDictionary

                print(jsonDict)
                if  jsonDict["status"] as! String == "Success"
                {


                    let detailDict : Dictionary = jsonDict["detail"] as! Dictionary<String,Any>

                    if let getTotalPrice = detailDict["total_price"]
                    {
                        self.lblTotalPrice.text = "$ \(getTotalPrice) + Free Shipping"
                    }

                    if  let getTotalSize = detailDict["total_upload_size"]
                    {
                        self.lblTotalSize.text = "Total Size : \(getTotalSize)"

                    }
                }
               else
                {

                let alertViewController = UIAlertController(title: NSLocalizedString("Alert!", comment: ""), message:"Something Went wrong please try again." , preferredStyle: .alert)
                let okAction = UIAlertAction(title: NSLocalizedString("Ok", comment: ""), style: .default) { (action) -> Void in

                }
                alertViewController.addAction(okAction)
                self.present(alertViewController, animated: true, completion: nil)


        }
            }

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

У меня возникли проблемы с загрузкой файла изображения с помощью Alamofire 5. Мое решение выглядит так:

    let parameters: [String: String] = ["user_id": "1"]

    AF.upload(multipartFormData: { multipartFormData in

            for (key, value) in parameters {
                multipartFormData.append(value.data(using: .utf8)!, withName: key)
            }

            if let jpegData = UIImageJPEGRepresentation(image, 1.0) {
                multipartFormData.append(jpegData, withName: "image", fileName: "image", mimeType: "image/jpeg")
            }
    }, to: "http://example.com/upload-image")
        .authenticate(username: "username", password: "password") // had basic auth
        .response { response in
            if response.response?.statusCode == 200 {
                print("OK. Done")
            } 
    }

после быстрой очистки версий, приведенных выше, это будет фрагмент, который я всегда повторно использую, где Endpoints.uploadProfileImage() это просто URL.

      func uploadPhoto(media: UIImage, params: [String:String], fileName: String){
    let headers: HTTPHeaders = [
        "Content-type": "multipart/form-data"
    ]
    AF.upload(
        multipartFormData: { multipartFormData in
            multipartFormData.append(media.jpegData(
                compressionQuality: 0.5)!,
                withName: "upload_data",
                fileName: "\(fileName).jpeg", mimeType: "image/jpeg"
            )
            for param in params {
                let value = param.value.data(using: String.Encoding.utf8)!
                multipartFormData.append(value, withName: param.key)
            }
        },
        to: Endpoints.uploadProfileImage(),
        method: .post ,
        headers: headers
    )
    .response { response in
        print(response)
    }
}

Учитывая Alamofire 5.0+:

Загрузка данных

let data = Data("data".utf8)

AF.upload(data, to: "https://httpbin.org/post").responseJSON { response in
    debugPrint(response)
}

Загрузка файла

let fileURL = Bundle.main.url(forResource: "video", withExtension: "mov")

AF.upload(fileURL, to: "https://httpbin.org/post").responseJSON { response in
    debugPrint(response)
}

Загрузка данных многостраничной формы

AF.upload(multipartFormData: { multipartFormData in
    multipartFormData.append(Data("one".utf8), withName: "one")
    multipartFormData.append(Data("two".utf8), withName: "two")
}, to: "https://httpbin.org/post")
    .responseJSON { response in
        debugPrint(response)
    }

Изображение через составную форму:

// in case of parameters dictionary let's just roll the keys and values later
let parameters = ["name": rname] //var parameters: [String: Any] = [:]

AF.upload(multipartFormData: { multipartFormData in

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

        guard let image = photo else { return }
        let jpegData = image.jpegData(compressionQuality: 1.0)
        multipartFormData.append(Data((jpegData)!), withName: "photo")

}, to: "https://httpbin.org/post")

    .responseJSON { response in
        debugPrint(response)
}
 user_photo is key for dic 
 swift_file.jpg is value for value  
 Write the same  withName is  key
 Write the same fileName is value 
 call the UploadImage(Image)


func UploadImage(img:UIImage) {
        let urlfinal = “ananda.profile.php";
        let parameters = ["user_id":"531", "user_photo”: "swift_file.jpg"] 
        Alamofire.upload(multipartFormData: { (multipartFormData) in
            multipartFormData.append(UIImageJPEGRepresentation(img, 1)!, withName: "user_photo", fileName: "swift_file.jpeg", mimeType: "image/jpg")
            for (key, value) in parameters {
                multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
            }
            print(multipartFormData)
        }, to:urlfinal)
        { (result) in
            switch result {
            case .success(let upload, , ):
                upload.uploadProgress(closure: { (progress) in
                })

                upload.responseJSON { response in
                    print(response)
                }
            case .failure( _): break

            }
        }
   }
Другие вопросы по тегам