打印NSData使用NSLog

56

如何使用NSLog打印NSData对象的内容:

-(void) post:(NSString*) msg to:(NSString*) link{
    NSString *myRequestString = [NSString stringWithFormat:@"message=%@", msg];
    NSData *myRequestData = [NSData dataWithBytes: [myRequestString UTF8String] length: [myRequestString length]];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: link]]; 
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
    [request setHTTPMethod: @"POST"];
    [request setHTTPBody: myRequestData];
    NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil];
    NSLog("%@", *returnData); //doesn't work

}

我想打印*returnData的内容...


这里的问题不是你使用了 NSLog("") 而不是 NSLog(@"") 吗?(也就是说,你传递了一个 C 字符串而不是 NSString?)(无论格式如何?) - benathon
5个回答

85

使用以下方法将NSData转换为NSString:

NSString *strData = [[NSString alloc]initWithData:returnData encoding:NSUTF8StringEncoding];

以类似下面的方式在 NSLog 中打印 NSString:

NSLog(@"%@",strData);

这个答案是为了JeremyP而编辑的,因为他不知道如何确定内容是否为UTF-8,尽管这不是这个问题的讨论。

您可以在以下委托方法中获取响应标头

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSDictionary *dic = [httpResponse allHeaderFields];
}

这个字典会给你完整的标题信息,像下面这样

<CFBasicHash 0x5a45e40 [0x24b2380]>{type = immutable dict, count = 7,
entries =>
0 : <CFString 0x5d1bf60 [0x24b2380]>{contents = "X-Aspnet-Version"} = <CFString 0x5d21a60 [0x24b2380]>{contents = "2.0.50727"}
1 : <CFString 0x41a03a8 [0x24b2380]>{contents = "Server"} = <CFString 0x5d272f0 [0x24b2380]>{contents = "Microsoft-IIS/6.0"}
2 : <CFString 0x41a0010 [0x24b2380]>{contents = "Content-Length"} = <CFString 0x5d28630 [0x24b2380]>{contents = "385"}
6 : <CFString 0x419ff48 [0x24b2380]>{contents = "Cache-Control"} = <CFString 0x5d29c70 [0x24b2380]>{contents = "private, max-age=0"}
10 : <CFString 0x5d1c640 [0x24b2380]>{contents = "X-Powered-By"} = <CFString 0x5d26f10 [0x24b2380]>{contents = "ASP.NET"}
11 : <CFString 0x41a0060 [0x24b2380]>{contents = "Content-Type"} = <CFString 0x5d29c90 [0x24b2380]>{contents = "text/xml; charset=utf-8"}
12 : <CFString 0x41a0088 [0x24b2380]>{contents = "Date"} = <CFString 0x5d27610 [0x24b2380]>{contents = "Fri, 08 Jul 2011 15:23:10 GMT"}
} 

检查charset="utf-8",您将从这里获取编码。


如果这个对你有用,请标记它为答案,这样其他人就可以把它视为正确的答案。 - jigneshbrahmkhatri
它给我这个警告 -> 警告:从不兼容的指针类型传递参数1到“NSLog” - user559142
2
你如何知道数据是以UTF-8编码的? - JeremyP
@jeremyP,请检查我的编辑答案,这是专门为您准备的。 - jigneshbrahmkhatri
@Jignesh:我给你的回答点了踩,因为你的回答假设HTTP消息是UTF-8编码的。这是一个错误的假设。如果在“Content-Type”中没有指定编码方式,那么默认的编码方式(根据RFC 2616)是ISO-8859-1。 - JeremyP
显示剩余4条评论

64

如果你这样做:

NSLog(@"%@", returnData); 

NSData将以十六进制格式记录。我认为这可能是你想要的。

如果你想把它转换成字符串并记录该字符串,你需要先找出使用的字符集。HTTP的默认字符集不是UTF-8,而是ISO-8859-1。一种方法是检查Content-Type头部中的charset部分。


5
这是正确答案,您不能假设数据的内容编码!HTTP头、字节顺序标记等都有其原因,所有文本并不相同。 - Joe
我认为这是一个更好的答案。 - antonio081014
要将十六进制数据作为可读字符串进行检查,通常可以使用以下方法:https://dev59.com/SGw15IYBdhLWcg3wbLHU#38225931 :) - Leonard Pauli

4

我经常想要查看NSData实际表示的内容,通常这是一些文本,使十六进制变得有些不方便。因此,我通常在Web浏览器的JavaScript控制台中编写以下代码片段,它运行得非常快并且可以轻松地进行修改,以便进行更多的处理。

  1. Copy/paste the following script into your browser console (right click here -> Inspect element), hit enter

    (function nsDataHexToString() {
        var str = prompt("Paste the hex string here:", "ié. 48656c6c 6f207468 657265...")
        var chs = str.replace(/[^A-F0-9]/ig,"").split("")
        var res = ""
        var cnt = 2
        for (var i = 0; i+cnt-1<chs.length; i+=cnt) {
            var nr = ""
            for (var j=0; j<cnt; j++)
                nr += chs[i+j]
            nr = parseInt(nr, 16)
            res += String.fromCharCode(nr)
        }
        console.log(res)
        return res
    })()
    
  2. Run your swift/obj-c code, put in a breakpoint and inspect your NSData object

    let sample = "Hello there"
    let data = sample.dataUsingEncoding(NSUTF8StringEncoding)
    // Put breakpoint here, hover over "data", and press the eye/i
    
  3. Copy the hex (something like <48656c6c 6f207468 657265>) and paste into the browser prompt

  4. The console will then show a string: "Hello there"

最近,我需要检查由NSAttributedString.dataFromRange输出的内容,因为rtfd使用了有点不同的编码方式,但是我得到了我需要的内容 :) 这对于解决一些JSON转换问题也很有用。

祝你好运 :)


谢谢@CoryImdieke!很高兴能帮到你 :) - Leonard Pauli

4

还有一件事情也必须考虑到:

NSLog(@"%@", *returnData); // this is wrong.

NSLog(@"%@", returnData); // this is correct.

我希望你能帮助我!


5
你忘了在NSLog函数中添加@符号。 - Varun Bhatia

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接