先說說項目狀況:使用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 --------------------------------
暫時用這個方法解決,總以爲本身陷入了個誤區,確定有更好的解決辦法。但願過路的哪位兄臺大神指點一下,很是感謝!