Upload images to the server using Alamofire - swift

The following problem arose, the fact is that sometimes images are not uploaded to the server. All the data is correct, the image is present, the variables are arranged in the correct order, the function reports a successful upload, but sometimes the images still do not reach the server. There are no such problems with the Retorfit library, but with Alamofire it often arises. I can not figure out yet why.
class func write_photo(params:[String:String],image:UIImage, in_position:String, completion:_ js:String, _ success:Bool -> Void, failure:_ errorMessage:String,_ failure:Bool -> Void) {
let url = BaseURL + "xdb_items.write_photo"
let URL = try! URLRequest(url: url, method: .post)
let in_idclient = params["in_idclient"]
let in_iditem = params["in_iditem"]
let imgData = UIImageJPEGRepresentation(image, 0.5)!
sessionManagerImage.upload(multipartFormData: { multipartFormData in
multipartFormData.append((in_idclient?.data(using: String.Encoding.utf8)!)!, withName: "in_idclient")
multipartFormData.append((in_iditem?.data(using: String.Encoding.utf8)!)!, withName: "in_iditem")
multipartFormData.append(imgData, withName: "in_filename", fileName: "photo", mimeType: "image/png")
multipartFormData.append((in_position.data(using: String.Encoding.utf8)!), withName: "in_position")
}, with: URL, encodingCompletion: {
encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response { response in
completion("", true)
}
case .failure(let encodingError):
print("ERROR RESPONSE: \(encodingError)")
}
})
}
my friends, when I did the application rollout, the Xcode issued such a warning on the id_item variable: could not execute support code to read Objective-C class data in the process. at real iPhone device maybe this is the problem
found an error, status code 500, because of what it can occur?
Postman work great! Screenshot Postman:
enter image description here
enter image description here
Code that Postman offers, but I need Alamofire:
import Foundation
let headers = [
"content-type": "multipart/form-data; boundary=----WeXXXXXXXXXXXXXXXXXXrZu0gW",
"Authorization": "Basic dXXXXXXXXXXXX=",
"cache-control": "no-cache",
"Postman-Token": "2c1bXXXXXXXXXXXXXXXXX4e"
]
let parameters = [
[
"name": "in_filename",
"fileName": "/home/iv/Рабочий стол/Скрины/Скрин6.png"
],
[
"name": "in_idclient",
"value": "516"
],
[
"name": "in_iditem",
"value": "1232"
],
[
"name": "in_position",
"value": "5"
]
]
let boundary = "----WeXXXXXXXXXXXXXXXXXXrZu0gW"
var body = ""
var error: NSError? = nil
for param in parameters {
let paramName = param["name"]!
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"\(paramName)\""
if let filename = param["fileName"] {
let contentType = param["content-type"]!
let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)
if (error != nil) {
print(error)
}
body += "; filename=\"\(filename)\"\r\n"
body += "Content-Type: \(contentType)\r\n\r\n"
body += fileContent
} else if let paramValue = param["value"] {
body += "\r\n\r\n\(paramValue)"
}
}
let request = NSMutableURLRequest(url: NSURL(string: "http://XXXXXXXXXX:XXXX/XX/xdb_items.write_photo")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()

try instead of this
multipartFormData.append(imgData, withName: "in_filename", fileName: "photo", mimeType: "image/png")
to
multipartFormData.append(imgData, withName: "profile_photo")
may be this will helpful for you

let imageData : Data! = (UIImage converted to Data)
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imageData, withName: "image", fileName: "file.jpeg", mimeType: "image/jpeg")
}, to: NSURL(string: "http://URL you want to upload it to")! as URL)
{ (result) in
switch result {
case .success(let upload, _, _):
//Success
case .failure(let encodingError):
//Failure
}
}

Related

Swift 5, make http post request

How can I do attached "postman operation" on Swift 5? i would like to use this code for login with rest service on ios(iphone).
Below is the code for Post Method,using URLSession
let Url = String(format: "http://10.10.10.53:8080/sahambl/rest/sahamblsrv/userlogin")
guard let serviceUrl = URL(string: Url) else { return }
let parameters: [String: Any] = [
"request": [
"xusercode" : "YOUR USERCODE HERE",
"xpassword": "YOUR PASSWORD HERE"
]
]
var request = URLRequest(url: serviceUrl)
request.httpMethod = "POST"
request.setValue("Application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else {
return
}
request.httpBody = httpBody
request.timeoutInterval = 20
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()
}
Try this with Alamofire 4.x
let parameters: [String: Any] = [
"request": [
"xusercode" : "YOUR USERCODE HERE",
"xpassword": "YOUR PASSWORD HERE"
]
]
Alamofire.request("YOUR URL HERE", method: .post, parameters: parameters,encoding: JSONEncoding.default, headers: nil).responseJSON {
response in
switch response.result {
case .success:
print(response)
break
case .failure(let error):
print(error)
}
}

