JS向OC传递JSON参数时的编码解码问题

在使用UIWebView进行混合编程时,JS与OC常常需要进行各种相互调用。有时候还需要传递一些参数,如果参数比较复杂的话,就可以考虑使用JSON。但是如果直接传递JSON,不进行编码的话,会出现非法字符。所以需要使用Base64进行编码,下面就来说说如何编码、解码。

JS代码中准备一个Base64的编码方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function base64_encode(str){
    var c1, c2, c3;
    var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    var i = 0, len= str.length, string = '';

    while (i < len){
        c1 = str.charCodeAt(i++) & 0xff;
        if (i == len){
            string += base64EncodeChars.charAt(c1 >> 2);
            string += base64EncodeChars.charAt((c1 & 0x3) << 4);
            string += "==";
            break;
        }
        c2 = str.charCodeAt(i++);
        if (i == len){
            string += base64EncodeChars.charAt(c1 >> 2);
            string += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
            string += base64EncodeChars.charAt((c2 & 0xF) << 2);
            string += "=";
            break;
        }
        c3 = str.charCodeAt(i++);
        string += base64EncodeChars.charAt(c1 >> 2);
        string += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
        string += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
        string += base64EncodeChars.charAt(c3 & 0x3F)
    }
    return string
}

然后使用如下方式将参数转换为JSON,并调用上面准备好的方法进行编码,依然是JS代码。

1
2
3
4
5
6
7
var jsonString = JSON.stringify(params);

var ecodedParams = base64_encode(jsonString);

var url = "gap:" + ecodedParams;

sendUrl(url);

这里有一个需要注意的地方,不要将自定义的协议头(这里指的是gap)也给转了,不然OC那边不好拦截。只将参数转换后,进行字符串拼接即可。

OK, JS这边的任务完成了,下面OC这边进行参数的接收与解码。iOS7自带了一个Base64的解码方法,相当方便。关于iOS7以下的解码方法,稍后会进行介绍。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    NSString *scheme = request.URL.scheme;
    if ([scheme isEqualToString:@"gap"]) {
        NSString *params = request.URL.resourceSpecifier;

        // 解码
        [self decodeParams:params];
        return NO;
    }
    return YES;
}

/**
 *  使用iOS7系统自带的方法进行解码并解析json
 */
- (id)decodeParams:(NSString *)params {
    NSData *data = [[NSData alloc] initWithBase64EncodedString:params options:NSDataBase64DecodingIgnoreUnknownCharacters];

    id rs = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];

    return rs;
}

以上方法适用于iOS7以上,如果要支持iOS7以下,就需要使用三方库进行解码了。这里介绍一下用Google的GTMBase64进行解码。由于这个东西不支持ARC,所以需要对相应的.m文件配置-fno-objc-arc, 下面看下如何使用。

1
NSData *data = [GTMBase64 decodeString:params];

只需要一句代码就搞定了,so easy! 最后再进行下方法合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
 *  解码
 */
- (id)decodeParams:(NSString *)params {
    NSData *data = nil;

    if ([UIDevice currentDevice].systemVersion.floatValue < 7.0f) {
        data = [GTMBase64 decodeString:params];
    } else {
        data = [[NSData alloc] initWithBase64EncodedString:params options:NSDataBase64DecodingIgnoreUnknownCharacters];
    }

    id rs = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];

    return rs;
}

Done!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值