【问题标题】:NSData Multi-part response from NSURLConnection来自 NSURLConnection 的 NSData 多部分响应
【发布时间】:2015-03-04 17:17:21
【问题描述】:

我需要进行一个 Web 服务调用,该调用在多部分/相关响应中返回一个 IMAGE(响应我已在代码之后粘贴在下面。)

我无法读取图像数据。请帮忙。 我能够得到 POSTMAN 的回复。但不知道如何在代码中解析它。 此外,我需要帮助将 NSData 转换为 JSON 或 NSDictionary,以便我可以读取图像数据。我尝试了 NSJSONSerialization,但它返回 NULL。

  • 我写的代码:

    NSURL *url = [URIStringsClass messageAttachmentURI];  // Gets me our organization URI
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    NSURLResponse *response = nil;
    NSError *error = nil;
    
    // These are the headers that we need to set as per WebServices team documentation
    [request setHTTPMethod:@"GET"];
    [request setValue:self.message.system forHTTPHeaderField:@"X-systemID"];
    [request setValue:[NSString stringWithFormat:@"%@",self.message.messageId] forHTTPHeaderField:@"X-messageID"];
    [request setValue: [[[_message attachments] objectAtIndex:[indexPath row] - 2]JSONStringForKey:@"name"] forHTTPHeaderField:@"X-attachmentID"];
    
    // I AM NOT SURE IF I HAVE TO MENTION THIS    
    //    [request setValue:@"multipart/related" forHTTPHeaderField:@"content-type"];
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    
    if(data != nil)
    {
        UIView *aView = [[UIView alloc] initWithFrame:CGRectMake(30, 30, 200, 200)];
        UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(30, 30, 200, 200)];
        imageView.image = [UIImage imageWithData:data];
        aView.backgroundColor = [UIColor redColor];
        [aView addSubview:imageView];
        [self.subjectView addSubview:aView];
    
        NSString *newStr = [NSString stringWithUTF8String:[data bytes]];
        NSLog(@"JSON Data : %@", newStr);
    }
    
  • NSURLResponse执行代码后

    (lldb) po response
    <NSHTTPURLResponse: 0x7c9965f0> { URL: https://............ } { status code: 200, headers {
        Connection = "keep-alive";
        "Content-Language" = "en-US";
        "Content-Length" = 64159;
        "Content-Type" = "multipart/related; boundary=\"MIMEBoundaryurn_uuid_53A435D3A5CC74CCF71420587543829\"; type=\"text/xml\"; start=\"<0.urn:uuid:53A435D3A5CC74CCF71420587543830@apache.org>\"";
        Date = "Tue, 06 Jan 2015 23:28:56 GMT";
        Server = "WebSphere Application Server/7.0";
        "Set-Cookie" = "BIGipServerebiz-isqa-9444=1574180012.58404.0000; path=/";
        Via = Gateway;
        "X-Archived-Client-IP" = "127.0.0.1";
        "X-Backside-Transport" = "OK OK,OK OK";
        "X-Client-IP" = ".................";
        "X-CorrelationID" = "Id-54ac6fb500dfd23a00002862f08e4067 0; Id-54ac6fb50028d4fe000024d97aae61c6 0";
    } }
    
  • POSTMAN 上的 Web 服务响应:

    --MIMEBoundaryurn_uuid_53A435D3A5CC74CCF71420585641061
    Content-ID: <0.urn:uuid:53A435D3A5CC74CCF71420585641062@apache.org>
    Content-Type: application/json;
        charset="utf-8"
    
    {"GetAttachmentResponse":{"executionContext":null,"attachment":{"attachInfo":{"name":4,"attachmentID":"0","mimiType":"application/octet-stream"},"attachRef":"cid:urn:uuid:53A435D3A5CC74CCF71420585641037@apache.org"}}}
    --MIMEBoundaryurn_uuid_53A435D3A5CC74CCF71420585641061
    Content-ID: <urn:uuid:53A435D3A5CC74CCF71420585641037@apache.org>
    Content-Type: application/octet-stream
    
    ????JFIFHH??@ICC_PROFILE0ADBEmntrRGB XYZ ?acspAPPLnone???-ADBE
    
    [rest of binary data snipped out of question: see hex below or look at revision history]
    
    --MIMEBoundaryurn_uuid_53A435D3A5CC74CCF71420585641061--
    

    如果有人想看漂亮的 JSON 版本,那就是:

    {
        "GetAttachmentResponse": {
            "executionContext": null,
            "attachment": {
                "attachInfo": {
                    "name": 4,
                    "attachmentID": "0",
                    "mimiType": "application/octet-stream"
                },
                "attachRef": "cid:urn:uuid:53A435D3A5CC74CCF71420585641037@apache.org"
            }
        }
    }
    
  • NSData 我从代码中得到的:

    2015-01-06 14:56:53.682 KPFlagshipMessages[10676:147391] DATA : <0d0a0d0a 2d2d4d49 4d45426f 756e6461 72797572 6e5f7575 69645f35 33413433 35443341 
    35434337 34434346 37313432 30353835 36313938 34340d0a 436f6e74 656e742d 49443a20 3c302e75 726e3a75 
    7569643a 35334134 33354433 41354343 37344343 46373134 32303538 35363139 38343640 61706163 68652e6f 
    72673e0d 0a436f6e 74656e74 2d547970 653a2061 70706c69 63617469 6f6e2f6a 736f6e3b 0d0a0963 68617273 
    65743d22 7574662d 38220d0a 0d0a7b22 47657441 74746163 686d656e 74526573 706f6e73 65223a7b 22657865 
    63757469 6f6e436f 6e746578 74223a6e 756c6c2c 22617474 6163686d 656e7422 3a7b2261 74746163 68496e66 
    6f223a7b 226e616d 65223a22 494d475f 30313534 222c2261 74746163 686d656e 74494422 3a223022 2c226d69 
    6d695479 7065223a 22617070 6c696361 74696f6e 2f6f6374 65742d73 74726561 6d227d2c 22617474 61636852 
    6566223a 22636964 3a75726e 3a757569 643a3533 41343335 44334135 43433734 43434637 31343230 35383536 
    31393831 39406170 61636865 2e6f7267 227d7d7d 0d0a2d2d 4d494d45 426f756e 64617279 75726e5f 75756964 
    5f353341 34333544 33413543 43373443 43463731 34323035 38353631 39383434 0d0a436f 6e74656e 742d4944 
    3a203c75 726e3a75 7569643a 35334134 33354433 41354343 37344343 46373134 32303538 35363139 38313940 
    61706163 68652e6f 72673e0d 0a436f6e 74656e74 2d547970 653a2061 70706c69 63617469 6f6e2f6f 63746574 
    2d737472 65616d0d 0a0d0aff d8ffe000 104a4649 46000101 01006000 600000ff db004300 01010101 01010101 
    01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 
    01010101 01010101 01010101 ffdb0043 01010101 01010101 01010101 01010101 01010101 01010101 01010101 
    01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01ffc000 1108014d 
    00fa0301 22000211 01031101 ffc4001f 00000105 01010101 01010000 00000000 00000102 03040506 0708090a 
    0bffc400 b5100002 01030302 04030505 04040000 017d0102 03000411 05122131 41061351 61072271 14328191 
    a1082342 b1c11552 d1f02433 62728209 0a161718 191a2526 2728292a 34353637 38393a43 44454647 48494a53 
    54555657 58595a63 64656667 68696a73 74757677 78797a83 84858687 88898a92 93949596 9798999a a2a3a4a5 
    a6a7a8a9 aab2b3b4 b5b6b7b8 b9bac2c3 c4c5c6c7 c8c9cad2 d3d4d5d6 d7d8d9da e1e2e3e4 e5e6e7e8 e9eaf1f2 
    f3f4f5f6 f7f8f9fa ffc4001f 01000301 01010101 01010101 00000000 00000102 03040506 0708090a 0bffc400 
    b5110002 01020404 03040705 04040001 02770001 02031104 05213106 12415107 61711322 32810814 4291a1b1 
    c1092333 52f01562 72d10a16 2434e125 f1171819 1a262728 292a3536 3738393a 43444546 4748494a 53545556 
    5758595a 63646566 6768696a 73747576 7778797a 82838485 86878889 8a929394 95969798 999aa2a3 a4a5a6a7 
    a8a9aab2 b3b4b5b6 b7b8b9ba c2c3c4c5 c6c7c8c9 cad2d3d4 d5d6d7d8 d9dae2e3 e4e5e6e7 e8e9eaf2 f3f4f5f6 
    f7f8f9fa ffda000c 03010002 11031100 3f00fb87 e19fc3ff 00829a4f c1df851a af887e1a fc15d3a0 93e12fc3 
    39eeb53d 6be1f7c3 cb749649 7c0da13c b733dedf 6880bcd2 c8c6599e 579269a4 767625dd b3e63e32 f8d3fb19 
    f84a2b98 2cbe1cfc 2df1b6a5 047238b2 f0c7c22f 024b6ecc 8c5407d5 af3c3b65 a6471b31 00b4335e 328da180 
    e2bf1b34 ff0089cb aaf83fc0 52789bc5 3ab7886f a0f01782 ada26bfb bbbd5e6b 4860f0e6 94915bda da38992d 
    aded2183 ecf12430 a46a170c bbc2b1c9 b9f88b71 >
    

【问题讨论】:

  • 顺便说一下,不要在主线程中使用sendSynchronousRequest。使用许多异步技术中的任何一种,例如 NSURLConnection sendAsynchronousRequest 或 NSURLSession dataWithRequest。

标签: ios nsdata postman


【解决方案1】:

这看起来像是非常合理的多部分响应,我看到第二部分中似乎是有效的 JPEG(或至少是一个开头)。看到多部分响应是非常不寻常的:我们一直在 iOS 代码中构造多部分请求,但我们通常不处理多部分响应。

您的 Objective-C 代码虽然试图将其加载为图像,但它不是一个简单的图像。您实际上必须解析多部分响应。

在我们将您拖入解析这种多部分响应的丑陋过程之前,您是否被这种响应所困扰?我更愿意看到一个带有 base-64 编码图像的简单 JSON 响应。或者带有图片 URL 的 JSON 响应,可以单独下载。

解析这种非标准响应需要大量丑陋的代码,所以问题是是否有机会更改响应。


听起来你被这种格式卡住了。在这种情况下,要解析此响应,您首先必须从 NSURLResponse 标头中的 Content-Type 中获取 boundary。然后您可以扫描NSData 响应有效负载以查找--,后跟该边界字符串。然后,您将为每个部分设置几个标头,然后是一个空行,然后是有效负载。第一个有效负载是 JSON。第二个是形象。您只需读取字节,直到遇到下一个\r\n,然后是--,然后是边界。整个过程以-- 结尾,然后是一个边界,紧接着是另一个--。


有关如何构建多部分响应的讨论,请参阅 RFC 1341(MIME 规范)中对 multipart responses 的讨论。或查看RFC 2388(由 HTML 表单创建的多部分请求)。或者参见this example,了解如何在 Objective-C 中创建一个多部分请求。或者只是谷歌“创建多部分请求”。一旦您了解了如何创建多部分响应,那么多部分响应的解析将相当直观。但一定要确保在深入之前了解多部分有效负载。

请参阅Parse multipart response for image download in ios,了解一些用于解析此类响应的有希望的 Objective-C 代码。

【讨论】:

  • 嗨,罗伯。感谢您的回复和编辑帖子。我被这种反应困住了。我们得到的 JSON 响应与问题中显示的完全一样。你能帮忙吗?
  • 嗯,问题是你不只是有一个很好的 JSON 响应。你也没有很好的形象。你已经在一个多部分的响应中卡在一起,这将是一个痛苦的解析。不难,就是烦。您将不得不枚举NSData 的bytes,并按照我在修改后的答案中提到的那样对其进行解析。
  • 我能够删除标题并获取图像数据。但是当我用那个 NSData 制作 UIImage 时,它​​返回 nil。请问我能做什么?或者,如果我可以给你数据,你能告诉我图像数据到底从哪个索引开始,我必须使用什么编码?
  • 此特定 JPEG 中的前两个字节以 FF D8 开头。它上升到(但不包括)随后的 0D 0A 2D 2D 后跟边界字符串。请注意,一般情况下,您不能只查找 FF D8,也不能使用相同的索引,也不能硬编码要搜索的边界字符串。您必须解析多部分,因此其他答案提到了您。 (我不能保证,但如果您不想编写自己的解析器,我觉得这是一个开始的地方)。但是如果你想在某个地方上传这个(完整的请求标头详细信息加上完整的有效负载,最好是十六进制字符串),请随意。
  • 我能够制作一个通用解析器(将很快分享代码)。但是,当我将 NSData 编码为字符串以读取标头时,我认为它正在破坏我正在解析的 NSData 的一部分 ImageData。你能告诉我如何将我的原始数据传递给你吗?
猜你喜欢
  • 2015-07-01
  • 1970-01-01
  • 2011-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多