JSON转换传给JS时的特殊处理

背景介绍 Native和JS的交互如果采用第三方库WebViewJavascriptBridge,这个问题就不会有。这个问题也是在看这个第三方库源码的时候发现的。如果要自己写,那么这部分代码要移植过去。不然的话,会出现有时候JS解析JSON不正确的现象
Object-C版

- (NSString *)toJsonString:(NSDictionary *)dictionary { if (nil == dictionary) { return nil; }NSString *jsonString = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:dictionary options:(NSJSONWritingOptions)0 error:nil] encoding:NSUTF8StringEncoding]; jsonString = [jsonString stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]; jsonString = [jsonString stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; jsonString = [jsonString stringByReplacingOccurrencesOfString:@"\'" withString:@"\\\'"]; jsonString = [jsonString stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"]; jsonString = [jsonString stringByReplacingOccurrencesOfString:@"\r" withString:@"\\r"]; jsonString = [jsonString stringByReplacingOccurrencesOfString:@"\f" withString:@"\\f"]; jsonString = [jsonString stringByReplacingOccurrencesOfString:@"\u2028" withString:@"\\u2028"]; jsonString = [jsonString stringByReplacingOccurrencesOfString:@"\u2029" withString:@"\\u2029"]; return jsonString; }- (NSDictionary *)toDictionary:(NSString *)jsonString { if (nil == jsonString) { return nil; } // 去掉百分号,中文等特殊编码 NSString *tempString = [NSString stringWithFormat:@"%@", jsonString]; tempString = [tempString stringByRemovingPercentEncoding]; return [NSJSONSerialization JSONObjectWithData:[tempString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil]; }

Swift版
func assembledJS(response: [String: AnyObject]?, type: CallbackType = .Success) -> String? { guard let response = response else { return nil } let pre = "bridge.invokeJs('" let last = "')" var callbackId: NSNumber? if type == .Success { callbackId = params?["success"] as? NSNumber } else { callbackId = params?["fail"] as? NSNumber }if let callbackId = callbackId { let result = ["response": response, "callbackId": callbackId]do { let data = try NSJSONSerialization.dataWithJSONObject(result, options: NSJSONWritingOptions(rawValue: 0)) guard varstr = NSString(data: data, encoding: NSUTF8StringEncoding) as? String else { return assembledJS(["message": "native convert json error"], type: .Failure) }str = str.stringByReplacingOccurrencesOfString("\\", withString: "\\\\") str = str.stringByReplacingOccurrencesOfString("\"", withString: "\\\"") str = str.stringByReplacingOccurrencesOfString("\'", withString: "\\\'") str = str.stringByReplacingOccurrencesOfString("\n", withString: "\\n") str = str.stringByReplacingOccurrencesOfString("\r", withString: "\\r") str = str.stringByReplacingOccurrencesOfString("\u{000C}", withString: "\\u{000C}") //\f str = str.stringByReplacingOccurrencesOfString("\u{2028}", withString: "\\u{2028}") //LINE SEPARATOR str = str.stringByReplacingOccurrencesOfString("\u{2029}", withString: "\\u{2029}") //PARAGRAPH SEPARATORreturn "\(pre)\(str)\(last)" } catch { log("由dic拼装json出错, 默认执行出错回调") return assembledJS(["message": "native convert json error"], type: .Failure) } } else { log("不需要回调") return nil } }

不同之处
  • Object-C中字符串是NSString,是Foundation的库函数,不是Unicode的
  • Swift中字符串String是语言自带的结构体,是Unicode编码的。
  • 一般情况下,两者在使用中基本没差别,可以共存,也可以很方便地相互转换。
  • 【JSON转换传给JS时的特殊处理】在转义字符等特殊场合,两者的表示还是有差异的。比如NSString的“\f”,对应String中的"\u{000c}"

    推荐阅读