你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS - OC和網頁JS的交互

iOS - OC和網頁JS的交互

編輯:IOS開發綜合

我們知道,在iOS開發過程中,有時候會用webview加載一張網頁,網頁上有一些按鈕或者其他的一些鏈接,要使這些按鈕有實際的作用,1??要麼就是網頁部分在HTML文件內部自己實現方法,2??要麼就是通過OC和網頁的交互,在本app內OC實現點擊網頁的按鈕,可以觸發自己OC寫的方法。

下面我講兩種常用的方法。

第一種是遵守webview的協議,通過實現協議方法截取網絡請求,通過這個截取到的網絡請求進行解析,然後實現自己的方法。

第二種方法是用了一個叫WebViewJavascriptBridge 的第三方庫進行橋接,這個方法就比較強大了,它既可以在oc部分寫實現代碼,也可以在網頁JS部分寫實現代碼。

這個庫的下載地址為:(裡面有demo,可以學著看看)

github上的下載地址

好了現在先上圖,說明一下,現在的網頁上的按鈕和我本app內部,需要做哪些交互。
網頁的圖片
此頁面為webview加載的圖片,要做的便是分別點擊這5個按鈕(Facebook分享、QQ分享、微信分享、短信分享、郵件分享)在app內部得到響應。分享集成部分再次就不多說了,謝謝。

方法一:webview協議截取網絡請求

app部分(OC部分)
1.設置webview 加載網頁
2.實現協議方法
3.實現網絡截取後相應的方法
- (void)viewDidLoad {
    [super viewDidLoad];


    UIWebView * webview = [[UIWebView alloc]initWithFrame:self.view.bounds];
    webview.delegate = self;
    //http://127.0.0.1/WEB/initHtml.html  是我放在自己服務器的網頁文件
    [webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://127.0.0.1/WEB/initHtml.html"]]];
    [self.view addSubview:webview];
}

#pragma mark ---webview協議方法
#pragma mark ---攔截web網絡請求
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    //獲取自己的網絡請求的網址字符串
    NSString *url = request.URL.absoluteString;
    //自己定義的協議前綴  網頁部分一會兒也是要設置成這個協議!
    NSString *scheme = @"xmg://";
    //打印出自己獲取的網絡請求的網址是什麼
    NSLog(@"~~~~~ %@",url);
    //解析網址前綴是否為@"xmg://"
    if ([url hasPrefix:scheme])
    {
        //截出方法名
        NSString *actionName = [url substringFromIndex:scheme.length];、
        //動態方法選擇器 比如我獲取的網址是xmg://mailShare  則會執行mailShare這個方法
        [self performSelector:NSSelectorFromString(actionName) withObject:nil];
        //不加載這個網絡請求的頁面
        return NO;
    }
    //YES:加載這個網絡請求的頁面
    return YES;
}

-(void)mailShare{
   NSLog(@"1shareMail");
}

