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 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}"

你可能感兴趣的:(JSON转换传给JS时的特殊处理)