在使用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!