I need to upload an image to the server endpoint where the structure has to be as following:
我需要将图像上传到服务器端点,其结构必须如下:
{ "image": { "file": imageData }, "access_token": access_token }
How can I send such a request using NSURLSession (or maybe even Alamofire or AFNetworking)?
如何使用NSURLSession(或者甚至是Alamofire或AFNetworking)发送此类请求?
3 个解决方案
#1
4
You cannot just include binary image data in a JSON request. JSON requires text representation, so if you do this, you must convert it to string (e.g. base64 encoding), use that in the JSON, and then the server code would presumably convert the base64 string back to binary data before attempting to use it.
您不能只在JSON请求中包含二进制图像数据。 JSON需要文本表示,所以如果你这样做,你必须将它转换为字符串(例如base64编码),在JSON中使用它,然后服务器代码可能会在尝试使用它之前将base64字符串转换回二进制数据。
But if you were base64 encoding of the image, it might look something like:
但是如果你是图像的base64编码,它可能看起来像:
// get image data
let imageData = UIImagePNGRepresentation(image)
// convert to base64
let base64String = imageData.base64EncodedStringWithOptions(nil)
// build parameters
let parameters = ["image": ["file" : base64String], "access_token" : accessToken]
// get JSON
var error: NSError?
let data = NSJSONSerialization.dataWithJSONObject(parameters, options: nil, error: &error)
assert(data != nil, "Unable to serialize \(error)")
// build request
let url = NSURL(string: "http://example.com/upload")!
let request = NSMutableURLRequest(URL: url)
request.addValue("text/json", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
let task = NSURLSession.sharedSession().uploadTaskWithRequest(request, fromData: data) { data, response, error in
// check for basic connectivity errors
if error != nil {
println("error: \(error)")
return
}
// check for server errors
if let httpResponse = response as? NSHTTPURLResponse, let statusCode = httpResponse.statusCode as Int? {
if statusCode != 200 {
println("status code is \(statusCode)")
}
}
// check for details of app-level server response, e.g. if JSON that was dictionary:
var parseError: NSError?
if let responseObject = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &parseError) as? [String : AnyObject] {
println(responseObject)
} else {
println("JSON parse failed: \(parseError)")
println("response was: \(response)")
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
println("responseString was: \(responseString)")
}
}
task.resume()
If you use Alamofire, this is simplified:
如果您使用Alamofire,则会简化:
// build parameters
let parameters = ["image": ["file" : base64String], "access_token" : accessToken] as [String : AnyObject]
// build request
let urlString = "http://example.com/upload"
Alamofire.request(.POST, urlString, parameters: parameters, encoding: .JSON)
.responseJSON(options: nil) { request, response, responseObject, error in
if error != nil {
println(error)
} else {
println(responseObject)
}
}
But both of the above are making assumptions about the nature of the response, that the server is base64 decoding the image data from the JSON, etc., but hopefully this illustrates the basic patterns.
但是上面两个都假设了响应的性质,服务器是基于64解码来自JSON的图像数据等,但希望这说明了基本模式。
Alternatively, use an application/x-www-form-urlencoded
request, in which you can send binary data as illustrated here.
或者,使用application / x-www-form-urlencoded请求,您可以在其中发送二进制数据,如此处所示。
#2
0
Try this:
尝试这个:
var request = NSMutableURLRequest(URL: NSURL(string: "https://\(IP):\(port)/")!)
var response: NSURLResponse?
var error: NSError?
//Adding the JSON String in HTTP Body
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(jsonString, options: nil, error: &error)
request.timeoutInterval = (number as! NSTimeInterval)
request.HTTPMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("gzip", forHTTPHeaderField: "Accept-encoding")
let urlData = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)
#3
0
Found a solution using AFNetworking with help from https://*.com/a/11092052/3871476
在https://*.com/a/11092052/3871476的帮助下使用AFNetworking找到了解决方案
For others looking for the solution.
寻找解决方案的其他人。
let manager = AFHTTPRequestOperationManager(baseURL: NSURL(string: url))
let request = manager.POST(url, parameters: param, constructingBodyWithBlock: {(formData: AFMultipartFormData!) -> Void in
formData.appendPartWithFileData(imgdata, name: "image[file]", fileName: "photo.jpeg", mimeType: "image/jpeg")
}, success: {(operation: AFHTTPRequestOperation!, responseObject: AnyObject!) -> Void in
//Success
}, failure: {(operation: AFHTTPRequestOperation!, error: NSError!) -> Void in
//Failure
println(error.localizedDescription)
})
The trick was to use the "image[file]"
parameter.
诀窍是使用“image [file]”参数。
#1
4
You cannot just include binary image data in a JSON request. JSON requires text representation, so if you do this, you must convert it to string (e.g. base64 encoding), use that in the JSON, and then the server code would presumably convert the base64 string back to binary data before attempting to use it.
您不能只在JSON请求中包含二进制图像数据。 JSON需要文本表示,所以如果你这样做,你必须将它转换为字符串(例如base64编码),在JSON中使用它,然后服务器代码可能会在尝试使用它之前将base64字符串转换回二进制数据。
But if you were base64 encoding of the image, it might look something like:
但是如果你是图像的base64编码,它可能看起来像:
// get image data
let imageData = UIImagePNGRepresentation(image)
// convert to base64
let base64String = imageData.base64EncodedStringWithOptions(nil)
// build parameters
let parameters = ["image": ["file" : base64String], "access_token" : accessToken]
// get JSON
var error: NSError?
let data = NSJSONSerialization.dataWithJSONObject(parameters, options: nil, error: &error)
assert(data != nil, "Unable to serialize \(error)")
// build request
let url = NSURL(string: "http://example.com/upload")!
let request = NSMutableURLRequest(URL: url)
request.addValue("text/json", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
let task = NSURLSession.sharedSession().uploadTaskWithRequest(request, fromData: data) { data, response, error in
// check for basic connectivity errors
if error != nil {
println("error: \(error)")
return
}
// check for server errors
if let httpResponse = response as? NSHTTPURLResponse, let statusCode = httpResponse.statusCode as Int? {
if statusCode != 200 {
println("status code is \(statusCode)")
}
}
// check for details of app-level server response, e.g. if JSON that was dictionary:
var parseError: NSError?
if let responseObject = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &parseError) as? [String : AnyObject] {
println(responseObject)
} else {
println("JSON parse failed: \(parseError)")
println("response was: \(response)")
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
println("responseString was: \(responseString)")
}
}
task.resume()
If you use Alamofire, this is simplified:
如果您使用Alamofire,则会简化:
// build parameters
let parameters = ["image": ["file" : base64String], "access_token" : accessToken] as [String : AnyObject]
// build request
let urlString = "http://example.com/upload"
Alamofire.request(.POST, urlString, parameters: parameters, encoding: .JSON)
.responseJSON(options: nil) { request, response, responseObject, error in
if error != nil {
println(error)
} else {
println(responseObject)
}
}
But both of the above are making assumptions about the nature of the response, that the server is base64 decoding the image data from the JSON, etc., but hopefully this illustrates the basic patterns.
但是上面两个都假设了响应的性质,服务器是基于64解码来自JSON的图像数据等,但希望这说明了基本模式。
Alternatively, use an application/x-www-form-urlencoded
request, in which you can send binary data as illustrated here.
或者,使用application / x-www-form-urlencoded请求,您可以在其中发送二进制数据,如此处所示。
#2
0
Try this:
尝试这个:
var request = NSMutableURLRequest(URL: NSURL(string: "https://\(IP):\(port)/")!)
var response: NSURLResponse?
var error: NSError?
//Adding the JSON String in HTTP Body
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(jsonString, options: nil, error: &error)
request.timeoutInterval = (number as! NSTimeInterval)
request.HTTPMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("gzip", forHTTPHeaderField: "Accept-encoding")
let urlData = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)
#3
0
Found a solution using AFNetworking with help from https://*.com/a/11092052/3871476
在https://*.com/a/11092052/3871476的帮助下使用AFNetworking找到了解决方案
For others looking for the solution.
寻找解决方案的其他人。
let manager = AFHTTPRequestOperationManager(baseURL: NSURL(string: url))
let request = manager.POST(url, parameters: param, constructingBodyWithBlock: {(formData: AFMultipartFormData!) -> Void in
formData.appendPartWithFileData(imgdata, name: "image[file]", fileName: "photo.jpeg", mimeType: "image/jpeg")
}, success: {(operation: AFHTTPRequestOperation!, responseObject: AnyObject!) -> Void in
//Success
}, failure: {(operation: AFHTTPRequestOperation!, error: NSError!) -> Void in
//Failure
println(error.localizedDescription)
})
The trick was to use the "image[file]"
parameter.
诀窍是使用“image [file]”参数。