在Swift中上传包含多部分/表单数据的图像和参数

弗洛里安

[警告]
正如我所看到的,这个问题受到的关注比它应有的更多。我想告诉您不要使用以下任何代码。
在我问这个问题时,Swift不到一年,发展很快,大多数库都不对Swift友好且不稳定。我强烈建议您尝试将Alamofire或其他库用于此类任务。但是不要自己做。
[/警告]

我想将图像上传到Drupal端点。

我遇到的问题是我收到了文本/ html内容类型的HTTP 200 OK响应。在HTML响应中,有明确的消息表明已正确创建节点。但是在服务器端,映像未与节点关联。

另外,我不希望text / html,而是我在Accept标头中指定的application / json。

它已经可以在使用Android Rest模板的Android应用中使用。这是参考代码:

String url = getUrl("node/{info_id}/attach_file");

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);

if (user.isLoggedIn()) {
    headers.add(user.getSessionName(), user.getSessionId());
    headers.add("X-CSRF-Token", user.getToken());
    headers.add("Cookie", user.getSessionName() + "=" + user.getSessionId());
}

MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();

parts.add("files[field_mobileinfo_image]",
        new FileSystemResource(info.getImageUri()));
parts.add("field_name", "field_mobileinfo_image");

HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(parts, headers);
return getRestTemplate().exchange(url, HttpMethod.POST, request, Void.class, info.getId()).getBody();

我知道我没有在Android(Void.class)中检查响应,但是一切正常,并且图像已附加到服务器端的节点上。

现在在Swift中的iOS上,我尝试了多种方法。

使用AFNetworking:

func upload(mobileInfo: MobileInfo) {
    let user = userService.load()
    let url = Config.buildUrl("")

    let manager = AFHTTPRequestOperationManager(baseURL: NSURL(string:url)!)
    let serializer = AFHTTPRequestSerializer()
    serializer.setValue(user.sessionId, forHTTPHeaderField: user.sessionName)
    serializer.setValue(user.token, forHTTPHeaderField: "X-CSRF-Token")
    serializer.setValue("\(user.sessionName)=\(user.sessionId)", forHTTPHeaderField: "Cookie")
    manager.requestSerializer = serializer

    manager.responseSerializer.acceptableContentTypes.removeAll(keepCapacity: false)
    manager.responseSerializer.acceptableContentTypes.insert("application/json")

    let imageData = UIImageJPEGRepresentation(mobileInfo.image, 0.3)    
    manager.POST("/node/\(mobileInfo.id)/attach_file", parameters: nil, constructingBodyWithBlock: { (formData) -> Void in
        formData.appendPartWithFileData(
            imageData,
            name: "files[field_mobileinfo_image]",
            fileName: "field_mobileinfo_image",
            mimeType: "image/jpeg")
        formData.appendPartWithFormData("field_mobileinfo_image".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true), name: "field_name")
    },
    success: { (operation, data) -> Void in
        println(data)
    }) { (operation, error) -> Void in
        println(error)
    }
}

手动处理从其他stackoverflow问题中获取的信息:

