首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS 使用 SBJSON 解析回傳空值問題解決方案

     編輯:程式設計綜合問答

問題背景

在 iOS 開發中,使用舊版 SBJSON 框架解析伺服器回傳的 JSON 資料時,發現雖然原始 JSON 包含完整的鍵值對(如 varfirstname、varlastname 等),但解析成 NSArray 後,部分中文欄位卻變成空字串。這對於需要正確顯示使用者資料的應用來說是嚴重問題。

原始 JSON 資料結構

{
  "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 之前較常見,現代開發應避免使用。

推薦解決方案:改用 NSJSONSerialization

自 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] 言う  // 正確顯示中文

最佳實踐建議

  • 棄用 SBJSON:專案中若仍在使用,請盡快遷移至 NSJSONSerialization 或現代第三方庫(如 SwiftyJSON、ObjectMapper)
  • 統一鍵名風格:後端 API 應避免同時回傳數字索引鍵和具名鍵,減少解析歧義
  • 錯誤處理:務必檢查 NSError 物件,不要傳入 nil 忽略錯誤
  • 編碼確認:確保伺服器回傳 Content-Type: application/json; charset=utf-8

總結

iOS 原生 NSJSONSerialization 完美解決了 SBJSON 解析中文空值的問題。現代 iOS 開發應優先使用系統級 API,減少第三方依賴,提升應用穩定性與維護性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved