解決NSData轉NSString返回nil的問題

2021-07-01 20:38:07 字數 3485 閱讀 8536

在使用initwithdata

等方法將

nsdata轉換成nsstring時,如果nsdata的內容含有非encoding編碼的字元,將會返回nil。

----------sdk文件如下-------------

- (instancetype

)initwithdata:

()dataencoding:

()encoding;

return value

annsstringobject initialized by converting the bytes indatainto unicode characters usingencoding. the returned object may be different from the original receiver. returnsnilif the initialization fails for some reason (for example ifdatadoes not represent valid data forencoding).

-----------------------------

這個結果在很多時候可能並不是我們所希望的,比如在獲取網頁原始碼進行分析等方面,如果頁面採用了utf-8編碼,只是含有個別非utf-8字元,我們更希望轉換nsstring成功,拋棄(或替換)那些非法字元。

按照utf8格式標準

unicode/ucs-4

bit數

utf-8

byte數

範圍(16進製制)

0000 ~

007f

0~7

0*** ***x

1

0x - 7x

0080 ~

07ff

8~11

110x ***x

10xx ***x

2

cx 8x - dx bx

0800 ~

ffff

12~16

1110***x

10xx ***x

10xx ***x

3

ex 8x 8x - ex bx bx

1 0000 ~

1f ffff

17~21

1111 0***

10xx ***x

10xx ***x

10xx ***x

4

f8 8x 8x 8x 8x - fb bx bx bx bx 

20 0000 ~

3ff ffff

22~26

1111 10xx

10xx ***x

10xx ***x

10xx ***x

10xx ***x

5

fc 8x 8x 8x 8x 8x - fd bx bx bx bx bx

400 0000 ~

7fff ffff

27~31

1111 110x

10xx ***x

10xx ***x

10xx ***x

10xx ***x

10xx ***x

6

如果乙個位元組小於0x80,那麼他就是乙個字元;

如果大於c0小於e0,表示2個位元組組成的utf8字元(第乙個是110開頭的,第二個是10開頭的);

如果大於e0小於f0,表示3個位元組組成的utf8字元(第乙個是1110開頭的,第二個是10開頭的,第三個是10開頭的);

以此類推,如果不符合utf-8規則,則表示乙個非法字元,只要替換這樣的字元即可。 

實現方法如下(此實現可用但不夠嚴謹,如用於工程中建議進行優化):

[objc]view plain

copy

//替換非utf8字元

//注意:如果是三位元組utf-8,第二位元組錯誤,則先替換第一位元組內容(認為此位元組誤碼為三位元組utf8的頭),然後判斷剩下的兩個位元組是否非法;

- (nsdata

*)replacenoutf8:(

nsdata

*)data  

;                      

//utf8最多6個字元,當前方法未使用

nsmutabledata

*md = [nsmutabledata

datawithdata

:data];  

intloc = 

0;  

while

(loc 

length

])  

else

if((buffer & 0xe

0) == 0xc

0)  

loc--;  

//非法字元,將這個字元(乙個byte)替換為a

[mdreplacebytesinrange

:nsmakerange(loc, 1)

withbytes

:aalength:1

];  

loc++;  

continue

;  }  

else

if((buffer & 0xf

0) == 0xe

0)  

loc--;  

}  loc--;  

//非法字元,將這個字元(乙個byte)替換為a

[mdreplacebytesinrange

:nsmakerange(loc, 1)

withbytes

:aalength:1

];  

loc++;  

continue

;  }  

else

}  return

md;  

}  

轉換後的nsdata就可以正確轉換為nsstring了。

*如果是非utf-8編碼,請自行對對應照編碼協議轉換。

解決NSData轉NSString返回nil的問題

在使用initwithdata 等方法將 nsdata轉換成nsstring時,如果nsdata的內容含有非encoding編碼的字元,將會返回nil。sdk文件如下 instancetype initwithdata dataencoding encoding return value annss...

NSDictionary轉NSData 相互轉換

前言 今天發現一些同學 在nsdictionary轉nsdata竟然抓瞎了,所以就粘出來這個簡單的方法!大家在做網路請求的時間,如nsconnection 把nsdata轉nsdictionary的事了吧!這裡是一樣的foundation庫提供的nsjsonserialization 的乙個方法 d...

NSDictionary轉NSData 相互轉換

前言 今天發現一些同學 在nsdictionary轉nsdata竟然抓瞎了,所以就粘出來這個簡單的方法!大家在做網路請求的時間,如nsconnection 把nsdata轉nsdictionary的事了吧!這裡是一樣的foundation庫提供的nsjsonserialization 的乙個方法 d...