Objective C / iOS中相当于python的file.read()的是什么?
假设我有以下的Python代码:
someString = file("filename.jpg").read()
我该如何在iOS的Objective C中实现这行代码呢?我想把一个jpg图片转换成字符串,最终进行网址编码,以便可以传给Tumblr的API。我最开始尝试用base64编码把图片转换成字符串,但似乎没有得到Tumblr的有效响应。我也尝试了NSUTF8Encoding,但那些尝试返回的是nil字符串(见下文)。
我为什么要这么做呢?因为有人在Tumblr上发布了一个Python示例,展示如何提交多个照片到一个照片集,这是对这个讨论的回应,而这个过程似乎是从使用file.read()将图片转换为字符串开始的。不幸的是,API不接受简单的‘multipart/form-data’请求,只接受‘application/x-www-form-urlencoded’格式。
Python在做这个read()时使用了什么样的编码,我该如何在iPhone的Objective C中实现呢?
我尝试了以下方法:
NSString *utf8String = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"filename" ofType:@"jpg"] encoding:NSUTF8StringEncoding error:&error];
这给了我一个nil
字符串和error 261 The operation couldn’t be completed.
使用base64编码可以得到一个字符串,但Tumblr的API在进行网址编码后不接受它,所以我猜这不是Python用read()做的(虽然我可能只是漏掉了某个步骤)。Tumblr的API回应说"status":400,"msg":"Bad Request"},"response":{"errors":["Error uploading photo."]
在stackoverflow上有一个类似的问题,关于如何将照片上传到Tumblr的照片集,但这个问题更具体于发布的Python代码。
2 个回答
这就是你想要的东西吗?
NSData *data = [NSData dataWithContentsOfFile:@"filename.jpg"];
NSString *string = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]
我通过简单地记录字符串找到了答案——看起来它是十六进制格式的,里面有 \xXX 的形式,其中 XX 是每个字节的十六进制代码,对于某些容易打印的字符则用 ASCII 替代。
\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00\x1d\x08\x06\x00\x00\x00\xcb\x9en\x87\x00\x00\x01\xc9IDATH\r\xc5\x971K\x03A\x10\x85s\nB \x10\xb0\n\xa4\xb2J\x95* \x08\x82\x95\xbfA\x10\xfc\x01V\xb6\x82\x95?\xc0J\x10\x04[[\xc16U@\xb0\x8d`/(\x8a\x82\x08Z\t\x12\x89\xdf$\xd9p\x9c\xae\xfb&\x9c8\xf0\xd8\xbd\xdb\xb7o^\xe6\x96\xb9K6\x1c\x0e+\xb3D\x96e\xf3\xeck\xb3\xffj\x96\xfda\xcf\\\x98\xa8#\x89\xdb\xe0\x1c\xfe\x00\xf4\x99\x0f@\x17\xec\x80\xba\xaa3\xe5Y\x05\x14\xb0\xa1\x06\x0e\xc0=\xb0\xb2\xfd\x84\x17\xee\xaf(z\x81#%72\xb1\x1bIZ4r\x03\xaf\x16\x12\xa4F\xc9\x00\x82\xf6\xbcM\xb8\x98,v\xbd\x9fJ\x1c\xd6\xd53\xd0 \xf9\x12Pc]%\xaa\x06\x9e\x11\xfcTE\xe1\xd9y\x91B2@\xb9>P{\x90\x14\xc7$\xe3K!\x19\x98(Y\x15\xd4xR\x89\x1e\x03\xef\xaa(\xbc7\x95\xeb1\xd0RE\xe1-\xab\\\x8f\x01\xcf\x19\xb8\xfb\x0b\x03\x9e\x9e\x7f\xad\x1a\x90\x1a\x915\rb\x15\xdc\x82X\xf3\t\xf7\x1f\xe1tB\xa3I\x8d\xb2\x81\x89\x89=\xc1\xc0v*i~\xdds\x06\xc8]QJ\xabpLk\x1cy7\xa99;\x16@\x1f\x84r\x17\xc7K\xe3\xa4t\xf2\xeb\xde\n\xd8;\xe1\xb7\x13n\xcd\xca^\\z\xe4\xdd\xa4\xe6\xa8^\x80\xe2\xaf.^\x9f\xa4t\xf2\xeb\xd2!$i\x13\x1c\n\xc9\x83\x993\xb8\xad|\xa2\xd8<j\x00\x01{\xde\x9b\xa0\x0b\x82\xb0w\xec\xb1w\x0bTe\x03\x90;\xc0~\xad}^y\x13\xc6\xf8\xafh\x1d\x81o\xfdaZ\x01\x167\x80\xf2\x8ccI\xd4\xfb=\xf2\xac\x85\x8a\x8c\x0cp\xe3\x14\xa8\x02e\xf1\x8e\xcd\x84\x85}>\x95%\xea\xd5iX\x1f\xf0|\xeb\x99\xe12\xa3i\x06\xfc\x7f&\xca\xb30\xaa\xc0byzn\xa5\xbaU\xe0?\rT\xbf\x00\x87\x89 \xa8s3+7\x00\x00\x00\x00IEND\xaeB`\x82
在 Objective C 中,可以通过将图像读取到 NSData 中来复制上述过程,然后获取描述(这是一串两位数的十六进制格式字节值)。之后,你可以循环遍历每个字节,根据它的值决定如何表示它:
NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"anImage" ofType:@"jpg"]];
NSString *hexFormatString = [data describe];
hexFormatString = [[hexFormatString stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]] stringByReplacingOccurrencesOfString:@" " withString:@""];
NSMutableString * newString = [NSMutableString string];
for (int x=0; x<[hexFormatString length]; x+=2) {
NSString *component = [hexFormatString substringWithRange:NSMakeRange(x, 2)];
int value = 0;
sscanf([component cStringUsingEncoding:NSASCIIStringEncoding], "%x", &value);
if ((value <=46 && value >= 45) || (value <=57 && value >= 48) || (value <=90 && value >= 65) || (value == 95) || (value <=122 && value >= 97)) { //48-57, 65-90, 97-122
[newString appendFormat:@"%c", (char)value];
}
else {
[newString appendFormat:@"%%%@", [component uppercaseString]];
}
}