Image Upload not working, iOS Swift Multipart

I have to upload an image to the server, but i am getting unusual behaviour,
if let imgdata = UIImageJPEGRepresentation(#imageLiteral(resourceName: "vishal"), 0.2) {
let headers: HTTPHeaders = [
"token": authToken,
"Content-type": "multipart/form-data"
]
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imgdata, withName: "image", fileName: "image.png", mimeType: "image/png")
}, usingThreshold: UInt64.init(), to: url, method: .patch, headers: headers) { (result) in
switch result{
case .success(let upload, _, _):
upload.responseJSON { response in
print("Succesfully uploaded")
if let _ = response.error{
return
}
if let value = response.result.value {
let json = JSON(value)
print(json)
}
}
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
}
}
}
in a new project, this code works fine and uploads the image to the server, but in my old project for the same code, api call is successful but image is not uploaded
Please help

Setting snippet data (Unlisted) for youtube upload via REST API using Swift

I upload video to youtube from my app. But it's public. I want to upload it unlisted. How can I do this ?
Any advice or code samples ?
func postVideoToYT(videoUrl: URL, token: String,title:String,innoId:Int,videoTags:String,callback: #escaping (Bool) -> Void) {
do {
let headers = ["Authorization": "Bearer \(token)"]
let videoData = try Data(contentsOf: videoUrl)
upload(multipartFormData: { multipartFormData in
multipartFormData.append("{'snippet':{'title' : '\(title)', 'description': ''}}".data(using: String.Encoding.utf8, allowLossyConversion: false)!, withName: "snippet", mimeType: "application/json")
multipartFormData.append("{'status' : {'privacyStatus':'unlisted'}}".data(using: String.Encoding.utf8, allowLossyConversion: false)!, withName: "status",mimeType: "application/json")
multipartFormData.append(videoData, withName: "video", fileName: "video.mp4", mimeType: "application/octet-stream")
}, usingThreshold: 1, to: URL(string: "https://www.googleapis.com/upload/youtube/v3/videos?part=snippet&status")!, method: .post, headers: headers, encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
print("Post video to url --->\(response)")
if let json = response.result.value as? [String : Any] {
let videoId = json["id"] as! String
self.delayWithSeconds(1, completion: {
self.addVideo(innoId: innoId, videoKey:videoId, shortDesc: title, tagIds: videoTags)
})
}
callback(true)
}
upload.uploadProgress(closure: { (progress) in
self.progressView.progress = Float(progress.fractionCompleted)
self.progressLabel.text = "\(( Int(progress.fractionCompleted * 100)))%"
})
break
case .failure(_):
callback(false)
break
}
})
}
catch {
}
}
**I think my problem is here ''https://www.googleapis.com/upload/youtube/v3/videos?part=snippet&statuspart=snippet&status''

Swift 3 Multipart form/data Upload- URLSession gets 206 response code/Alamofire receives 406

I am trying to upload data to our server. The data is a zip file converted in to Data.
SSZipArchive.createZipFile(atPath: "\(self.currentWPDirectory!)/\(self.documentId!).zip", withFilesAtPaths: checkInFileList)
let zipData = try! Data(contentsOf: URL(string: "file:///\(self.currentWPDirectory!)/\(self.documentId!).zip")!)
URLSession
let parameters = "?documentId=\(self.documentId!)&documentAction=CHECKIN&doc_action_comment=some comment&device_name=\(UIDevice.current.name)"
let urlString = "\(Constants.WebService.checkIn)\(parameters)"
let url = urlString.replacingOccurrences(of: " ", with: "%20")
let request = NSMutableURLRequest(url: URL(string: url)!)
let data = zipData
request.httpMethod = HTTPMethod.post.rawValue
let boundary = "----------SwIfTeRhTtPrEqUeStBoUnDaRy"
let contentType = "multipart/form-data; boundary=\(boundary)"
request.setValue(contentType, forHTTPHeaderField:"Content-Type")
let body = NSMutableData();
let tempData = NSMutableData()
let fileName = "FILE_NAME" + ".zip"
let parameterName = "userfile"
let mimeType = "application/octet-stream"
tempData.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
let fileNameContentDisposition = fileName != "" ? "filename=\"\(fileName)\"" : ""
let contentDisposition = "Content-Disposition: form-data; name=\"\(parameterName)\"; \(fileNameContentDisposition)\r\n"
tempData.append(contentDisposition.data(using: String.Encoding.utf8)!)
tempData.append("Content-Type: \(mimeType)\r\n\r\n".data(using: String.Encoding.utf8)!)
tempData.append(zipData)
tempData.append("\r\n".data(using: String.Encoding.utf8)!)
body.append(tempData as Data)
body.append("\r\n--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
request.setValue("\(body.length)", forHTTPHeaderField: "Content-Length")
request.httpBody = body as Data
let session = URLSession(configuration: URLSessionConfiguration.default)
let task = session.uploadTask(with: request as URLRequest, from: data) { (data, response, err) in
// Gets 206 in response
}
task.resume()
Alamofire
let params = [
"documentId": self.documentId!,
"documentAction": (self.isSync) ? "SYNC" : "CHECKIN",
"doc_action_comment": "Some Comment",
"device_name": UIDevice.current.name
]
Alamofire.upload(
multipartFormData: { multipartFormData in
multipartFormData.append(zipData, withName: "FILE_DATA", fileName: "\(self.documentId!).zip", mimeType: "application/zip")
for (key, value) in params {
multipartFormData.append((value as! String).data(using: .utf8)!, withName: key)
}
},
to: "\(Constants.WebService.checkIn)?documentId=\(self.documentId!)&documentAction=\((self.isSync) ? "SYNC" : "CHECKIN")&doc_action_comment=comment&device_name=\(UIDevice.current.name)",
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
print(response)
// Get 406 Response code
// Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0."
}
self.completionCallback!(true)
}
case .failure(let encodingError):
print(encodingError)
self.completionCallback!(false)
}
}
)
I have tried many ways to get multipart form/data uploads to send my data, with no success. Can anyone point me in the right direction?

