Upload image from gallery with parameters and header using Alamofire - ios

I am trying to upload image but need to pass parameters and header as well, got help from google about parameters but not getting how to pass header also. Passing on the code below please guide.
Below is my code:
if (request.requestType == "Multipart")
{
var strToken : String = ""
if let access_token = UserDefaults.standard.string(forKey: "auth_token"){
let tokenValue = String(format: "Token %#", access_token);
strToken = tokenValue
}
let headers: HTTPHeaders = [
"Authorization": strToken,
"Content-Type": "multipart/form-data"
]
let img = request.image
let imgData = UIImageJPEGRepresentation(img, 0.2)!
do{
let strURL = try strCompleteURL.asURL()
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imgData, withName: "image_path",fileName: "file.jpg", mimeType: "image/jpg")
for (key, value) in params {
multipartFormData.append(value.data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
},
to:strURL)
{ (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
if response.result.isSuccess {
print(response.result.value as Any)
if let data = response.data{
self.response.responseCode = response.response?.statusCode
self.processResult(data);
}
}
}
case .failure(let encodingError):
print(encodingError)
}
}
}
catch{
}
above code tries to upload image but not succeed because of missing header, please guide how to pass header and parameters as well.
Thanks

Hi I have used headers like this
func uploadImage( image:UIImage, url:String, _ successBlock:#escaping ( _ response: JSON )->Void , errorBlock: #escaping (_ error: NSError) -> Void ){
let path = baseUrl + url
print(path)
let headers = ["authorization": AppData().token]
let imgData = UIImageJPEGRepresentation(image, 0.2)!
let URL = try! URLRequest(url: path, method: .post, headers: headers)
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imgData, withName: "image",fileName: "file.jpg", mimeType: "file")
for (key, value) in params {
multipartFormData.append(value.data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}, with: URL) { (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)
if let value = response.result.value {
let json = JSON(value)
successBlock(json)
}
}
case .failure(let encodingError):
print(encodingError)
errorBlock(encodingError as NSError)
}
}
}

The Alamofire .upload() function has more parameters available than what you used. (This can be seen in the Alamofire.swift file in their pod folder)
public func upload(
multipartFormData: #escaping (MultipartFormData) -> Void,
usingThreshold encodingMemoryThreshold: UInt64 = SessionManager.multipartFormDataEncodingMemoryThreshold,
to url: URLConvertible,
method: HTTPMethod = .post,
headers: HTTPHeaders? = nil,
encodingCompletion: ((SessionManager.MultipartFormDataEncodingResult) -> Void)?)
{
return ...
}
In there you can see there is a parameter for headers that you have not made use of.
Without running the code myself and checking everything, this would be my best assumption of where your headers would go

Related

Pattern cannot match values of type 'URLRequest'

I am trying to upload an image in Alamofire parameters. But I keep getting this error that wont let me compile. I am using swift 5.
Error
let image = profilePictureView.image!
let imageData = image.jpegData(compressionQuality: 0.50)
print(image, imageData!)
AF.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imageData!, withName: "file", fileName: "swift_file.png", mimeType: "image/png")
for (key, value) in estimatedParams {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key)
}
}, to: ServiceConstants.baseUrl+ServiceConstants.MD_UPDATE_PROFILE+"/\(userId)")
{ (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
}
}
You can use this function:
//MARK: - Upload Image
private func uploadUserImage(image: UIImage) {
if let imageData = image.jpegData(compressionQuality: 1.0) {
let headers: HTTPHeaders = [
"Content-type": "multipart/form-data",
]
AF.upload(
multipartFormData: { multipartFormData in
multipartFormData.append(imageData, withName: "image" , fileName: "profile-image.png", mimeType: "image/png")
},
to: WebService.profileImageUploadURL, method: .post, headers: headers)
.downloadProgress { progress in
print(progress)
}
.response { response in
if response.response?.statusCode == 200 {
self.delegate?.uploadImageResponse(status: .success)
} else {
self.delegate?.uploadImageResponse(status: .failed)
}
}
}
}

How to convert UIImage to JPEG without loosing exif data?

I'm currently working on iOS applications and I'm using multipart image upload to uploading images to the server. Following is my image uploading method.
func uploadImageData(imageType:Int, uploadId:String, fileName:String, imageFile:UIImage, completion:#escaping (APIResponseStatus, ImageUploadResponse?) -> Void) {
let image = imageFile
let imgData = image.jpegData(compressionQuality: 0.2)!
let params = [APIRequestKeys.imageType:imageType, APIRequestKeys.uploadId:uploadId, APIRequestKeys.fileName:fileName] as [String : Any]
//withName is the post request key for the image file
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imgData, withName: APIRequestKeys.imageFile, fileName: "\(fileName).jpg", mimeType: "image/jpg")
for (key, value) in params {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key)
}
}, to: Constants.baseUrl + APIRequestMetod.uploadImageData, headers:self.getImageUploadHeaders())
{ (result) in
switch result {
case .success(let upload, _, _):
APIClient.currentRequest = upload
upload.uploadProgress(closure: { (progress) in
})
upload.responseObject {
(response:DataResponse<ImageUploadResponse>) in
switch response.result {
case .success(_):
completion(APIClient.APIResponseStatus(rawValue: (response.response?.statusCode)!)!, response.value!)
case .failure(let encodingError):
if let err = encodingError as? URLError, err.code == .notConnectedToInternet {
completion(APIClient.APIResponseStatus.NoNetwork, nil)
} else {
completion(APIClient.APIResponseStatus.Other, nil)
}
}
}
case .failure( _):
completion(APIClient.APIResponseStatus.Other, nil)
}
}
}
But for this implementation server is always sending exif data error. Following is the error that I'm getting.
exif_read_data(A029C715-99E4-44BE-8691-AA4009C1F5BD_FOTOPREGUNTA.ico): Illegal IFD size in
upload_image_xhr.php on line
The important thing is this service is working without errors in POSTMAN and android application as well. This error is only getting for my iOS implementation. My backend developer telling me that there is and exif data error in data that I'm sending and please verify the data from my side.
Anyone have an idea about this?
Thanks in advance.
I will make block function for Upload image to Server Using Multipart
//Here strUrl = YOUR WEBSERVICE URL
//postParam = post Request parameter i.e.
//let postParam : [String : Any] = [first_name : "name"]
//imageArray = image upload array i.e.
//var imageArray : [[String:Data]] = [["image_name" : YOUR IMAGE DATA]]
func postImageRequestWithURL(withUrl strURL: String,withParam postParam: Dictionary<String, Any>,withImages imageArray:[[String:Data]], completion:#escaping (_ isSuccess: Bool, _ response:NSDictionary) -> Void)
{
let requetURL = strURL
Alamofire.upload(multipartFormData: { (MultipartFormData) in
for (imageDic) in imageArray
{
for (key,valus) in imageDic
{
MultipartFormData.append(valus, withName:key,fileName: "file.jpg", mimeType: "image/jpg")
}
}
for (key, value) in postParam
{
MultipartFormData.append("\(value)".data(using: .utf8)!, withName: key)
// MultipartFormData.append(value, withName: key)
}
}, usingThreshold: UInt64.init(), to: requetURL, method: .post, headers: ["Accept": "application/json"]) { (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
let desiredString = NSString(data: response.data!, encoding: String.Encoding.utf8.rawValue)
print("Response ====================")
print(desiredString!)
if let json = response.result.value as? NSDictionary
{
if response.response?.statusCode == 200
|| response.response?.statusCode == 201
|| response.response?.statusCode == 202
{
completion(true,json);
}
else
{
completion(false,json);
}
}
else
{
completion(false,[:]);
}
}
case .failure(let encodingError):
print(encodingError)
completion(false,[:]);
}
}
}
I Hope this will help...

File upload issue in ios

I have a problem uploading a Document file through Document picker controller. I have selected File through Document picker. and send file using multipart data in service. but xcode give some error in ios swift.
Here is my code For Image upload.
Alamofire.upload(multipartFormData: { (multipartFormData) in
for (key, value) in params {
multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
multipartFormData.append(imageData!, withName: "upload_photo", fileName: "img.png", mimeType: "image/jpeg")
}, to:pageURL)
{ (result) in
switch result {
case .success(let upload, _, _):
self.stopLoader()
upload.uploadProgress(closure: { (Progress) in
print("Upload Progress: \(Progress.fractionCompleted)")
})
But i have to upload Document file from url.
Use my below class it is simple and manageable and working file :
import UIKit
import Alamofire
class TDWebServices: NSObject {
static let shared = TDWebServices()
func post(urlString : String , param : [String : Any], completionHandler : #escaping ( _ result : Any?) -> ()) {
Alamofire.request(urlString, method: .post, parameters: param, encoding: JSONEncoding.default, headers: ["Accept": "application/json"]).responseJSON { (response) in
switch response.result {
case .success:
let json = response.result.value as? NSDictionary
completionHandler(json)
case .failure(let error):
print(error)
completionHandler(nil)
return
}
}
}
func uploadImage(urlString : String , image : UIImage, param : [String : Any], completionHandler : #escaping ( _ result : Any?) -> ()) {
guard let imageData = UIImageJPEGRepresentation(image, 0.5) else {
print("Could not get JPEG representation of UIImage")
return
}
let header: HTTPHeaders = [
"Content-type": "multipart/form-data"
]
Alamofire.upload(multipartFormData: { multipartFormData in
for (key, value) in param {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
multipartFormData.append(imageData,
withName: "image", // <- It is param for uploading the file make sure it is perfect as per your API
fileName: "image.jpg",
mimeType: "image/jpeg")
},
to: urlString,
headers: header, // ["Authorization": "Basic xxx"]
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.uploadProgress { progress in
// progressCompletion(Float(progress.fractionCompleted))
}
upload.validate()
upload.responseJSON { response in
completionHandler(response.result.value)
}
case .failure(let encodingError):
print(encodingError)
completionHandler(nil)
}
})
}
}
How to use?
let param = ["user_id" : 123 as Any] // Whatever your params are
// showActivity() // <- show activity indicator
TDWebServices.shared.post(urlString: <your_api_url>, param: param) { (res) in
// hideActivity() // <- hide activity indicator
if res != nil{
let aDict = res as? [String : Any] // your response
// Hnadle your code here
}
else{
self.showAlert(title: "Invalid!", message: "Internet connection issue.", calcelHandler: {}) // <- If you have internet issue
}
}
Still facing issue then let me know..

Upload files using multipart request - Swift 4

I have to upload files on server using multipart request. For network calls i am using Alamofire.
What i have done so far is below
Request Service:
Multipart request:-
let headers: HTTPHeaders = [
"Content-type": "multipart/form-data"
]
let fileData = Filedata() // getting data from local path
let URL = try! URLRequest(url: "https://SomeUrl/upload", method: .post, headers: headers)
Alamofire.upload(multipartFormData: { (multipartFormData) in
//multipartFormData.append(fileData, withName: "image", fileName: "image", mimeType: "image/png")
multipartFormData.append(fileData, withName: "file")
}, with: URL, encodingCompletion: { (result) in
switch result {
case .success(let upload, _, _):
upload.responseJSON { response in
print(response)
}
case .failure(let encodingError):
print(encodingError)
}
})
Response:-
{ Status Code: 400, Headers {
Connection = (
close
);
"Content-Type" = (
"application/json;charset=UTF-8"
);
Date = (
"Tue, 15 May 2018 10:34:15 GMT"
);
"Transfer-Encoding" = (
Identity
);
} }
[Data]: 171 bytes
[Result]: SUCCESS: {
error = "Bad Request";
message = "Required request part 'file' is not present";
path = "/files/safebolt.org/upload";
status = 400;
timestamp = "2018-05-15T10:34:15.715+0000";
}
Can anyone please tell me what i am doing wrong with request ?
Try with:
multipartFormData.append(fileData, withName: "file", fileName: "file", mimeType: "image/png")
I have created one function. Hope it works for you.
//Alamofire file upload code
func requestWith(URLString: String,
imageData: Data?,
fileName: String?,
pathExtension: String?,
parameters: [String : Any],
onView: UIView?,
vc: UIViewController,
completion:#escaping (Any?) -> Void,
failure: #escaping (Error?) -> Void) {
let headers: HTTPHeaders = [
"Content-type": "multipart/form-data"
]
let URL = BASE_PATH + URLString
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: "fileUpload", fileName: "\(fileName!).\(pathExtension!)", mimeType: "\(fileName!)/\(pathExtension!)")
}
}, usingThreshold: UInt64.init(), to: URL, method: .post, headers: headers) { (result) in
switch result {
case .success(let upload, _, _):
upload.responseJSON { response in
if let err = response.error {
failure(err)
return
}
completion(response.result.value)
}
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
failure(error)
}
}
}
Try This, is an example it works for me. If you want to convert encode 64 for images add extension. If simply post the data and image this code may help.
//creating parameters for the post request
let parameters: Parameters=[
"ad_title":classText1.text!,
"ad_description":classText2.text!,
"ad_category":CategoryClass.text!,
"ad_condition":classText3.text!,
"ad_username":classText6.text!,
"ad_usermobile":classText7.text!,
"ad_city":classText8.text!,
"ad_price":classText4.text!,
"negotiable":classText5.text!,
"image1":adImage1.image!,
"image2":adImage2.image!,
"image3":adImage3.image!,
"image4":adImage4.image!
]
Alamofire.upload(multipartFormData: { (multipartFormData) in
for (key, value) in parameters {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
}, 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)")
}
}