-(void)facebookShare{
    NSLog(@"facebookShare");
}
網頁部分
在圖片連接處 修改:
修改連接標簽的目標屬性vc+88rWlo6E8L3A+DQo8cD48c3Ryb25nPre9t6i2/qO6wPvTw1dlYlZpZXdKYXZhc2NyaXB0QnJpZGdltdrI/be9v+K9+NDQSlO6zU9DtcTHxb3TPC9zdHJvbmc+PC9wPg0KPHA+MS5hcHCyv7fWo6hPQ7K/t9ajqTxiciAvPg0KotnU2tDCv6q1xLmks8zS/dPDvrLMrL/iPGJyIC8+DQpDb3JlR3JhcGhpY3MuZnJhbWV3b3JrPGJyIC8+DQpGb3VuZGF0aW9uLmZyYW1ld29yazxiciAvPg0KVUlLaXQuZnJhbWV3b3JrPGJyIC8+DQpXZWJLaXQuZnJhbWV3b3JrPGJyIC8+DQqi2rW8yOtXZWJWaWV3SmF2YXNjcmlwdEJyaWRnZbXayP23vb/iPGJyIC8+DQqi29TayrnTw7XE0rPD5rzTyOvNt87EvP5XZWJWaWV3SmF2YXNjcmlwdEJyaWRnZS5oINXiuPbOxLz+xNqw/LqswcvG5Mv7zsS8/qOsy/nS1Na708O1vMjr1eLSu7j2PGJyIC8+DQqi3L+qyrzQtLT6wus8L3A+DQo8cHJlIGNsYXNzPQ=="brush:java;"> #import "ViewController.h" #import "WebViewJavascriptBridge.h" @interface ViewController () //聲明`WebViewJavascriptBridge`對象為屬性 @property (nonatomic,strong) WebViewJavascriptBridge * bridge; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } -(void)viewWillAppear:(BOOL)animated{ if (_bridge) { return; } //用UIWebView加載web網頁 UIWebView * webview = [[UIWebView alloc]initWithFrame:self.view.bounds]; webview.delegate = self; [self.view addSubview:webview]; //設置能夠進行橋接 [WebViewJavascriptBridge enableLogging]; _bridge = [WebViewJavascriptBridge bridgeForWebView:webview]; [_bridge registerHandler:@"facebookObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@" ======FacebookObjcCallback ========= %@", data); //傳話給網頁說已經接收到 responseCallback(@"facebookObjcCallback回復網頁,已經收到消息"); // }]; [_bridge registerHandler:@"QQShareObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@" ======QQShareObjcCallback ========= %@", data); //傳話給網頁說已經接收到 responseCallback(@"QQShareObjcCallback回復網頁,已經收到消息"); }]; [_bridge registerHandler:@"WXShareObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@" ======WXShareObjcCallback ========= %@", data); //傳話給網頁說已經接收到 responseCallback(@"WXShareObjcCallback回復網頁,已經收到消息"); // }]; [_bridge registerHandler:@"MessageShareObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@" ======MessageShareObjcCallback ========= %@", data); //傳話給網頁說已經接收到 responseCallback(@"MessageShareObjcCallback回復網頁,已經收到消息"); // }]; [_bridge registerHandler:@"MailShareObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@" ======MailShareObjcCallback ========= %@", data); //傳話給網頁說已經接收到 responseCallback(@"MailShareObjcCallback回復網頁,已經收到消息"); // }]; // oc傳話給JS(網頁執行) 網頁部分會執行以下代碼: /* bridge.registerHandler('testJavascriptHandler', function(data, responseCallback) { log('ObjC called testJavascriptHandler with', data) var responseData = { 'Javascript Says':'Right back atcha!' } log('JS responding with', responseData) responseCallback(responseData) }) 接收 */ //網頁接收OC的方法句柄名叫testJavascriptHandler 此時OC給JS傳的數據是@{ @"foo":@"before ready" } [_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }]; // 自定義按鈕 此處沒用,需要的可以自己打開使用 // [self renderButtons:webView]; //當你沒有把網頁放入服務器的話,可以把網頁放在本地工程,這個時候就要執行以下的方法,用NSBoundle加載本地文件 // [self loadExamplePage:webview]; } //自定義按鈕 - (void)renderButtons:(UIWebView*)webView { UIFont* font = [UIFont fontWithName:@"HelveticaNeue" size:12.0]; UIButton *callbackButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [callbackButton setTitle:@"呼叫JS的Handle" forState:UIControlStateNormal]; [callbackButton addTarget:self action:@selector(callHandler:) forControlEvents:UIControlEventTouchUpInside]; [self.view insertSubview:callbackButton aboveSubview:webView]; callbackButton.frame = CGRectMake(10, 400, 100, 35); callbackButton.titleLabel.font = font; } //可以通過自定義按鈕實現方法,動態和JS進行交互 //注:本代碼中沒有寫按鈕去實現此方法,需要的同學可以自己去定義按鈕實現此方法 - (void)callHandler:(id)sender { id data = @{ @"OC第一次發信息給JS": @"Hi there, JS,I am OC !" }; // testJavascriptHandler是JS部分接收OC傳送消息的方法句柄 // data 是OC給JS傳的數據 // response是JS接收到消息後給OC傳的數據 [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { NSLog(@"JS收到消息後,回復給OC的消息為: %@", response); }]; } //加載本地網頁 //本代碼中的網頁是從服務器獲取,不是放在本地,放在本地的同學,可以用以下的方法加載 - (void)loadExamplePage:(UIWebView*)webView { NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"codetest" ofType:@"html"]; NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; NSURL *baseURL = [NSURL fileURLWithPath:htmlPath]; [webView loadHTMLString:appHtml baseURL:baseURL]; }

