ios - 我们如何在 Swift 中上传带有嵌套 JSON 参数的多部分表单数据?

标签 ios json swift nsurlsession alamofire

我需要将图像上传到结构必须如下所示的服务器端点:

 { "image": { "file": imageData }, "access_token": access_token }

如何使用 NSURLSession(或者甚至是 Alamofire 或 AFNetworking)发送这样的请求?

最佳答案

您不能只在 JSON 请求中包含二进制图像数据。 JSON 需要文本表示,所以如果你这样做,你必须将它转换为字符串(例如 base64 编码),在 JSON 中使用它,然后服务器代码可能会在尝试使用它之前将 base64 字符串转换回二进制数据。

但是如果你对图像进行 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()

如果你使用 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)
        }
    }

但以上两者都对响应的性质做出了假设,即服务器正在对来自 JSON 的图像数据进行 base64 解码等,但希望这能说明基本模式。

或者,使用 application/x-www-form-urlencoded 请求,您可以在其中发送二进制数据作为 illustrated here .

关于ios - 我们如何在 Swift 中上传带有嵌套 JSON 参数的多部分表单数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32087960/

相关文章:

iOS 使用另一个帐户分发应用程序

ios - 通过 iOS 将用户和密码发送到网页

ios - Firebase 查询数组

json - 有效地从 JSON 文件中删除无效字符?

uitableview - 在 Storyboard中和定义 VC 类之后编辑 UITableViewController

swift - 迭代具有无主引用的结构数组会无休止地进行

objective-c - iOS 将默认日期设置为日期选择器?

python - 如何在Python中将多级别的API响应转换为数据帧

C - 如何将宽字符日语字符转换为 UTF-8?

swift - 如何从嵌套枚举中获取所有值?