func upload2(mobileInfo: MobileInfo) {
    let user = userService.load()
    let imageData = UIImageJPEGRepresentation(mobileInfo.image, 0.3)
    let url = NSURL(string:Config.buildUrl("/node/\(mobileInfo.id)/attach_file"))!
    println(url)
    var request = NSMutableURLRequest(URL: url)
    var session = NSURLSession.sharedSession()
    request.HTTPMethod = "POST"
    var boundary = "---------------------------14737809831466499882746641449"
    var contentType = "multipart/form-data; boundary=\(boundary)"
    println(contentType)
    request.addValue(contentType, forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    request.addValue("\(user.sessionName)=\(user.sessionId)", forHTTPHeaderField: "Cookie")
    request.addValue(user.sessionId, forHTTPHeaderField: user.sessionName)
    request.addValue(user.token, forHTTPHeaderField: "X-CSRF-Token")

    println(request.allHTTPHeaderFields)

    var body = NSMutableData()

    body.appendData("\r\n--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    body.appendData("Content-Disposition: form-data; name=\"field_name\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    body.appendData("field_mobileinfo_image".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)

    body.appendData("\r\n--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    body.appendData("Content-Disposition: form-data; name=\"files[field_mobileinfo_image]\"; filename=\"img.jpg\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    body.appendData("Content-Type: application/octet-stream\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    body.appendData(imageData)
    body.appendData("\r\n--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)


    var returnData = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)

    var returnString = NSString(data: returnData!, encoding: NSUTF8StringEncoding)

    println("returnString \(returnString)")
}

使用SRWebClient:

func upload3(mobileInfo: MobileInfo) {
    let user = userService.load()
    let imageData:NSData = NSData(data: UIImageJPEGRepresentation(mobileInfo.image, 0.3))
    SRWebClient.POST("http://master.test.lesfrontaliers.lu/node/\(mobileInfo.id)/attach_file")
        .headers(["Accept": "application/json",
            user.sessionName: user.sessionId,
            "X-CSRF-Token": user.token,
            "Cookie": "\(user.sessionName)=\(user.sessionId)"])
        .data(imageData, fieldName:"files[field_mobileinfo_image]", data:["field_name":"field_mobileinfo_image"])
        .send({ (response: AnyObject!, status: Int) -> Void in
            println(status)
            println(response)
        },failure:{(error:NSError!) -> Void in
            println(error)
        })
}

请救救我!;-)我做了很多尝试,使其无法正常工作,如果做错了,我再也看不见。对我来说似乎还可以。我可以看到的唯一区别是,我没有将映像存储在文件系统上,而是直接发送二进制数据,这最终是相同的。

这是在邮递员中创建的请求的图像(工作和接收json)

邮差

[编辑]如果可以帮助某人,则这是上述手动请求中错误部分的正确代码:

var body = NSMutableData()

body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition: form-data; name=\"field_name\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("field_mobileinfo_image\r\n".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)

body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition: form-data; name=\"files[field_mobileinfo_image]\"; filename=\"img.jpg\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Type: image/jpeg\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(imageData)
body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

body.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

request.HTTPBody = body
RMP

不知道这是否能满足您的要求,但是我们使用它来上传图像,主要区别是使用filenameContent-type

[self appendBody:body data:[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\".jpg\"\r\n", key]];

[self appendBody:body data:@"Content-Type: image/jpeg\r\n\r\n"];
[body appendData:imageData];

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

仅在Swift 4.2中上传包含多部分表单数据的图像

在Flask中上传文件,无需多部分/表单数据

如何在Swift4中通过具有多个参数的多部分表单数据上传图像或文件

使用多部分/表单数据上传图像

如何在Swift中使用嵌套的JSON参数上传多部分表单数据?

如何在iOS,Swift3,Alamofire 4中使用多部分表单数据将图像作为参数上传以及其他参数

AJAX在angular.js 1.3.0中上传多部分/表单数据的“意外令牌”

无法将包含多部分/表单数据的图片上传到服务器

使用JSON asp.net核心api上传多部分/表单数据图像

使用多部分/表单数据将图像从移动应用上传到API

AngularJS如何上传多部分表单数据和文件?

使用HTTPWebrequest上传文件(多部分/表单数据)

如何使用antd上传发送多部分/表单数据

使用 PowerShell 上传多部分/表单数据文件

通过图形API上传照片-多部分/表单数据

AngularJS:将照片作为多部分表单数据上传和发布并获得响应

在React中上传带有表单数据的图像

包含多部分/表单数据的DART发布

邮递员用jersey 2.0上传400错误的多部分/表单数据图像上传请求

多部分表单数据(NSDictionary 和图像)与 Android 到目标 – C

多部分/表单数据和FormType验证

使用Alamofire和多部分/表单数据

使用 Deno 和 Oak 处理多部分/表单数据

在带有scala的Play Framework 2中使用多部分验证带有图像上传的表单数据

Android的多部分/表单数据构造

多部分表单数据是如何工作的?

请求:发布多部分/表单数据

使用RestRserve的多部分/表单数据

Laravel惯性多部分表单数据