Multipart-form (image,parameters,headers) Post request with Alamofire in swift

Firstly, i want to say i am new to swift, and know a little.So any help would be appriciated. I have a multipart-data form which has a image (profile-image), a few parameters (first-name, last-name) and headers(userid, hashCode). I want to send a POST request to submit the form.
I have been able to make POST request with only, headers and other parameters except image as:
let headers = [
"user_id": (Helper.getUserInfo()?.user_id)!,
"hash_code":(Helper.getUserInfo()?.hash_code)!,
]
let params = [
"name": self.name.text!,
"address":self.address.text!]
Alamofire.request(.POST, kFormUrl, parameters:params ,headers:headers).responseJSON { [weak self] response in
//working fine
}
But how to send image as a file (not base-64string) i.e. direct file upload with parameters and headers.
Thanks in advance
you can use Alamofire 3.0+ below code
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":aboutme,"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)
}
})
}
let userImageURL = NSURL(string: "your image url" as String)
let data = NSData.init(contentsOfURL: userImageURL!)
Alamofire.upload(
.POST,registerUrl!,
multipartFormData: { multipartFormData in
multipartFormData.appendBodyPart(data:"N".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"flag")
multipartFormData.appendBodyPart(data: data!, name: "image", fileName: "pic.jpg", mimeType: "image/png")
multipartFormData.appendBodyPart(data: facebookId.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"facebook_id")
multipartFormData.appendBodyPart(data: nameString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"first_name")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { response in
print(response)
let dict = response.result.value as! NSDictionary
}
case .Failure(let encodingError):
print(encodingError)
}
}
)
I use Alamofire (Swift 2.3) to send multipart with progress.
func upload(URLRequest: Router, onProgress: (progress: Float?) -> Void, completion: (json: AnyObject?, error: Error?) -> Void) {
let headers:[String: String] = [:]
let router = URLRequest.URLRequest
let tuple = URLRequest.parameters
let parameters = tuple.0!
let imagesData = tuple.1
let url = router.URLString
self.manager!.upload(
.POST,
url,
headers: headers,
multipartFormData: { (multipartFormData: MultipartFormData) -> Void in
for value in imagesData {
var mimeType = "video/jpg"
var bodyName = "images"
let filename = value.uniqueName
if value.mediaType == ReporterMediaType.image {
mimeType = "image/jpg"
bodyName = "images"
} else if value.mediaType == ReporterMediaType.video {
mimeType = "video/quicktime"
bodyName = "video"
} else if value.mediaType == ReporterMediaType.videoFrame {
mimeType = "image/jpg"
bodyName = "videoFrame"
}
multipartFormData.appendBodyPart(
data: value.data,
name: bodyName,
fileName: filename,
mimeType: mimeType)
}
for (key, value) in parameters {
multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
}
},
encodingCompletion: { (encodingResult) -> Void in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { response in
if response.result.isSuccess || response.response?.statusCode == 200 {
completion(json: upload, error: nil)
} else {
dispatch_async(dispatch_get_main_queue()) {
completion(json: nil, error: response.result.error)
}
}
}
upload.progress { _, totalBytesRead, totalBytesExpectedToRead in
let progress = Float(totalBytesRead)/Float(totalBytesExpectedToRead)
onProgress(progress: progress)
}
case .Failure:
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
break
}
}) }
func multipartImage(data:Data?, url:String,jsonInput:[String: String],controller:UIViewController, completion: #escaping (_ result: DataResponse<Any>) -> Void) {
var headers = Alamofire.SessionManager.defaultHTTPHeaders
headers["Headerkey"] = "Headerkey"
Alamofire.upload(multipartFormData:
{ (multipartFormData) in
if data != nil {
multipartFormData.append(data!, withName:"user_image", fileName:"image.jpg", mimeType:"image/jpeg")
}else{
multipartFormData.append("".data(using: String.Encoding.utf8)!, withName: "user_image")
}
for (key, value) in jsonInput
{
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
}
}, to:url, method: .post, headers: headers)
{ (result) in
switch result {
case .success(let upload, _ , _ ):
upload.uploadProgress(closure:
{ (progress) in
print(String(format:"%.0f%#",Float(progress.fractionCompleted)*100,"%")))
})
upload.responseJSON { response in
if showLoader == true
{
MBProgressHUD.hide(for: controller.view, animated: true)
}
completion(response)
}
case .failure(let encodingError):
print(encodingError.localizedDescription)
break
}
}
}

Resources