unity3d for iOS Objective-C与JavaScript的交互

来源:互联网 发布:linux红帽子系统 编辑:程序博客网 时间:2024/04/29 21:41

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 Functionsstatic 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


unity3d webviewInterface.js代码 负责给WebMediator.js传递属性值

#pragma strictprivate 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="#" onclick='unity.callback("/close")'>Close</a></li>  </ul></p></head><body>



原创粉丝点击