iOS -initWithData: encoding: 返回 nil 的解决办法

321 阅读1分钟

方法:-initWithData: encoding: 是将一个 NSData 对象转换为 NSString 对象。 有时候,NSData 非空,该方法却返回一个 nil,而不是返回一个 NSString 对象。 究其原因,无非是 NSData 中含有非 UTF-8 编码的字符,导致转换失败。

下面给出一个解决办法:首先导入 libiconv.tdb

#import <iconv.h>

static NSData *ALUTF8NSData(NSData *data) {
    if (!data) return nil;
    const char *iconv_utf8_encoding = "UTF-8";
    iconv_t cd = iconv_open(iconv_utf8_encoding, iconv_utf8_encoding); // 从utf8转utf8
    int one = 1;
    iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, &one); // 丢弃不正确的字符

    size_t inbytesleft, outbytesleft;
    inbytesleft = outbytesleft = data.length;
    char *inbuf  = (char *)data.bytes;
    char *outbuf = malloc(sizeof(char) * data.length);
    char *outptr = outbuf;
    size_t icon = iconv(cd, &inbuf, &inbytesleft, &outptr, &outbytesleft);

    if (icon == 0) {
        NSData *result = [NSData dataWithBytes:outbuf length:data.length - outbytesleft];
        iconv_close(cd);
        free(outbuf);

        return result;
    }
    return nil;
}

NSDataNSString 示例:

NSData *data = /***/;
NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (!dataString) { // 解决 NSData 转化为 NSString 时,可能返回 nil 的情况
    NSData *data = ALUTF8NSData(nsData);
    dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}