背景介绍
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 var str = 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 SEPARATOR
return "\(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编码的。
一般情况下,两者在使用中基本没差别,可以共存,也可以很方便地相互转换。
在转义字符等特殊场合,两者的表示还是有差异的。比如NSString的“\f”,对应String中的"\u{000c}"