Как загрузить изображение с параметрами, используя Alamofire в Swift
Я разрабатываю приложение для iPhone с Swift. и я использую фреймворк Alamofire для обработки http-запросов. Я использую Alamofire.request
для POST, GET и т.д. Alamofire.request
так:
Alamofire.request(.POST, myURL , parameters: ["a": "1", "b" : "2" ])
.response { (request, response, data, error) in
}
И я использую Alamofire.upload
для загрузки изображения на сервер это:
Alamofire.upload(.POST, uploadURL , fileURL)
И то и другое работает отлично, но теперь я хочу загрузить изображение, а также отправить некоторые параметры, и мой тип контента должен быть multipart/form-data
а Alamofire.upload
не принимает параметры.
На SO есть еще два вопроса об этой проблеме со swift, первый из которых не использует Alamofire (и действительно, почему бы и нет?), А второй - mattt (Alamofire Developer), в котором упоминаются параметры кодирования.
Я проверил его пример, но все еще не мог понять, как это сделать.
Может ли кто-нибудь помочь мне решить эту проблему?
Спасибо! :)
Ответы
Ответ 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)
}
})
}
Ответ 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 с быстрым 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["User[first_name]"] = firstName
parameters["User[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 с быстрым 2.0 просто скопируйте и вставьте ниже code.here m asumming Ответ 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)