上一篇文章講到了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
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { json
// Override point for customization after application launch. app
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 框架
[self.window makeKeyAndVisible]; ide
ViewController * viewController = [[ViewController alloc] init]; this
[self.window setRootViewController:viewController]; atom
return YES;
}
2.修改類ViewController,添加一個WebView並添加與JavaScript交互的功能。
[objc] view plaincopy
//
// ViewController.h
// JSInteraction
//
// Created by Winter on 15/8/12.
// Copyright (c) 2015年 YLD. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController<UIWebViewDelegate> {
UINavigationItem *item_;
}
@property (nonatomic, strong) UIWebView *webView;
在WebView的shouldStartLoadWithRequest處理JS的請求根據JS的傳入的Url來判斷JS所需的操做。在這裏面我主要提供了一個彈出對話框的接口,當JS傳入的URL是以jsinteraction:showAleart開頭時則調用ViewController裏的showAlert方法,而JS須要從App獲取數據時,則須要WebView調用stringByEvaluatingJavaScriptFromString方法並傳入後臺JS提供的方法並傳入參數來實現傳遞數據給後臺的JS。有點繞,且看看實現方式。
[objc] view plaincopy
//
// ViewController.m
// JSInteraction
//
// Created by Winter on 15/8/12.
// Copyright (c) 2015年 YLD. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationBar *bar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 20, self.view.bounds.size.width, 30.0f)];
bar.backgroundColor = [UIColor clearColor];
item_ = [[UINavigationItem alloc] initWithTitle:@""];
[bar pushNavigationItem:item_ animated:YES];
[self.view addSubview:bar];
self.view.backgroundColor = [UIColor colorWithRed:0.0f green:20.0f blue:255.0f alpha:1.0f];
self.webView = [[UIWebView alloc] initWithFrame:CGRectMake(10.0f, 60.0f, self.view.bounds.size.width-20, self.view.bounds.size.height - 80.0f)];
self.webView.delegate = self;
[self.view addSubview:self.webView];
[self initializeWebView];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
* Load local html file
*/
- (void)initializeWebView {
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"LoginJs/login" ofType:@"html"];
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]]];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *requestString = [[request URL] absoluteString];
NSArray *headers = [requestString componentsSeparatedByString:@":"];
if([headers count]>1) {
NSString *appAction = [(NSString *)[headers objectAtIndex:0] lowercaseString];
NSString *funtionName =(NSString*)[headers objectAtIndex:1];
if([appAction isEqualToString:@"jsinteraction"]) {
if([funtionName isEqualToString:@"showAleart"] && [headers count] > 2){
NSString* message = (NSString*)[headers objectAtIndex:2];
[self showAleart:message];
}
return NO;
} else if([appAction isEqualToString:@"executescript"]){
if([funtionName isEqualToString:@"loginObj.setLoginInfo"]){
NSString *loginInfo = @"'{\"Username\":\"YLD\",\"Password\":\"111\"}'";
NSString *execute = [NSString stringWithFormat:@"loginObj.setLoginInfo(%@)", loginInfo];
[webView stringByEvaluatingJavaScriptFromString:execute];
}
return NO;
}
}
return YES;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
item_.title = [self.webView stringByEvaluatingJavaScriptFromString:@"document.title"];
}
/**
* 彈出消息對話框
*/
- (void)showAleart: (NSString *) message {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Warning"
message:message
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil , nil nil];
[alertView show];
}
@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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title id="title">Login</title>
<script type="text/javascript" src="login.js"></script>
</head>
<body style="background:lightblue">
<div style="margin-top: 20px;margin-left: 20px">
<div>
<label>Username:</label>
<input id="txtUsername" type="text" style="margin-left: 20px"/>
</div>
<div style="margin-top: 20px">
<label>Password:</label>
<input id="txtPassword" type="text" style="margin-left: 20px"/>
</div>
<div style="margin-top: 20px;margin-left: 160px">
<button onclick="loginObj.login()" style="width:100px">Login</button>
</div>
</div>
</body>
</html>
在login.js中實現相應的方法,在頁面加載完成時會調用請求,請求IOS端的數據。實現與IOS端的交互主要是依靠更改window的location。
[javascript] view plaincopy
"user strict"
var Login = (function(){
function Login(){
}
Login.prototype.login = function(){
this.appRequest("JSInteraction", "showAleart", "Start...");
}
/**
* 設置登陸信息
* @logininfoJson json參數字符串
*/
Login.prototype.setLoginInfo = function(logininfoJson){
//解析json字符串
var logininfo = eval("("+logininfoJson+")");
document.getElementById("txtUsername").value = logininfo.Username;
document.getElementById("txtPassword").value = logininfo.Password;
}
Login.prototype.appRequest = function(appAction, functionName, parameters){
var requestCommand = appAction + ":" + functionName + ":" + parameters;
window.location = requestCommand;
}
return Login;
})();
var loginObj = new Login();
window.onload=function(){
loginObj.appRequest("executeScript", "loginObj.setLoginInfo", "");
}
5.接下來咱們將web的LoginJs添加至IOS的JSInteraction工程中
添加完成後,工程結構以下圖
6.運行App,效果以下所示。
點擊Login按鈕
源代碼下載頁:http://download.csdn.net/detail/leyyang/9000543