2.網頁部分(JS部分)
①在script標簽內寫橋接方法
②在a標簽內記得表面id唯一標示,以便script能夠獲取此標簽元素

<script>
        window.onerror = function(err) {
            log('window.onerror: ' + err)
        }

    function setupWebViewJavascriptBridge(callback) {
        if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
        if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
        window.WVJBCallbacks = [callback];
        var WVJBIframe = document.createElement('iframe');
        WVJBIframe.style.display = 'none';
        WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
        document.documentElement.appendChild(WVJBIframe);
        setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
    }

    setupWebViewJavascriptBridge(function(bridge) {
                                 // JS注冊接收消息的部分 名字叫testJavascriptHandler 
                                 // function是接收消息後做的處理
                                 bridge.registerHandler('testJavascriptHandler', function(data, responseCallback) {

                                                        var responseData = { 'Javascript Says':'Right back atcha!'};

   //給OC的消息回執
                                                                            responseCallback(responseData);
                                                        });

                                 document.body.appendChild(document.createElement('br'));

                                 //facebook連接出發方法
                                 var facebookButton = document.getElementById('Facebook');
                                 facebookButton.onclick = function(e) {
                                        e.preventDefault();
                                        
                                        //橋接呼叫OC句柄:facebookObjcCallback  
                                        //並傳送數據{'foo': 'bar'}過去
                                        bridge.callHandler('facebookObjcCallback', {'foo': 'bar'}, function(response) {
                                        //JS接收到OC的消息回執
                                                    
                                                           });
                                 };


                                 var QQShareBtn = document.getElementById('QQShare')
                                 QQShareBtn.onclick = function(a){
                                 a.preventDefault();
                                 bridge.callHandler('QQShareObjcCallback',{'QQ':'share'},function(response){

                                                    });

                                 };

                                 var wxShareBtn = document.getElementById('WXShare')
                                 wxShareBtn.onclick = function(a){
                                 a.preventDefault();
                                 bridge.callHandler('WXShareObjcCallback',{'WX':'share'},function(response){

                                                    });

                                 };


                                 var messageShareBtn = document.getElementById('MessageShare')
                                 messageShareBtn.onclick = function(a){
                                 a.preventDefault();
                                 bridge.callHandler('MessageShareObjcCallback',{'Message':'share'},function(response){

                                                    });

                                 };


                                 var mailShareBtn = document.getElementById('MailShare')
                                 mailShareBtn.onclick = function(a){
                                 a.preventDefault();
                                 bridge.callHandler('MailShareObjcCallback',{'Mail':'share'},function(response){

                                                    });

                                 };

                                 });


        </script>

 
        
            
                來分享給好友!            
            
                

總結:
1??利用橋接的話,就可以進行雙方的通信,JS部分可以做回執處理,OC部分也可以做回執處理。
注意點就是JS的Handle要命名好,OC部分的Handle也要命名好,不要搞混淆。
2??而利用webview的協議方法的話,好處是只要雙方規定了某一個協議,比如xmg://或其他,
單方面在OC處的webview協議方法解決,解析截取到的網絡請求,這種方法實現起來比較快捷,
壞處就是,JS得不到回執啦(但好像也不是什麼壞處)~

大家根據自己的需求選擇自己適合的方法吧,謝謝大家能夠看完!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved