UIWebView与JavaScript互相注入

一. iOS开发之UIWebView(首先复习一下UIView的使用,参考链接:http://www.cnblogs.com/zhuqil/archive/2011/07/28/2119923.html

    UIWebView是iOS sdk中一个最常用的控件。是内置的浏览器控件,我们可以用它来浏览网页、打开文档等等。这篇文章我将使用这个控件,做一个简易的浏览器。如下图:

UIWebView与JavaScript互相注入_第1张图片

我们创建一个Window-based Application程序命名为:UIWebViewDemo

UIWebView的loadRequest可以用来加载一个url地址,它需要一个NSURLRequest参数。我们定义一个方法用来加载url。在UIWebViewDemoViewController中定义下面方法:

复制代码
- (void)loadWebPageWithString:(NSString*)urlString
{
NSURL *url =[NSURL URLWithString:urlString];
NSLog(urlString);
NSURLRequest *request =[NSURLRequest requestWithURL:url];
[webView loadRequest:request];
}
复制代码

在界面上放置3个控件,一个textfield、一个button、一个uiwebview,布局如下:

UIWebView与JavaScript互相注入_第2张图片

在代码中定义相关的控件:webView用于展示网页、textField用于地址栏、activityIndicatorView用于加载的动画、buttonPress用于按钮的点击事件。

@interface  UIWebViewDemoViewController :UIViewController {   
     IBOutlet  UIWebView *webView;
     IBOutlet  UITextField *textField;
     UIActivityIndicatorView *activityIndicatorView;
     
}
- ( IBAction )buttonPress:( id ) sender;
- ( void )loadWebPageWithString:( NSString *)urlString;
@end

使用IB关联他们。

设置UIWebView,初始化UIActivityIndicatorView:

复制代码
- (void)viewDidLoad
{
[super viewDidLoad];
webView.scalesPageToFit =YES;
webView.delegate =self;
activityIndicatorView = [[UIActivityIndicatorView alloc]
initWithFrame : CGRectMake(0.0f, 0.0f, 32.0f, 32.0f)] ;
[activityIndicatorView setCenter: self.view.center] ;
[activityIndicatorView setActivityIndicatorViewStyle: UIActivityIndicatorViewStyleWhite] ;
[self.view addSubview : activityIndicatorView] ;
[self buttonPress:nil];
// Do any additional setup after loading the view from its nib.
}
复制代码

UIWebView主要有下面几个委托方法:

1、- (void)webViewDidStartLoad:(UIWebView *)webView;开始加载的时候执行该方法。
2、- (void)webViewDidFinishLoad:(UIWebView *)webView;加载完成的时候执行该方法。
3、- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;加载出错的时候执行该方法。

我们可以将activityIndicatorView放置到前面两个委托方法中。

复制代码
- (void)webViewDidStartLoad:(UIWebView *)webView
{
[activityIndicatorView startAnimating] ;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
[activityIndicatorView stopAnimating];
}
复制代码

buttonPress方法很简单,调用我们开始定义好的loadWebPageWithString方法就行了:

- ( IBAction )buttonPress:( id ) sender
{
     [textField resignFirstResponder];
     [ self  loadWebPageWithString:textField.text];
     
}

当请求页面出现错误的时候,我们给予提示:

- ( void )webView:(UIWebView *)webView didFailLoadWithError:( NSError  *)error
{
     UIAlertView *alterview = [[UIAlertView alloc] initWithTitle:@ ""  message:[error localizedDescription]  delegate: nil  cancelButtonTitle: nil otherButtonTitles:@ "OK" , nil ];
     [alterview show];
     [alterview release];
}

总结每一种委托代理方法:

下面每个委托方法的第一个参数都是指向一个UIwebview的指针,因此你可以将一个委托用于多个网页视图。

  1. -(BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*) reuqest navigationType:(UIWebViewNavigationType)navigationType;//当网页视图被指示载入内容而得到通知。应当返回YES,这样会进行加载。通过导航类型参数可以得到请求发起的原因,可以是以下任意值:   
  2. UIWebViewNavigationTypeLinkClicked   
  3. UIWebViewNavigationTypeFormSubmitted   
  4. UIWebViewNavigationTypeBackForward   
  5. UIWebViewNavigationTypeReload   
  6. UIWebViewNavigationTypeFormResubmitted   
  7. UIWebViewNavigationTypeOther  
-( void)webViewDidStartLoad:(UIWebView*)webView ;//当网页视图已经开始加载一个请求后,得到通知。  
-( void)webViewDidFinishLoad:(UIWebView*)webView ;//当网页视图结束加载一个请求之后,得到通知。  
  -( void)webView:(UIWebView*)webView  DidFailLoadWithError:(NSError*)error;//当在请求加载中发生错误时,得到通知。会提供一个NSSError对象,以标识所发生错误类型。
 
二  IOS中UIWebView和JavaScript交互
具体参考链接: http://blog.2jun.net/2012/11/02/webviewandjs/
      当程序中使用到UIWebView控件的时候,难免会遇到需要与页面进行交互的情况。这种情况在android平台下比较容易处理,android平台下WebView控件的addJavascriptInterface()方法可以很轻松的完成交互,而IOS上就稍复杂一些。

页面与客户端的交互是通过JS来完成的,通常情况下与JS的交互可以分为两种:客户端传递给JS一些数据和JS向客户端请求一些本地操作。下面分别对这两种情况进行处理。

JS向客户端请求本地操作

这里的实现主要是通过对UIWebView的delegate方法

-(BOOL)webView: shouldStartLoadWithRequest: navigationType: 

进行处理来实现的。通过在得到webview所要加载的url来判断是否是需要处理的条件即可。 下面举个具体例子来完成这个操作。如果需要通过JS来通知客户端需要调用用户登录的相关操作。首先跟服务端定好相关的协议串。提供一个方案,协议串的格式如下,

XX::command:param1=value1¶m2=value2…
//XX是协议名,command是命令名,后面是参数表(0或多个,command后的冒号不可省略)    

那么对应本次登录的请求串就是

test::login:   

那么页面上的相应JS的写法就是:

function sendLoginCommand(){  
    var url="test::login:";  
    document.location = url;  
} 

对应IOS端的代码是:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ ~

    // 处理事件
    NSString *requestString = [[request URL] absoluteString];
    NSArray *components = [requestString componentsSeparatedByString:@"::"];
    if (components != nil && [components count] > 0) {
        NSString *pocotol = [components objectAtIndex:0];
        if ([pocotol isEqualToString:@"test"]) {
            NSString *commandStr = [components objectAtIndex:1];
            NSArray *commandArray = [commandStr componentsSeparatedByString:@":"];
            if (commandArray != nil && [commandArray count] > 0) {
                NSString *command = [commandArray objectAtIndex:0];
                if ([command isEqualToString:@"login"]) {
                    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"消息" message:@"网页发出了登录请求" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
                    [alert show];
                }
            }
            return NO;
        }
    }


    return YES;
}   

客户端向JS传递数据

客户端向JS传递数据,通过插入JS方法来实现,UIWebView的方法

- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script

可以完成这项功能。继续以实际例子来说明,若要通过客户端来实现向JS传递一个用户名参数的功能,可以由客户端向页面中插入一个 getUsername()的JS方法。具体实现代码:

NSString *js = [NSString stringWithFormat:@"function getUsername(){ return '%@'; }", @"bill"];
[webView stringByEvaluatingJavaScriptFromString:js];

然后JS在需要得到用户名的地方只要调用window.getUsername()即可。

另外,由于android的addJavascriptInterface()方法中有两个参数,若第二个参数传入字符串,比如test,则JS的调用需要更改为 window.test.getUsername()。为了使IOS与android的调用保持一致,则需要对js进行修改,具体修改形式:

#define JsStr @"var test = {}; (function initialize() { test.getUsername = function () { return '%@';};})(); "
NSString *js = [NSString stringWithFormat:JsSt, @"bill"];
[webView stringByEvaluatingJavaScriptFromString:js];

这样在IOS环境下JS也可以通过调用 window.test.getUsername()来获取用户名了。

 

转载于:https://www.cnblogs.com/techWang-iOS/p/4942692.html

你可能感兴趣的:(UIWebView与JavaScript互相注入)