Uploading image to third party service using alamofire and auth token - swift

I have been trying to upload my image to a third party website using their api and alamofire to get some information back regarding the image that has been uploaded. I have to pass the auth token in with the request to get access to their resources, here is the instruction they have provided,
"Image should be specified by its url or uploaded with multipart form by parameter 'data'. You should use, respectively, GET and POST methods."
I have been trying to implement the upload method in 5 different ways but none of them seem to work I get a responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840 \"Invalid value around character 2.\" UserInfo={NSDebugDescription=Invalid value around character 2.}))" error back here is one of the functions that takes care of the upload:
let headers: HTTPHeaders = [ "Authorization": "Bearer \(authToken)" ]
let URL = try! URLRequest(url: "url", method: .post, headers: headers)
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imageData, withName: "signImg", fileName: "picture.png", mimeType: "image/png")
}, with: URL, encodingCompletion: {
encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint("SUCCESS RESPONSE: \(response)")
}
case .failure(let encodingError):
// hide progressbas here
print("ERROR RESPONSE: \(encodingError)")
}
})
I also don't understand the meaning of the parameters used to append the multipartformdata such as withName, filetype, mimeType.
I would really appreciate if you could attach an explanation with the solution.

Related

Alamofire photo upload with key of the file in body

I am able to upload a photo via Postman but in my iOS application it fails, and it is so weird that I still get a .success from encodingCompletion.
Here is part of my code
UpdateUserInfo
//
// Update user info
//
func updateUserInfo(){
var imageData: Data!
var url = ""
if let userId = KeychainWrapper.standard.string(forKey: USER_ID_KEY){
url = URL_USER_UPLOAD_PIC + userId
}
if pickedImage != nil{
imageData = UIImagePNGRepresentation(pickedImage)
//imageData = UIImageJPEGRepresentation(pickedImage!, 1.0)
}
let token = KeychainWrapper.standard.string(forKey: USER_LOGIN_TOKEN_KEY)!
let headers: HTTPHeaders = [
"Authorization": "Bearer \(token)"
]
if imageData != nil{
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imageData!, withName: "fileset", fileName: "file.png", mimeType: "image/png")
}, to: url,
method: .post,
headers: headers,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
print("Donkey Success \(String(describing: upload.response?.statusCode))")
upload.responseString(completionHandler: { (response) in
debugPrint(response)
})
case .failure(let encodingError):
print(encodingError)
print("Donkey Fail")
}
})
}
}
and in my postman I have
Postman
My first question is why I am getting a .success if it fails to upload?
and my second question is, do I need to put the key "pic" (seen in Postman) somewhere in my request? if so where?
Thanks for any help in advance
In Post man Image Key is pic but in your code its "fileset"
change to
multipartFormData.append(imageData!, withName: "pic", fileName: "file.png", mimeType: "image/png")
And success is Result of encoding not uploading processs
EncodingResult is MultipartFormDataEncodingResult that Defines
whether the MultipartFormData encoding was successful and contains
result of the encoding as associated values. - Success: Represents a successful MultipartFormData encoding and contains the
new UploadRequest along with
streaming information. - Failure: Used to represent a failure in the MultipartFormData encoding and also
contains the encoding

Swift and Python HTTP Request "GET"

