IOS UIWebView与JavaScript交互实现Web App

上一篇文章讲到了Android WebView与JavaScript的交互问题,如今来说一下IOS的UIWebView与JavaScript的交互问题。和Android的相比,IOS的会略显笨拙一些不大友好,然而也算是在未引用第三方框架的基础上完成了交互的问题。OK,如今开始吧。javascript

1.首先在IOSA->Application下选择Single View Application建立一个IOS应用,命名为JSInteraction,而后我删去了Info.plist文件里Main storyboard file base name字段,选择加载ViewController的View。html

 

1.修改AppDelegate.m的didFinishLaunchingWithOptions并添加以下代码。java

[objc] view plaincopyweb

  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  json

  2.     // Override point for customization after application launch.  app

  3.       

  4.     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];  框架

  5.     [self.window makeKeyAndVisible];  ide

  6.       

  7.     ViewController * viewController = [[ViewController alloc] init];  this

  8.     [self.window setRootViewController:viewController];  atom

  9.       

  10.     return YES;  

  11. }  

2.修改类ViewController,添加一个WebView并添加与JavaScript交互的功能。

[objc] view plaincopy

  1. //  

  2. //  ViewController.h  

  3. //  JSInteraction  

  4. //  

  5. //  Created by Winter on 15/8/12.  

  6. //  Copyright (c) 2015年 YLD. All rights reserved.  

  7. //  

  8.   

  9. #import <UIKit/UIKit.h>  

  10.   

  11. @interface  ViewController : UIViewController<UIWebViewDelegate> {  

  12.     UINavigationItem *item_;  

  13. }  

  14.   

  15. @property (nonatomicstrongUIWebView *webView;  

  16.   

  17. @end   


在WebView的shouldStartLoadWithRequest处理JS的请求根据JS的传入的Url来判断JS所需的操做。在这里面我主要提供了一个弹出对话框的接口,当JS传入的URL是以jsinteraction:showAleart开头时则调用ViewController里的showAlert方法,而JS须要从App获取数据时,则须要WebView调用stringByEvaluatingJavaScriptFromString方法并传入后台JS提供的方法并传入参数来实现传递数据给后台的JS。有点绕,且看看实现方式。

[objc] view plaincopy

  1. //  

  2. //  ViewController.m  

  3. //  JSInteraction  

  4. //  

  5. //  Created by Winter on 15/8/12.  

  6. //  Copyright (c) 2015年 YLD. All rights reserved.  

  7. //  

  8.   

  9. #import "ViewController.h"  

  10.   

  11. @interface  ViewController ()  

  12.   

  13. @end   

  14.   

  15. @implementation ViewController  

  16.   

  17. - (void)viewDidLoad {  

  18.     [super viewDidLoad];  

  19.       

  20.     UINavigationBar *bar = [[UINavigationBar alloc] initWithFrame:CGRectMake(020self.view.bounds.size.width30.0f)];  

  21.     bar.backgroundColor = [UIColor clearColor];  

  22.     item_ = [[UINavigationItem alloc] initWithTitle:@""];  

  23.     [bar pushNavigationItem:item_ animated:YES];  

  24.     [self.view addSubview:bar];  

  25.       

  26.     self.view.backgroundColor = [UIColor colorWithRed:0.0f green:20.0f blue:255.0f alpha:1.0f];  

  27.     self.webView = [[UIWebView alloc] initWithFrame:CGRectMake(10.0f60.0fself.view.bounds.size.width-20self.view.bounds.size.height - 80.0f)];  

  28.     self.webView.delegate = self;  

  29.     [self.view addSubview:self.webView];  

  30.       

  31.       

  32.     [self initializeWebView];  

  33.       

  34.     // Do any additional setup after loading the view, typically from a nib.  

  35. }  

  36.   

  37. - (void)didReceiveMemoryWarning {  

  38.     [super didReceiveMemoryWarning];  

  39.     // Dispose of any resources that can be recreated.  

  40. }  

  41.   

  42. /* 

  43.  * Load local html file 

  44.  */  

  45. - (void)initializeWebView {  

  46.     NSString *filePath = [[NSBundle mainBundle] pathForResource:@"LoginJs/login" ofType:@"html"];  

  47.       

  48.     [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]]];  

  49. }  

  50.   

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

  52.     NSString *requestString = [[request URL] absoluteString];  

  53.     NSArray *headers = [requestString componentsSeparatedByString:@":"];  

  54.   

  55.     if([headers count]>1) {  

  56.         NSString *appAction = [(NSString *)[headers objectAtIndex:0] lowercaseString];  

  57.         NSString *funtionName =(NSString*)[headers objectAtIndex:1];  

  58.           

  59.         if([appAction isEqualToString:@"jsinteraction"]) {  

  60.             if([funtionName isEqualToString:@"showAleart"] && [headers count] > 2){  

  61.                 NSString* message = (NSString*)[headers objectAtIndex:2];  

  62.               

  63.                 [self showAleart:message];  

  64.             }  

  65.           

  66.             return NO;  

  67.         } else if([appAction isEqualToString:@"executescript"]){  

  68.             if([funtionName isEqualToString:@"loginObj.setLoginInfo"]){  

  69.                 NSString *loginInfo = @"'{\"Username\":\"YLD\",\"Password\":\"111\"}'";  

  70.                 NSString *execute = [NSString stringWithFormat:@"loginObj.setLoginInfo(%@)", loginInfo];  

  71.               

  72.                 [webView stringByEvaluatingJavaScriptFromString:execute];  

  73.             }  

  74.             return NO;  

  75.         }  

  76.     }  

  77.       

  78.     return YES;  

  79. }  

  80.   

  81. - (void)webViewDidFinishLoad:(UIWebView *)webView {  

  82.     item_.title = [self.webView stringByEvaluatingJavaScriptFromString:@"document.title"];  

  83. }  

  84.   

  85. /** 

  86.  * 弹出消息对话框 

  87.  */  

  88. - (void)showAleart: (NSString *) message {  

  89.     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Warning"  

  90.                                                         message:message  

  91.                                                        delegate:self  

  92.                                               cancelButtonTitle:@"OK"  

  93.                                               otherButtonTitles:nil , nil nil];  

  94.       

  95.     [alertView show];  

  96. }  

  97.   

  98. @end  


3.IOS端已经完成,根据目前的实现,JS端须要请求的URL须是如下两种格式才能实现与IOS的交互。

1)jsinteraction:showAleart:xxxx

2)  executescript:loginObj.setLoginInfo:xxxx

4.下面实现web端的功能,新建一个文件夹命名为LoginJs,在改文件夹下添加两个文件,login.html和login.js。login.html有两个文本输入框咱们会在程序启动时让IOS端为其注入相应的数据,再有一个登陆按钮,点击按钮则会调用IOS端ViewController的showAlert方法,弹出对话框。

[html] view plaincopy

  1. <!DOCTYPE html>  

  2. <html lang="en">  

  3. <head>  

  4.     <meta charset="UTF-8">  

  5.     <title id="title">Login</title>  

  6.     <script type="text/javascript" src="login.js"></script>  

  7. </head>  

  8.   

  9. <body style="background:lightblue">  

  10.     <div style="margin-top: 20px;margin-left: 20px">  

  11.         <div>  

  12.             <label>Username:</label>  

  13.             <input id="txtUsername" type="text" style="margin-left: 20px"/>  

  14.         </div>  

  15.         <div style="margin-top: 20px">  

  16.             <label>Password:</label>  

  17.             <input id="txtPassword" type="text" style="margin-left: 20px"/>  

  18.         </div>  

  19.         <div style="margin-top: 20px;margin-left: 160px">  

  20.             <button onclick="loginObj.login()" style="width:100px">Login</button>  

  21.         </div>  

  22.     </div>  

  23. </body>  

  24. </html>  

在login.js中实现相应的方法,在页面加载完成时会调用请求,请求IOS端的数据。实现与IOS端的交互主要是依靠更改window的location。

[javascript] view plaincopy

  1. "user strict"  

  2.   

  3. var Login = (function(){  

  4.     function Login(){  

  5.   

  6.     }  

  7.   

  8.     Login.prototype.login = function(){  

  9.         this.appRequest("JSInteraction""showAleart""Start...");  

  10.     }  

  11.   

  12.     /** 

  13.      * 设置登陆信息 

  14.      * @logininfoJson json参数字符串 

  15.      */  

  16.     Login.prototype.setLoginInfo = function(logininfoJson){  

  17.         //解析json字符串  

  18.         var logininfo = eval("("+logininfoJson+")");  

  19.   

  20.         document.getElementById("txtUsername").value = logininfo.Username;  

  21.         document.getElementById("txtPassword").value = logininfo.Password;  

  22.     }  

  23.   

  24.     Login.prototype.appRequest = function(appAction, functionName, parameters){  

  25.         var requestCommand = appAction + ":" + functionName + ":" + parameters;  

  26.   

  27.         window.location = requestCommand;  

  28.     }  

  29.                

  30.     return Login;  

  31. })();  

  32.   

  33. var loginObj = new Login();  

  34.   

  35. window.onload=function(){  

  36.     loginObj.appRequest("executeScript""loginObj.setLoginInfo""");  

  37. }  


5.接下来咱们将web的LoginJs添加至IOS的JSInteraction工程中



添加完成后,工程结构以下图


6.运行App,效果以下所示。


点击Login按钮



源代码下载页:http://download.csdn.net/detail/leyyang/9000543