UIWebView是iOS最常用的SDK之一,它有一个stringByEvaluatingJavaScriptFromString方法可以将javascript嵌入页面中,通过这个方法我们可以在iOS中与UIWebView中的网页元素交互。
使用stringByEvaluatingJavaScriptFromString方法,需要等UIWebView中的页面加载完成之后去调用。
Objective-C .mm代码 负责创建uiwebview
// Web view integration plug-in for Unity iOS.
#import <Foundation/Foundation.h>
extern UIViewController *UnityGetGLViewController(); // Root view controller of Unity screen.
#pragma mark Plug-in Functions
static UIWebView *webView;
extern "C" void _WebViewPluginInstall() {
// Add the web view onto the root view (but don't show).
UIViewController *rootViewController = UnityGetGLViewController();
webView = [[UIWebView alloc] initWithFrame:rootViewController.view.frame];
webView.hidden = YES;
[rootViewController.view addSubview:webView];
}
extern "C" void _WebViewPluginMakeTransparentBackground() {
[webView setBackgroundColor:[UIColor clearColor]];
[webView setOpaque:NO];
}
extern "C" void _WebViewPluginLoadUrl(const char* url, boolean isClearCache) {
if (isClearCache) {
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithUTF8String:url]]]];
}
extern "C" void _WebViewPluginSetVisibility(bool visibility) {
webView.hidden = visibility ? NO : YES;
}
extern "C" void _WebViewPluginSetMargins(int left, int top, int right, int bottom) {
UIViewController *rootViewController = UnityGetGLViewController();
CGRect frame = rootViewController.view.frame;
CGFloat scale = rootViewController.view.contentScaleFactor;
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
// Obtaining the current device orientation
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
// landscape
if (orientation) {
frame.size.width = screenSize.height - (left + right) / scale;
frame.size.height = screenSize.width - (top + bottom) / scale;
} else { // portrait
frame.size.width = screenSize.width - (left + right) / scale;
frame.size.height = screenSize.height - (top + bottom) / scale;
}
frame.origin.x += left / scale;
frame.origin.y += top / scale;
webView.frame = frame;
}
extern "C" char *_WebViewPluginPollMessage() {
// Try to retrieve a message from the message queue in JavaScript context.
NSString *message = [webView stringByEvaluatingJavaScriptFromString:@"unityWebMediatorInstance.pollMessage()"];
if (message && message.length > 0) {
NSLog(@"UnityWebViewPlugin: %@", message);
char* memory = static_cast<char*>(malloc(strlen(message.UTF8String) + 1));
if (memory) strcpy(memory, message.UTF8String);
return memory;
} else {
return NULL;
}
}
unity3d WebMediator.js代码 负责调用Objective-C代码
#pragma strict
// WebView-Unity mediator plugin script.
import System.Runtime.InteropServices;
// Message container class.
class WebMediatorMessage {
var path : String; // Message path
var args : Hashtable; // Argument table
function WebMediatorMessage(rawMessage : String) {
// Retrieve a path.
var split = rawMessage.Split("?"[0]);
path = split[0];
// Parse arguments.
args = new Hashtable();
if (split.Length > 1) {
for (var pair in split[1].Split("&"[0])) {
var elems = pair.Split("="[0]);
args[elems[0]] = WWW.UnEscapeURL(elems[1]);
}
}
}
}
private static var instance : WebMediator;
private static var isClearCache : boolean;
private var lastRequestedUrl : String;
private var loadRequest : boolean;
private var visibility : boolean;
private var leftMargin : int;
private var topMargin : int;
private var rightMargin : int;
private var bottomMargin : int;
// Install the plugin.
// Call this at least once before using the plugin.
static function Install() {
if (instance == null) {
var master = new GameObject("WebMediator");
DontDestroyOnLoad(master);
instance = master.AddComponent.<WebMediator>();
InstallPlatform();
}
}
// Set margins around the web view.
static function SetMargin(left : int, top: int, right : int, bottom : int) {
instance.leftMargin = left;
instance.topMargin = top;
instance.rightMargin = right;
instance.bottomMargin = bottom;
ApplyMarginsPlatform();
}
// Visibility functions.
static function Show() {
instance.visibility = true;
}
static function Hide() {
instance.visibility = false;
}
static function IsVisible() {
return instance.visibility;
}
static function SetClearCache()
{
isClearCache = true;
}
static function SetCache()
{
isClearCache = false;
}
// Load the page at the URL.
static function LoadUrl(url : String) {
instance.lastRequestedUrl = url;
instance.loadRequest = true;
}
function Update() {
UpdatePlatform();
instance.loadRequest = false;
}
#if UNITY_EDITOR
// Unity Editor implementation.
private static function InstallPlatform() { }
private static function UpdatePlatform() { }
private static function ApplyMarginsPlatform() { }
static function PollMessage() : WebMediatorMessage { return null; }
static function MakeTransparentWebViewBackground() { }
#elif UNITY_IPHONE
// iOS platform implementation.
@DllImportAttribute("__Internal") static private function _WebViewPluginInstall() {}
@DllImportAttribute("__Internal") static private function _WebViewPluginLoadUrl(url : String, isClearCache : boolean) {}
@DllImportAttribute("__Internal") static private function _WebViewPluginSetVisibility(visibility : boolean) {}
@DllImportAttribute("__Internal") static private function _WebViewPluginSetMargins(left : int, top : int, right : int, bottom : int) {}
@DllImportAttribute("__Internal") static private function _WebViewPluginPollMessage() : String {}
@DllImportAttribute("__Internal") static private function _WebViewPluginMakeTransparentBackground() {}
private static var viewVisibility : boolean;
private static function InstallPlatform() {
_WebViewPluginInstall();
}
private static function ApplyMarginsPlatform() {
_WebViewPluginSetMargins(instance.leftMargin, instance.topMargin, instance.rightMargin, instance.bottomMargin);
}
private static function UpdatePlatform() {
if (viewVisibility != instance.visibility) {
viewVisibility = instance.visibility;
_WebViewPluginSetVisibility(viewVisibility);
}
if (instance.loadRequest) {
instance.loadRequest = false;
_WebViewPluginLoadUrl(instance.lastRequestedUrl, isClearCache);
}
}
static function PollMessage() : WebMediatorMessage {
var message = _WebViewPluginPollMessage();
return message ? new WebMediatorMessage(message) : null;
}
static function MakeTransparentWebViewBackground()
{
_WebViewPluginMakeTransparentBackground();
}
#endif
#pragma strict
private var guiSkin : GUISkin;
private var redBoxPrefab : GameObject;
private var blueBoxPrefab : GameObject;
private var note : String;
// Show the web view (with margins) and load the index page.
private function ActivateWebView() {
WebMediator.LoadUrl(Application.dataPath +"/Raw" + "/web.html");
WebMediator.SetMargin(0, 0 , 0, 0);
WebMediator.Show();
}
// Hide the web view.
private function DeactivateWebView() {
WebMediator.Hide();
// Clear the state of the web view (by loading a blank page).
WebMediator.LoadUrl("about:blank");
}
// Process messages coming from the web view.
private function ProcessMessages() {
while (true) {
// Poll a message or break.
var message = WebMediator.PollMessage();
if (!message) break;
if (message.path == "/close") {
// "close" message.
DeactivateWebView();
Application.LoadLevel("Main");
}
}
}
function Start() {
WebMediator.Install();
ActivateWebView();
}
function Update() {
if (WebMediator.IsVisible()) {
ProcessMessages();
}
}
function OnGUI() {
var sw = Screen.width;
var sh = Screen.height;
if (note) GUI.Label(Rect(0, 0, sw, 0 * sh), note);
}
web.html代码 放到unity3d工程StreamingAssets文件夹中
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css" media="screen">
body {
background: white;
color: #222;
font-family: sans-serif;
font-size: 13pt;
}
a {
text-decoration: none;
color: #7070f0;
}
p { line-height: 180%; }
li { line-height: 180%; }
</style>
<script type="text/javascript">
function UnityWebMediator() {
this.android = navigator.userAgent.match(/Android/);
this.ios = navigator.userAgent.match(/iPhone/) || navigator.userAgent.match(/iPod/) || navigator.userAgent.match(/iPad/);
this.messageQueue = Array();
this.callback = function(path, args) {
var message = path;
if (args) {
var stack = [];
for (var key in args) {
stack.push(key + "=" + encodeURIComponent(args[key]));
}
message += "?" + stack.join("&");
}
if (this.android) {
UnityInterface.pushMessage(message);
} else if (this.ios) {
this.messageQueue.push(message);
} else {
console.log(message);
}
};
this.pollMessage = function() {
return this.messageQueue.shift();
}
unityWebMediatorInstance = this;
}
unity = new UnityWebMediator;
</script>
<title>Unity - WebView Integration Test Page</title>
<p><ul>
<li><a href="#" οnclick='unity.callback("/close")'>Close</a></li>
</ul></p>
</head>
<body>