I am making an app that can upload an image to a python backend server with my friends, and I need a little bit help on the http request, was trying to use Alamofire but somehow it needs backend to revise, but the backend cannot be revised because it is already in used with another Android App.
So here is my question, do I need to set the multipart/form-data, and also would you please read my code and give me some suggestions? I will show both of my sides code,
my front end:
func myImageUploadRequest()
{
// convert image to data object
guard let imageData = UIImageJPEGRepresentation(myImageView.image!, 1) else {
print("Could not get JPEG representation of UIImage")
return
}
// send multipart request
Alamofire.upload( multipartFormData: { multipartFormData in
multipartFormData.append(imageData, withName: "imagefile", fileName: "image.jpg", mimeType: "image/jpeg")},
to: "http://123.123.123.123/image",
headers: ["Authorization": "Basic xxx"],
encodingCompletion: { encodingResult in
// check the response
switch encodingResult {
case .success(let upload, _, _):
upload.uploadProgress { progress in
// Show progress
}
upload.responseJSON { response in
// Handle response
}
case .failure(let encodingError):
print(encodingError)
// Handle Error
}
})
}
I am still confused about this part, so I now have an image select from gallery, and I use an UIImageJPEGRepresentation to represent the image in a UIImageView area, how can I use that part to send to the server?
The back end is very simple, it is :
#app.route("/image", methods=["GET", "POST"])
def image():
if(request.method == 'GET'):
return '{ Success }'
file = request.files['file']
img = Image.open(request.files['file'])
img.save(os.path.join(app.config['UPLOAD_FOLDER'], file.filename))
return classify_image.pic_tensorflow('/home/images/file.jpg')
Can anyone give any suggestions?
I have changed the info list for the http.
Here are the error I got from the console
2018-03-13 01:42:54.424642-0500 zechengpart[53957:9552037] TIC Read Status [2:0x60000017ec00]: 1:54
2018-03-13 01:42:55.803615-0500 zechengpart[53957:9552112] [] nw_socket_get_input_frames recvmsg(fd 8, 3734 bytes): [54] Connection reset by peer

Upload audio binary file using Alamofire

I'm trying to upload an audio binary file to a server using Alamofire along with parameters and headers. Whenever I add the parameters; I get an error saying ambigious reference call to member error. I have checked the API online and haven't found a way to pass in parameters. Is there a way to do so?
let headersFileUpload: HTTPHeaders = ["Authorization": "JWT "+token!]
let parametersFileUpload: Parameters = ["ctype":"yes"]
Alamofire.upload(
multipartFormData: { multipartFormData in
multipartFormData.append(self.getDocumentsDirectory().appendingPathComponent("recording.m4a"), withName: "iosTest.mp3")
},
to: "http://localhost:8000/api/upload",
method:.post,
headers:headersFileUpload,
parameters:parametersFileUpload
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
}
case .failure(let encodingError):
print(encodingError)
}
}
)

RESTful mechanism to upload video (and properties) to vimeo