NSData is nil After AsynchronousRequest In Swift

I am trying to add video data to the HTTP Request's body but sometimes video data is turning to nil but sometimes not. Is there anything to fix this situation? When I delete the app from my app and after doing simulation again, nothing happened.
#IBAction func post(sender: AnyObject) {
let videodata = NSData(contentsOfURL: videoURL!)
let headers = [
"authorization": "Token \(userToken!)",
"content-type": "/*/",
"content-disposition": "attachment;filename=deneme.mp4",
"cache-control": "no-cache"
]
let request = NSMutableURLRequest(URL: NSURL(string: "http://molocate.elasticbeanstalk.com/video/upload/")!,
cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringCacheData,
timeoutInterval: 10.0)
request.HTTPMethod = "POST"
request.allHTTPHeaderFields = headers
request.HTTPBody = videodata
let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
//print(NSString(data: data!, encoding: NSUTF8StringEncoding))
do {
let result = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers)
print("Result -> \(result)")
let statue = result["result"] as! String
if(statue == "success"){
let videoId = result["video_id"] as! String
let videoUrl = result["video_url"] as! String
print(videoUrl)
let json = [
"video_id": videoId,
"video_url": videoUrl,
"caption": "This city is awesome:)",
"category": "travel",
"tagged_users": [["username": "amertturker"]],
"location": [
[
"id": "mekmaekfmaıhjagej3ıo45j3kt348t3gkg",
"latitude": "35.342643",
"longitude": "32.345236",
"name": "Milas Merkez Kafasına göre herkes",
"address": "Milas aq"
]
]
]
let newheaders = [
"authorization": "Token \(userToken!)",
"content-type": "application/json",
"cache-control": "no-cache"
]
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(json, options: .PrettyPrinted)
print(NSString(data: jsonData, encoding: NSUTF8StringEncoding))
// create post request
let url = NSURL(string: "http://molocate.elasticbeanstalk.com/video/update/")!
let request = NSMutableURLRequest(URL: NSURL(string: "http://molocate.elasticbeanstalk.com/video/update/")!,
cachePolicy: .UseProtocolCachePolicy,
timeoutInterval: 10.0)
request.HTTPMethod = "POST"
request.allHTTPHeaderFields = newheaders
request.HTTPBody = jsonData
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data, response, error in
print(response)
//print(NSString(data: data!, encoding: NSUTF8StringEncoding))
dispatch_async(dispatch_get_main_queue(), {
if error != nil{
print("Error -> \(error)")
return
}
do {
let result = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments)
print("Result -> \(result)")
} catch {
print("Error -> \(error)")
}
})
}
task.resume()
} catch {
print(error)
}
} else{
// self.displayAlert("Hata", message: result["result"] as! String)
// UIApplication.sharedApplication().endIgnoringInteractionEvents()
// self.activityIndicator.stopAnimating()
// self.activityIndicator.hidesWhenStopped = true
}
} catch {
print("Error -> \(error)")
}
}
})
dataTask.resume()
do {
try NSFileManager.defaultManager().removeItemAtPath(videoPath!) //.removeItemAtURL(fakeoutputFileURL!)
dispatch_async(dispatch_get_main_queue()) {
print("siiiiil")
self.performSegueWithIdentifier("finishUpdate", sender: self)
}
} catch _ {
}
Your calling the httprequest asynchronously and then trying to use the data on the calling thread. It hasn't been populated until after the http request has returned which will occur at an undetermined future time. Anything you want to do with videoData should be done inside the completion handler, otherwise you are in a race condition and it might be nil when you call it.