I am experiencing a really strange issue with uploading zip file to s3... Here is my sample code and all details:
private func uploadZipFile(_ photos:URL,_ step:String,_ presignedUrlModel: PresignedUrlModel) {
var uploadingBackgroundTask = UIBackgroundTaskIdentifier(rawValue: 3)
uploadingBackgroundTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
UIApplication.shared.endBackgroundTask(uploadingBackgroundTask)
uploadingBackgroundTask = .invalid
})
let success: () -> Void = {
DispatchQueue.main.async {
UIApplication.shared.endBackgroundTask(uploadingBackgroundTask)
uploadingBackgroundTask = .invalid
}
}
let failure: (ErrorResponse) -> Void = { error in
DispatchQueue.main.async {
UIApplication.shared.endBackgroundTask(uploadingBackgroundTask)
uploadingBackgroundTask = .invalid
}
}
let boundary = "Boundary-\(UUID().uuidString)"
let uploadingRequest = URL(string: presignedUrlModel.url)!
var request = APIhelper().getMultipartRequestBody(_type: "POST", _url: uploadingRequest, boundary: boundary)
let body = self.formBackgroundPhotoData(presignedUrlModel, step, photos, boundary)
request.httpBody = body
self.session.configuration.shouldUseExtendedBackgroundIdleMode = true
let task = session.dataTask(with: request, completionHandler: { (data, response, error) in
guard let data = data else {
return
}
if let httpResponse = response as? HTTPURLResponse {
if(httpResponse.statusCode==200)
{
success()
}
else if(httpResponse.statusCode>=400 && httpResponse.statusCode<500)
{
//getting 403 errorr
let error = ErrorResponse(message:
self.errorFormatingClass.getLocalizedErrorMessage(identifier: self.errorFormatingClass.ERROR)
,
identifier: self.errorFormatingClass.ERROR)
failure(error)
}
}
}
)
task.resume()
}
I always getting 403 response:AccessDeniedInvalid according to Policy: Policy Condition failed: ["eq", "$Content-Type", "application/zip"]
Here is how I form data:
private func formBackgroundPhotoData(_ presignedUrlModel: PresignedUrlModel,_ step: String,_ zip: URL,_ boundary: String) -> Data {
var body = Data()
var key = "key"
var value = presignedUrlModel.key
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.append("\(value)\r\n")
key = "AWSAccessKeyId"
value = presignedUrlModel.AWSAccessKeyId
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.append("\(value)\r\n")
key = "signature"
value = presignedUrlModel.signature
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.append("\(value)\r\n")
key = "policy"
value = presignedUrlModel.policy
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.append("\(value)\r\n")
let filename = zip.lastPathComponent
guard let data = try? Data(contentsOf: zip) else {
#if DEBUG
debugPrint("backgroundupload", "dataisnull")
#endif
return Data()
}
let mimetype = mimeTypeForPath(url: zip)
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"file\"; filename=\"\(filename)\"\r\n")
body.append("Content-Type: \(mimetype)\r\n\r\n")
body.append(data)
body.append("\r\n")
body.append("--\(boundary)--\r\n")
return body
}
Here is multipart request:
public func getMultipartRequestBody(_type: String, _url: URL, boundary: String) ->URLRequest
{
var request = URLRequest(url: _url)
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.timeoutInterval = 300
request.httpMethod = _type
return request
}
Now, I know this tons of code, and perhaps nobody will take a look... All I am asking: please provide an example for uploading zip or images to AWS S3, without adding S3 framework for uploading files..
Our whole team does not know what to do :(
Related
I want to upload some user data for register new users and I want to upload a profile picture. I'v tried with this code but it doesn't work, on my backend im just receiving a request with nothing like a form-data inside.
This is my swift code
func UserRegisterRequest(firstname: String, lastname: String, username: String, email: String, password: String, image: UIImage , completionHandler: #escaping (ReturnMessage) -> Void) {
let parameters = ["name": "MyTestFile123321",
"id": "12345"]
// MARK: URL Components
var components = URLComponents()
components.scheme = "https"
components.host = "my-url"
components.path = "/register"
//MARK: Create URL
guard let url = components.url else {
print("Invalid URL")
return
}
guard let mediaImage = Media(withImage: image, forKey: "profilePicture") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
//create boundary
let boundary = generateBoundary()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
//call createDataBody method
let dataBody = createDataBody(withParameters: parameters, media: [mediaImage], boundary: boundary)
request.httpBody = dataBody as Data
print(request.httpBody)
URLSession.shared.dataTask(with: request) {
data, response, error in
if let data = data {
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(DateFormatter.customFormatter)
let response = try decoder.decode(ReturnMessage.self, from: data)
completionHandler(response)
}catch(let error) {
print(error.localizedDescription)
}
} else {
print("No Data")
}
}.resume()
}
func generateBoundary() -> String {
return "Boundary-\(NSUUID().uuidString)"
}
func createDataBody(withParameters params: Parameters?, media: [Media]?, boundary: String) -> Data {
let lineBreak = "\r\n"
var body = Data()
if let parameters = params {
for (key, value) in parameters {
body.append("--\(boundary + lineBreak)")
body.append("Content-Disposition: form-data; name=\"\(key)\"\(lineBreak + lineBreak)")
body.append("\(value + lineBreak)")
}
}
if let media = media {
for photo in media {
print(photo)
body.append("--\(boundary + lineBreak)")
body.append("Content-Disposition: form-data; name=\"\(photo.key)\"; filename=\"\(photo.filename)\"\(lineBreak)")
body.append("Content-Type: \(photo.mimeType + lineBreak + lineBreak)")
body.append(photo.data)
body.append(lineBreak)
}
}
body.append("--\(boundary)--\(lineBreak)")
return body
}
I don't know if this is the right way to do it but any help is welcome.
thanks for you helping me guys
Currently I'm trying to program an https post request for the Plant Net API (https://my.plantnet.org/account/doc#) in Swift. I want to have one to five images inside my https post request and each image has as parameter organ (in my case this is always "leaf"). When I try to run my application, I get the error code 400 "Invalid multipart payload format". I'm not sure how I can solve this problem.
//
// PlantRecognition.swift
// Happy Plant
//
// Insert several images of the same plant (maximum of 5) and get the result list
//
import Foundation
import UIKit
class PlantRecognition {
//List with images of the plant to be recognized
var imageList: [UIImage] = []
//Api key for the plant net access
var API_KEY: String = "MY_API_KEY"
var plantNetURL: String = ""
init() {
//Set plant net url after class initialization
plantNetURL = "https://my-api.plantnet.org/v2/identify/all?api-key{\(API_KEY)}"
}
func recognizeImages(images: [UIImage]) {
//Try to create the api endpoint url
guard let apiEndpoint = URL(string: "https://my-api.plantnet.org/v2/identify/all?api-key=\(API_KEY)") else {print("Error creating api endpoint"); return }
//Convert the UIImages to jpeg
let imagesJPG = convertImagesToJPEG(images: images)
//Create url request
var request = URLRequest(url: apiEndpoint)
//Set the http method to post (local images)
request.httpMethod = "POST"
//Create boundary which marks the start/end of the request body
let boundary = "Boundary-\(UUID().uuidString)"
//Set value for our specific http header field
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
//Set the mime type to jpg (we will convert our UIImages to jpg)
let mimeType = "image/jpg"
//Create http body
var body = Data()
let boundaryPrefix = " — \(boundary)\r\n"
//Add the parameter to the body (Currently just leaf recognition is possible)
body.append("--\(boundaryPrefix)\r\n")
body.append("Content-Disposition: form-data; name=\"organs\r\n\r\n")
body.append("leaf\r\n")
//Add the images to the body
var filename = String()
for (index,data) in imagesJPG.enumerated(){
filename = "image\(index)"
body.append(boundaryPrefix)
body.append("Content-Disposition: form-data; name=\"image[]\"; filename=\"\(filename)\"\r\n")
body.append("Content-Type: \(mimeType)\r\n\r\n")
body.append(data)
body.append("\r\n")
}
body.append("--\(boundary)--\r\n")
//Post the request
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()
}
func convertImagesToJPEG(images: [UIImage]) -> [Data] {
var dataArray = [Data]()
for i in images {
if let data = i.jpegData(compressionQuality: 1.0) {
dataArray.append(data)
}
}
return dataArray
}
}
extension Data {
mutating func append(_ string: String) {
if let data = string.data(using: .utf8) {
append(data)
}
}
}
Here is my REST API for uploading file-
#api.route('/update_profile_picture', methods=['POST'])
def update_profile_picture():
if 'file' in request.files:
image_file = request.files['file']
else:
return jsonify({'response': None, 'error' : 'NO File found in request.'})
filename = secure_filename(image_file.filename)
image_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
image_file.save(image_path)
try:
current_user.image = filename
db.session.commit()
except Exception as e:
return jsonify({'response': None, 'error' : str(e)})
return jsonify({'response': ['{} profile picture update successful'.format(filename)], 'error': None})
The above code works fine as I tested with postman but in postman I can set a file object.
However, when I try to upload from iOS app, it gives me the error-
NO File found in request
Here is my swift code to upload image-
struct ImageFile {
let fileName : String
let data: Data
let mimeType: String
init?(withImage image: UIImage, andFileName fileName: String) {
self.mimeType = "image/jpeg"
self.fileName = fileName
guard let data = image.jpegData(compressionQuality: 1.0) else {
return nil
}
self.data = data
}
}
class FileLoadingManager{
static let sharedInstance = FileLoadingManager()
private init(){}
let utilityClaas = Utility()
func uploadFile(atURL urlString: String, image: ImageFile, completed:#escaping(Result<NetworkResponse<String>, NetworkError>)->()){
guard let url = URL(string: urlString) else{
return completed(.failure(.invalidURL))
}
var httpBody = Data()
let boundary = self.getBoundary()
let lineBreak = "\r\n"
let contentType = "multipart/form-data; boundary = --\(boundary)"
httpBody.append("--\(boundary + lineBreak)")
httpBody.append("Content-Disposition: form-data; name = \"file\"; \(lineBreak)")
httpBody.append("Content-Type: \(image.mimeType + lineBreak + lineBreak)")
httpBody.append(image.data)
httpBody.append(lineBreak)
httpBody.append("--\(boundary)--")
let requestManager = NetworkRequest(withURL: url, httpBody: httpBody, contentType: contentType, andMethod: "POST")
let urlRequest = requestManager.urlRequest()
let dataTask = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
if let error = error as? NetworkError{
completed(.failure(error))
return
}
if let response = response as? HTTPURLResponse{
if response.statusCode < 200 || response.statusCode > 299{
completed(.failure(self.utilityClaas.getNetworkError(from: response)))
return
}
}
guard let responseData = data else{
completed(.failure(NetworkError.invalidData))
return
}
do{
let jsonResponse = try JSONDecoder().decode(NetworkResponse<String>.self, from: responseData)
completed(.success(jsonResponse))
}catch{
completed(.failure(NetworkError.decodingFailed))
}
}
dataTask.resume()
}
private func boundary()->String{
return "--\(NSUUID().uuidString)"
}
}
extension Data{
mutating func append(_ string: String) {
if let data = string.data(using: .utf8){
self.append(data)
}
}
}
Also here is the NetworkRequest struct-
class NetworkRequest{
var url: URL
var httpBody: Data?
var httpMethod: String
var contentType = "application/json"
init(withURL url:URL, httpBody body:Data, contentType type:String?, andMethod method:String) {
self.url = url
self.httpBody = body
self.httpMethod = method
if let contentType = type{
self.contentType = contentType
}
}
func urlRequest()->URLRequest{
var request = URLRequest(url: self.url)
request.addValue(contentType, forHTTPHeaderField: "Content-Type")
request.httpBody = self.httpBody
request.httpMethod = self.httpMethod
return request
}
}
In The ImageLoaderViewController, an image is selected to be sent to be uploaded.
class ImageLoaderViewController: UIViewController {
#IBOutlet weak var selectedImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func selectImage(){
if selectedImageView.image != nil{
selectedImageView.image = nil
}
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .photoLibrary
imagePicker.delegate = self
self.present(imagePicker, animated: true, completion: nil)
}
#IBAction func uploadImageToServer(){
if let image = imageFile{
DataProvider.sharedInstance.uploadPicture(image) { (msg, error) in
if let error = error{
print(error)
}
else{
print(msg!)
}
}
}
}
func completedWithImage(_ image: UIImage) -> Void {
imageFile = ImageFile(withImage: image, andFileName: "test")
}
}
extension ImageLoaderViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate{
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[.originalImage] as? UIImage{
picker.dismiss(animated: true) {
self.selectedImageView.image = image
self.completedWithImage(image)
}
}
picker.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
}
The mistake is that you call boundary() function each time in your code that generates you new UUID but the resource must have a single one. So just generate UUID for your resource once and then insert this value where you need:
...
let boundary = boundary()
let contentType = "multipart/form-data; boundary = \(boundary)"
...
Setting up a multipart form-data content can be tricky. Especially there can be subtle errors when combining the many parts of the request body.
Content-Type request header value:
let contentType = "multipart/form-data; boundary = --\(boundary)"
Here, the boundary parameter should not be preceded with the prefix "--".
Also, remove any WS that are not explicitly allowed according the corresponding RFC.
Furthermore, enclosing the boundary parameter in double quotes makes it more robust and never hurts:
let contentType = "multipart/form-data; boundary=\"\(boundary)\""
Initial body:
httpBody.append("--\(boundary + lineBreak)")
This is the start of the body. Before the body, the request headers are written into the body stream. Each header is completed with a CRLF, and after the last header another CRLF must be written. Well, I am pretty sure, URLRequest will ensure this. Nonetheless, it might be worth checking this with a tool that shows the characters written over the wire.
Otherwise, add a preceding CRLF to the boundary (which conceptually belongs to the boundary anyway, and it does not hurt also):
httpBody.append("\(lineBreak)--\(boundary)\(lineBreak)")
Content-Disposition:
httpBody.append("Content-Disposition: form-data; name = \"file\"; \(lineBreak)")
Here, again you may remove the additional WS:
httpBody.append("Content-Disposition: form-data; name=\"file\"; \(lineBreak)")
Optionally, you may want to provide a filename parameter and a value. This is not mandatory, though.
Closing boundary
There's no error here:
httpBody.append(lineBreak)
httpBody.append("--\(boundary)--")
But you might want to make it clear, that the preceding CRLF belongs to the boundary:
httpBody.append("\(lineBreak)--\(boundary)--")
Characters after the closing boundary will be ignored by the server.
Encoding
extension Data{
mutating func append(_ string: String) {
if let data = string.data(using: .utf8){
self.append(data)
}
}
}
You cannot generally return utf8 encoded strings and embed this into the many different parts of a HTTP request body. Many parts of the HTTP protocol allow only a restricted set of characters. In many cases, UTF-8 is not allowed. You have to look-up the details in the corresponding RFCs - which is cumbersome, but also enlightened ;)
References:
RFC 7578, Definition of multipart/form-data
This is my way to upload a file from IOS Client using multipart form , with the help of Alamofire library
let url = "url here"
let headers: HTTPHeaders = [
"Authorization": "Bearer Token Here",
"Accept": "application/x-www-form-urlencoded"
]
AF.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imageData, withName: "image" ,fileName: "image.png" , mimeType: "image/png")
}, to: url, method: .post ,headers: headers).validate(statusCode: 200..<300).response { }
Here is nice example of Multipart. I think it could be something wrong with building multipart:
let body = NSMutableData()
if parameters != nil {
for (key, value) in parameters! {
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(value)\r\n")
}
}
if fileURLs != nil {
if fileKeyName == nil {
throw NSError(domain: NSBundle.mainBundle().bundleIdentifier ?? "NSURLSession+Multipart", code: -1, userInfo: [NSLocalizedDescriptionKey: "If fileURLs supplied, fileKeyName must not be nil"])
}
for fileURL in fileURLs! {
let filename = fileURL.lastPathComponent
guard let data = NSData(contentsOfURL: fileURL) else {
throw NSError(domain: NSBundle.mainBundle().bundleIdentifier ?? "NSURLSession+Multipart", code: -1, userInfo: [NSLocalizedDescriptionKey: "Unable to open \(fileURL.path)"])
}
let mimetype = NSURLSession.mimeTypeForPath(fileURL.path!)
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(fileKeyName!)\"; filename=\"\(filename!)\"\r\n")
body.appendString("Content-Type: \(mimetype)\r\n\r\n")
body.appendData(data)
body.appendString("\r\n")
}
}
body.appendString("--\(boundary)--\r\n")
return body
I am trying to upload some data to my server.I am tring to put my data in file and upload.The request body is multipart/form_data with a single parameter named "filemessage" containing text data which has a content-type of application/json
I am not sure how to handle the application/json as content-type for inner data contained by "filemessage".
I am getting 500 internal server error
{
"erMessage": "Unknown error",
"erCode": "UnknownErCode"
}
Here is the code.
func testMultipart()
{
let path = Bundle.main.path(forResource: "testregister", ofType: "txt")
do {
let mtext = try String(contentsOfFile: path!)
let dataA = Data(mtext.utf8)
guard let url = URL(string: "MY URL") else { return false }
var request = URLRequest(url: url)
request.httpMethod = "POST"
let mKey = "filemessage"
let mFileName = "testregister"
let mMimeType = "text/plain"
let boundary = generateBoundary()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let lineBreak = "\r\n"
var body = Data()
body.append("--\(boundary + lineBreak)")
body.append("Content-Disposition: form-data; name=\"\(mKey)\"; filename=\"\(mFileName)\"\(lineBreak)")
body.append("Content-Type: \(mMimeType + lineBreak + lineBreak)")
body.append(dataA)
body.append(lineBreak)
request.httpBody = dataA
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
}.resume()
}
catch(_){print("error")}
}
func generateBoundary() -> String
{
return "Boundary-\(NSUUID().uuidString)"
}
URL = https://test...com/camimage.aspx
Method Type : Post
Request Parameter :
Header Parameter [“UserID”]
Image Bytes
I got only above info with url and post request in multipart form data. I tried with swift4 multipart but not able to achieve the expected result.
Updated Question with Code and Log
func UploadRequest()
{
let url = URL(string: "https://...com/webcam/camimage.aspx")
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
let boundary = generateBoundaryString()
request.addValue("UserID", forHTTPHeaderField: "110159")
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
if (imageView.image == nil)
{
return
}
let image_data = UIImagePNGRepresentation(imageView.image!)
if(image_data == nil)
{
return
}
let body = NSMutableData()
let fname = "test.png"
let mimetype = "image/png"
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"uploaded_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 = URLSession.shared
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
guard ((data) != nil), let _:URLResponse = response, error == nil else {
print("error")
return
}
if let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
{
print(dataString)
}
})
task.resume()
}
func generateBoundaryString() -> String
{
return "*****"
}
I am putting Android Code also. It may help to analysis
FileInputStream fileInputStream = new FileInputStream(selectedFile);
URL url = new URL(SERVER_URL);
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);//Allow Inputs
connection.setDoOutput(true);//Allow Outputs
connection.setUseCaches(false);//Don't use a cached Copy
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("ENCTYPE", "multipart/form-data");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
connection.setRequestProperty("uploaded_file",selectedFilePath);
connection.setRequestProperty("UserID", "110159");
//creating new dataoutputstream
dataOutputStream = new DataOutputStream(connection.getOutputStream());
//writing bytes to data outputstream
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
+ selectedFilePath + "\"" + lineEnd);
dataOutputStream.writeBytes(lineEnd);
//returns no. of bytes present in fileInputStream
bytesAvailable = fileInputStream.available();
//selecting the buffer size as minimum of available bytes or 1 MB
bufferSize = Math.min(bytesAvailable,maxBufferSize);
//setting the buffer as byte array of size of bufferSize
buffer = new byte[bufferSize];
//reads bytes from FileInputStream(from 0th index of buffer to buffersize)
bytesRead = fileInputStream.read(buffer,0,bufferSize);
//loop repeats till bytesRead = -1, i.e., no bytes are left to read
while (bytesRead > 0){
//write the bytes read from inputstream
dataOutputStream.write(buffer,0,bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable,maxBufferSize);
bytesRead = fileInputStream.read(buffer,0,bufferSize);
}
dataOutputStream.writeBytes(lineEnd);
dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
serverResponseCode = connection.getResponseCode();
String serverResponseMessage = connection.getResponseMessage();
Log.i(TAG, "Server Response is: " + serverResponseMessage + ": " + serverResponseCode);
//response code of 200 indicates the server status OK
if(serverResponseCode == 200){
runOnUiThread(new Runnable() {
#Override
public void run() {
tvFileName.setText("File Upload completed.\n\n You can see the uploaded file here: \n\n" + "http://coderefer.com/extras/uploads/"+ fileName);
}
});
}
//closing the input and output streams
fileInputStream.close();
dataOutputStream.flush();
dataOutputStream.close();
I able to upload image via postman. Still not able to configured to upload via swift code.
Please check the attached two postman webapi chrome tool screenshots. Hope expert could help me out..
1st
2nd
Thanks in advance.
use this pod : https://github.com/Alamofire/Alamofire
Ref : https://gist.github.com/DejanEnspyra/5bae2a301b2b2bb5de3109344345617f
func requestWith(endUrl: String, imageData: Data?, parameters: [String : Any], onCompletion: ((JSON?) -> Void)? = nil, onError: ((Error?) -> Void)? = nil){
let url = "http://google.com" /* your API url */
let headers: HTTPHeaders = [
/* "Authorization": "your_access_token", in case you need authorization header */
"Content-type": "multipart/form-data"
]
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", fileName: "image.png", mimeType: "image/png")
}
}, usingThreshold: UInt64.init(), to: url, method: .post, headers: headers) { (result) in
switch result{
case .success(let upload, _, _):
upload.responseJSON { response in
print("Succesfully uploaded")
if let err = response.error{
onError?(err)
return
}
onCompletion?(nil)
}
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
onError?(error)
}
}
}