The procedure to upload a video to Vimeo starts out very similarly as the one defined for Youtube, but only up to a point. Below I describe the steps that worked, and outline the last video-upload step which does not:
The Vimeo-upload dance begins when we pass the following parameters to trigger user authentication:
let authPath:String = "\(url_vauth)?response_type=\(response_type)&client_id=\(client_id)&redirect_uri=\(redirect_uri)&state=\(state)&scope=upload"
if let authURL:NSURL = NSURL(string: authPath) {
let request = NSURLRequest(URL: authURL)
webView.loadRequest(request) // opens a webpage in a webUIView
// once credentials are entered, google redirects back with the above uri + a temporary code
// we will exchange later for a token
// within AppDelegate, we have defined a way to handle this uri, which is to call
// processOAuthStep1Response(url)
Then, we process the returned response to extract an authorization code:
let components = NSURLComponents(URL: url, resolvingAgainstBaseURL: false)
var auth_code:String!
// the block below extracts the text that follows "code" in the return url
if let queryItems = components?.queryItems {
for queryItem in queryItems { // step through each part of url
if queryItem.name.lowercaseString == "code" {
auth_code = queryItem.value
break
} // end of if queryItem.name.lowercaseString
} // end of for
} // if let queryItems
With this authorization code, we then generate a token:
let getTokenPath:String = url_token
let grant_type = "authorization_code"
let header_plain = "\(client_id):\(client_secret)"
let string_plain = header_plain.dataUsingEncoding(NSUTF8StringEncoding)
let string_base64 = (string_plain?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)))! as String
let headers = ["Authorization": "basic \(string_base64)"] // note that string_base64 really needs to be in base64!
//print ("...header is: \(string_base64)")
let tokenParams = ["grant_type": grant_type, "code": receivedCode, "redirect_uri": redirect_uri, "scope": "public"]
let request = Alamofire.request(.POST, getTokenPath, parameters: tokenParams, encoding: .URL, headers: headers)
We use this token to generate a ticket:
request(.POST, url_getticket, parameters: ticketParams , encoding: .URL, headers: headers).responseJSON { response in
//print(response)
switch response.result {
case .Success(let data):
let json = JSON(data)
print (json)
let myticket = json["ticket_id"].stringValue
//let usage = json[("upload_quota")].stringValue
let htmlform = json[("form")].stringValue
let uploadlink = json[("upload_link_secure")].stringValue
print("......ticket is \(myticket)")
print("......form is \(htmlform)")
print("......upload link is \(uploadlink)")
case .Failure(let error):
print("Request failed with error: \(error)")
} // end of switch
Finally (and this is where things stop to a screeching halt) we are supposed to use this ticket to make a POST request to Vimeo. The problem is that this ticket is embedded in an html form that actually makes the upload request to Vimeo...Not very useful for the iOS platform where I'm trying to implement this. Ideally, I'd like implementing with Alamofire via an upload call like so:
let headers = ["Authorization": "Bearer \(token)"]
upload(
.POST,
"https://1511923767.cloud.vimeo.com/upload?ticket_id=#######&video_file_id=####&signature=####&v6=1&redirect_url=https%3A%2F%2Fvimeo.com%2Fupload%2Fapi%3Fvideo_file_id%3D498216063%26app_id%3D70020%26ticket_id%####%26signature%######",
headers: headers,
multipartFormData: { multipartFormData in
multipartFormData.appendBodyPart(data: videodata, name: "video", fileName: "bagsy.m4v", mimeType: "application/octet-stream")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.progress { bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in
dispatch_async(dispatch_get_main_queue()) {
let percent = (Float(totalBytesWritten) / Float(totalBytesExpectedToWrite))
//progress(percent: percent)
print ("................\(percent)")
}
}
upload.validate()
upload.responseJSON { response in
print(response)
callback(true)
}
case .Failure(_):
callback(false)
}
})
Needless to say, the chunk of code above does not work. Any guidance would be most appreciated.
Consider using the official Vimeo iOS Upload SDK. We made it public about 2 weeks ago. It's a Swift library that handles upload of video files to Vimeo servers. It does so using a background-configured NSURLSession (so uploads continue regardless of whether your app is in the foreground or background). Let us know if you have any questions. Note: I'm one of the authors of the library and I work at Vimeo.
The VimeoUpload README is pretty robust and should communicate all that you need to know. Lettuce know if you have additional questions though, or feel free to make a pull request.
The ticket is never manually used in an upload. You should always use the url, or html provided by the API.
If you see HTML, it's because you are not providing the "type" parameter. We default to a simple POST upload system as described here: https://developer.vimeo.com/api/upload/videos#simple-http-post-uploading
If you provide "type=streaming", Vimeo returns a "complete_url", which you must call after performing the streaming upload as described here: https://developer.vimeo.com/api/upload/videos#resumable-http-put-uploads

Alamofire POST Returning Data

I am using Alamofire to make a post request to server. The post request is working fine.
Issue: When the post request is made, it returns some data which I need. How can I store/ retrieve that data
The POST Request:
Alamofire.request(.POST, postURL, parameters: params)
to get the response closure add
.response { request, response, data, error in }
to the end of your code
ie
Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar"])
.response { request, response, data, error in
print(request)
print(response)
print(data)
print(error)
}
If you are using the latest version of AlamoFire.
If you are using the latest version of AlamoFire.
Try this working fine for me.(Change request arguments based on your need)
let url1 = "http://yoururl.com"
let head = [ "Accept": "application/json;charset=UTF-8",
"Content-Type": "application/json;charset=UTF-8"] // Adding headers
let p = ["Email":"anything","Password": "123"] // Adding parameters if any
Alamofire.request(.POST,url1, parameters: p, encoding : .JSON, headers : head)
.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
}