unity3d for iOS Objective-C与JavaScript的交互

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


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

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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值