在 iOS 開發中,使用舊版 SBJSON 框架解析伺服器回傳的 JSON 資料時,發現雖然原始 JSON 包含完整的鍵值對(如 varfirstname、varlastname 等),但解析成 NSArray 後,部分中文欄位卻變成空字串。這對於需要正確顯示使用者資料的應用來說是嚴重問題。
{
"0": "41",
"intid": "41",
"1": "言う",
"varfirstname": "言う",
"2": "test",
"varlastname": "test",
"3": "地",
"varusername": "地",
"4": "abc@gmail.com",
"varemailid": "abc@gmail.com",
"5": "qwert",
"varpassword": "qwert",
"6": "12345",
"varmobileno": "12345",
"7": "Enable",
"mobileMessage": "Enable",
"8": "",
"varphoneno": "",
"9": "Enable",
"enumstatus": "Enable",
"10": "2013-01-30",
"date_insert": "2013-01-30",
"11": "2013-01-30",
"date_edit": "2013-01-30",
"12": "210.211.252.1",
"varipaddress": "210.211.252.1"
}
// 使用 SBJSON 解析
SBJSON *parser = [[SBJSON alloc] init];
NSArray *array = (NSArray *)[parser objectWithString:json_string error:nil];
NSLog(@"Array === %@", array);
// 嘗試取得 varfirstname
NSDictionary *dataObject = [array objectAtIndex:0];
NSString *status = [dataObject objectForKey:@"varfirstname"];
NSLog(@"status -- %@", status);
解析後的陣列中,數字鍵(0、1、2...)對應的中文值均變為空字串,而英文鍵(intid、varfirstname 等)保持正常:
Array === (
{
0 = 41;
1 = ""; // 應為 "言う"
2 = test;
3 = ""; // 應為 "地"
...
varfirstname = ""; // 應為 "言う"
varusername = ""; // 應為 "地"
...
}
)
SBJSON 是早期第三方 JSON 解析庫,對 Unicode 處理存在缺陷。當 JSON 同時包含數字索引鍵和具名鍵時,解析器會產生衝突,導致中文字符編碼錯誤。這在 iOS 5 之前較常見,現代開發應避免使用。
自 iOS 5 起,Apple 提供原生 NSJSONSerialization 類,效能更好、相容性更強、無需第三方依賴。以下是正確實作範例:
- (void)viewDidLoad {
[super viewDidLoad];
NSError *error;
// 從 Bundle 讀取 JSON 檔案(實際開發中通常從網路請求取得 NSData)
NSData *data = [[NSData alloc] initWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:@"json" ofType:@"txt"]];
// 使用原生解析器
id jsonObj = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
if (error) {
NSLog(@"JSON 解析失敗: %@", error.localizedDescription);
return;
}
NSLog(@"完整解析結果: %@", jsonObj);
NSLog(@"varfirstname: %@", jsonObj[0][@"varfirstname"]); // 正確輸出: 言う
}
2013-02-01 22:47:40.361 JSONExperiment[4200:c07] (
{
0 = 41;
1 = "\U8a00\U3046"; // 正確保留 Unicode 編碼
3 = "\U5730"; // 正確保留 Unicode 編碼
...
varfirstname = "\U8a00\U3046";
varusername = "\U5730";
...
}
)
2013-02-01 22:47:40.363 JSONExperiment[4200:c07] 言う // 正確顯示中文
NSJSONSerialization 或現代第三方庫(如 SwiftyJSON、ObjectMapper)NSError 物件,不要傳入 nil 忽略錯誤Content-Type: application/json; charset=utf-8iOS 原生 NSJSONSerialization 完美解決了 SBJSON 解析中文空值的問題。現代 iOS 開發應優先使用系統級 API,減少第三方依賴,提升應用穩定性與維護性。