先说说项目状况:使用phonegap创建的ios项目,而后在使用html + css开发网页中又使用了一个框架Framework7(Framework7是一个构建仿原生ios和android应用的框架)。形成把网站打包成app以后,只有一个入口主页面(假设该主页面为index.html), 而后在index.html页面引用全部要用的css和js。其余html页面只有部分html标签,不引用css和js, 其余html页面的展现都是经过主页面index.html的连接进行跳转到那里!javascript
如今在作这个项目的推送消息,碰到了一些问题:接收到推送通知的状况应该是三种:一、程序正在前台运行; 二、程序正在后台运行; 三、程序彻底退出后台。css
而后咱们在这三种状况下收到推送通知后,解析通知参数,而后想根据参数跳转到目标页面去。而后问题来了:由于首先要去目标页面必须先去index.html,而后再从index.html页面跳转到其余页面去(由于目标页面没有js和css引用,单独跳转过去只有一些简单html标签)。因此开始的思路是先把参数传到index.html页面,而后再根据参数从index.html跳转到其余页面上。html
若是UIWebView加载的网页是远程页面(好比:http://xindongai.com/mobile/index.html)而不是本app里面的网页(www/index.html),那么一切好说,直接把参数拼到远程页面后面,而后加载远程index.html后,执行js脚本,跳到对应目标页面上。验证程序在运行和退出状态下解析通知后调到目标页面都没问题。java
----------------------- -------- --------- ------ ------- --------- ----android
另一种状况是加载本地html页面,而后问题来了:
ios
一、刚开始是想经过UIWebView执行脚本跳转(pushSkip是一个在公共js定义的方法,index.html页面引用了js):web
//解析推送通知 - (void)analysisPushMsg:(NSDictionary *)userInfo byType:(NSInteger)type{ // 取得 APNs 标准信息内容 NSDictionary *aps = [userInfo valueForKey:@"aps"]; NSString *content = [aps valueForKey:@"alert"]; //推送显示的内容 NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge数量 NSString *sound = [aps valueForKey:@"sound"]; //播放的声音 // 取得自定义字段内容 NSString *url = [userInfo valueForKey:@"url"]; //自定义参数,key是本身定义的: 好比:url=activate.html [self.viewController.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"pushSkip('%@');", url]]; //.... }
这种状况下,当程序正在前台运行状况下,没有问题,能够顺利执行;可是一旦程序在后台或者彻底退出后台状况下,一执行程序立刻就挂掉了!app
二、用另一种状况,当解析到推送通知后,重新加载UIWebView的网页,再在代理方法- (void)webViewDidFinishLoad:(UIWebView*)theWebView里面执行js脚本:框架
- (void)analysisPushMsg:(NSDictionary *)userInfo byType:(NSInteger)type{ // 取得 APNs 标准信息内容 NSDictionary *aps = [userInfo valueForKey:@"aps"]; NSString *content = [aps valueForKey:@"alert"]; //推送显示的内容 NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge数量 NSString *sound = [aps valueForKey:@"sound"]; //播放的声音 // 取得自定义字段内容 NSString *url = [userInfo valueForKey:@"url"]; //自定义参数,key是本身定义的: 好比:url=activate.html NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"www/index.html" withExtension:nil];
self.skipUrl = url;ide
NSURLRequest *request = [NSURLRequest requestWithURL:fileURL]; [self.viewController.webView loadRequest:request]; //..... }
在控制器的代理方法里面:
- (void)webViewDidFinishLoad:(UIWebView*)theWebView { // Black base color for background matches the native apps // theWebView.backgroundColor = [UIColor whiteColor]; // theWebView.scrollView.bounces = NO; // [(UIScrollView *)[[theWebView subviews] objectAtIndex:0] setBounces:NO]; // [super webViewDidFinishLoad:theWebView];
AppDelegate *del = (AppDelegate *)[UIApplication sharedApplication].delegate;
NSString *url = del.skipUrl;
if (url){
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"try{pushSkip('%@');}catch(e){}", url]]; } }
这样的话,程序在任何状态下收到推送通知也不会挂掉,可是页面一直执行pushSkip(url)方法,陷入了死循环。我想应该是UIWebView加载idnex.html页面后,还把”try{pushSkip('%@');}catch(e){}“代码添加到index.html页面上了,致使一直死循环一直执行。
尼玛,真是痛苦,百度谷歌搜不到本身想要的结果,难道你们没碰到过这个问题吗?你们碰到这种问题的时候是怎么解决的呢?本身的思路彷佛陷入了一个误区,不知道怎么走出来?
又改了改,暂时想出来一个临时办法来:
三、新建一个页面aaa.html,这个页面脱离Framework7框架,是个跳板页面,里面只有一个js方法,做为跳转到index.html页面之用。
1)解析通知后,给UIWebView空间加载aaa.html页面;
2)在控制器代理方法- (void)webViewDidFinishLoad:(UIWebView*)theWebView里调用aaa.html页面的js方法;
3)在aaa.html的js方法里面跳转到index.html页面上,而且把最后要跳转的目标参数也带过去;
4)在index.html页面引用的公共js里面根据参数跳转到目标页面上去
这样无论程序处于哪一种状态下,均可以解析推送通知而且调到对应目标页面上,代码:
aaa.html页面:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <script type="text/javascript"> function pushMsg(url){ window.location.href="home.html?url=" + url; } </script> </body> </html>
- (void)analysisPushMsg:(NSDictionary *)userInfo byType:(NSInteger)type{ // 取得 APNs 标准信息内容 NSDictionary *aps = [userInfo valueForKey:@"aps"]; NSString *content = [aps valueForKey:@"alert"]; //推送显示的内容 NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge数量 NSString *sound = [aps valueForKey:@"sound"]; //播放的声音 // 取得自定义字段内容 NSString *url = [userInfo valueForKey:@"url"]; //自定义参数,key是本身定义的 NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"www/aaa.html" withExtension:nil]; self.skipUrl = url; NSURLRequest *request = [NSURLRequest requestWithURL:fileURL]; [self.viewController.webView loadRequest:request]; //.... }
控制器代理方法:
- (void)webViewDidFinishLoad:(UIWebView*)theWebView { // Black base color for background matches the native apps // theWebView.backgroundColor = [UIColor whiteColor]; // theWebView.scrollView.bounces = NO; // [(UIScrollView *)[[theWebView subviews] objectAtIndex:0] setBounces:NO]; // [super webViewDidFinishLoad:theWebView]; AppDelegate *del = (AppDelegate *)[UIApplication sharedApplication].delegate;
NSString *url = del.skipUrl;
if (url){
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"try{pushMsg('%@');}catch(e){}", url]]; } }
--------------------------- ----- end --------------------------------
暂时用这个方法解决,总以为本身陷入了个误区,确定有更好的解决办法。但愿过路的哪位兄台大神指点一下,很是感谢!