diff --git a/.gitignore b/.gitignore
index c5a0afab..baff6671 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,6 @@ Temp
*.sln
*.pidb
*.userprefs
+**/*.xcodeproj/*
+!**/*.xcodeproj/project.pbxproj
+!**/*.xcworkspace/contents.xcworkspacedata
diff --git a/README.md b/README.md
index ff27081c..f89d1723 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,8 @@ below:
### OS X (Editor)
+#### App Transport Security
+
Since Unity 5.3.0, Unity.app is built with ATS (App Transport
Security) enabled and non-secured connection (HTTP) is not
permitted. If you want to open `http://foo/bar.html` with this plugin
@@ -50,11 +52,19 @@ or invoke the following from your terminal,
/usr/libexec/PlistBuddy -c "Add NSAppTransportSecurity:NSAllowsArbitraryLoads bool true" /Applications/Unity/Unity.app/Contents/Info.plist
```
-#### References
+##### References
* https://github.com/gree/unity-webview/issues/64
* https://onevcat.zendesk.com/hc/en-us/articles/215527307-I-cannot-open-the-web-page-in-Unity-Editor-
+#### WebViewSeparated.bundle
+
+WebViewSeparated.bundle is a variation of WebView.bundle. It is based
+on https://github.com/gree/unity-webview/pull/161 . As noted in the
+pull-request, it shows a separate window and allows a developer to
+utilize the Safari debugger. For enabling it, please define
+`WEBVIEW_SEPARATED`.
+
### iOS
The implementation now supports WKWebView but it is disabled by
diff --git a/dist/unity-webview.unitypackage b/dist/unity-webview.unitypackage
index 30b6379f..1c07d011 100644
Binary files a/dist/unity-webview.unitypackage and b/dist/unity-webview.unitypackage differ
diff --git a/dist/unity-webview.zip b/dist/unity-webview.zip
index 9073869b..008e1372 100644
Binary files a/dist/unity-webview.zip and b/dist/unity-webview.zip differ
diff --git a/plugins/Mac/Resources/Info-WebViewSeparated.plist b/plugins/Mac/Resources/Info-WebViewSeparated.plist
new file mode 100644
index 00000000..e89822fe
--- /dev/null
+++ b/plugins/Mac/Resources/Info-WebViewSeparated.plist
@@ -0,0 +1,28 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ English
+ CFBundleExecutable
+ ${EXECUTABLE_NAME}
+ CFBundleIconFile
+
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ ${PRODUCT_NAME}
+ CFBundlePackageType
+ BNDL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ NSPrincipalClass
+
+
+
diff --git a/plugins/Mac/Resources/Info.plist b/plugins/Mac/Resources/Info.plist
index 2dc923d6..e89822fe 100644
--- a/plugins/Mac/Resources/Info.plist
+++ b/plugins/Mac/Resources/Info.plist
@@ -9,7 +9,7 @@
CFBundleIconFile
CFBundleIdentifier
- net.gree.unitywebview.${PRODUCT_NAME:rfc1034identifier}
+ $(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
diff --git a/plugins/Mac/Sources/WebView.m b/plugins/Mac/Sources/WebView.m
index 8da64473..cd9db72a 100644
--- a/plugins/Mac/Sources/WebView.m
+++ b/plugins/Mac/Sources/WebView.m
@@ -1,15 +1,15 @@
/*
* Copyright (C) 2011 Keijiro Takahashi
* Copyright (C) 2012 GREE, Inc.
- *
+ *
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
- *
+ *
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
- *
+ *
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
@@ -34,20 +34,20 @@
typedef void *MonoMethod;
typedef void *MonoString;
+#ifdef __cplusplus
extern "C" {
+#endif
MonoDomain *mono_domain_get();
- MonoAssembly *mono_domain_assembly_open(
- MonoDomain *domain, const char *assemblyName);
+ MonoAssembly *mono_domain_assembly_open(MonoDomain *domain, const char *assemblyName);
MonoImage *mono_assembly_get_image(MonoAssembly *assembly);
- MonoMethodDesc *mono_method_desc_new(
- const char *methodString, int useNamespace);
+ MonoMethodDesc *mono_method_desc_new(const char *methodString, int useNamespace);
MonoMethodDesc *mono_method_desc_free(MonoMethodDesc *desc);
- MonoMethod *mono_method_desc_search_in_image(
- MonoMethodDesc *methodDesc, MonoImage *image);
- MonoObject *mono_runtime_invoke(
- MonoMethod *method, void *obj, void **params, MonoObject **exc);
+ MonoMethod *mono_method_desc_search_in_image(MonoMethodDesc *methodDesc, MonoImage *image);
+ MonoObject *mono_runtime_invoke(MonoMethod *method, void *obj, void **params, MonoObject **exc);
MonoString *mono_string_new(MonoDomain *domain, const char *text);
+#ifdef __cplusplus
}
+#endif
static BOOL inEditor;
static MonoDomain *monoDomain;
@@ -73,7 +73,7 @@ static void UnitySendMessage(
monoDomain = mono_domain_get();
monoDesc = mono_method_desc_new(
"UnitySendMessageDispatcher:Dispatch(string,string,string)", FALSE);
-
+
monoAssembly =
mono_domain_assembly_open(monoDomain, [assemblyPath UTF8String]);
@@ -81,8 +81,8 @@ static void UnitySendMessage(
monoImage = mono_assembly_get_image(monoAssembly);
monoMethod = mono_method_desc_search_in_image(monoDesc, monoImage);
}
-
-
+
+
if (monoMethod == 0) {
if (inEditor) {
assemblyPath =
@@ -102,11 +102,11 @@ static void UnitySendMessage(
}
}
}
-
+
if (monoMethod == 0) {
return;
}
-
+
void *args[] = {
mono_string_new(monoDomain, gameObject),
mono_string_new(monoDomain, method),
@@ -196,7 +196,7 @@ - (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary
} else {
if ([customRequestHeader count] > 0) {
bool isCustomized = YES;
-
+
// Check for additional custom header.
for (NSString *key in [customRequestHeader allKeys])
{
@@ -213,7 +213,7 @@ - (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary
return;
}
}
-
+
[listener use];
}
}
@@ -321,20 +321,20 @@ - (void)update:(int)x y:(int)y deltaY:(float)deltaY buttonDown:(BOOL)buttonDown
event = [NSEvent mouseEventWithType:NSLeftMouseDown
location:NSMakePoint(x, y) modifierFlags:nil
timestamp:GetCurrentEventTime() windowNumber:0
- context:context eventNumber:nil clickCount:1 pressure:nil];
+ context:context eventNumber:nil clickCount:1 pressure:1];
[view mouseDown:event];
} else {
event = [NSEvent mouseEventWithType:NSLeftMouseDragged
location:NSMakePoint(x, y) modifierFlags:nil
timestamp:GetCurrentEventTime() windowNumber:0
- context:context eventNumber:nil clickCount:0 pressure:nil];
+ context:context eventNumber:nil clickCount:0 pressure:1];
[view mouseDragged:event];
}
} else if (buttonRelease) {
event = [NSEvent mouseEventWithType:NSLeftMouseUp
location:NSMakePoint(x, y) modifierFlags:nil
timestamp:GetCurrentEventTime() windowNumber:0
- context:context eventNumber:nil clickCount:0 pressure:nil];
+ context:context eventNumber:nil clickCount:0 pressure:0];
[view mouseUp:event];
}
@@ -452,7 +452,7 @@ - (const char *)getCustomRequestHeaderValue:(const char *)headerKey
if (!result) {
return NULL;
}
-
+
const char *s = [result UTF8String];
char *r = (char *)malloc(strlen(s) + 1);
strcpy(r, s);
@@ -462,7 +462,9 @@ - (const char *)getCustomRequestHeaderValue:(const char *)headerKey
@end
typedef void (*UnityRenderEventFunc)(int eventId);
+#ifdef __cplusplus
extern "C" {
+#endif
const char *_CWebViewPlugin_GetAppPath();
void *_CWebViewPlugin_Init(
const char *gameObject, BOOL transparent, int width, int height, const char *ua, BOOL ineditor);
@@ -489,7 +491,9 @@ void _CWebViewPlugin_Update(void *instance, int x, int y, float deltaY,
void _CWebViewPlugin_RemoveCustomHeader(void *instance, const char *headerKey);
void _CWebViewPlugin_ClearCustomHeader(void *instance);
const char *_CWebViewPlugin_GetCustomHeaderValue(void *instance, const char *headerKey);
+#ifdef __cplusplus
}
+#endif
const char *_CWebViewPlugin_GetAppPath()
{
diff --git a/plugins/Mac/Sources/WebViewSeparated.m b/plugins/Mac/Sources/WebViewSeparated.m
new file mode 100644
index 00000000..b2928a3a
--- /dev/null
+++ b/plugins/Mac/Sources/WebViewSeparated.m
@@ -0,0 +1,755 @@
+/*
+ * Copyright (C) 2011 Keijiro Takahashi
+ * Copyright (C) 2012 GREE, Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#import
+#import
+#import
+#import
+#import
+#import
+
+typedef void *MonoDomain;
+typedef void *MonoAssembly;
+typedef void *MonoImage;
+typedef void *MonoObject;
+typedef void *MonoMethodDesc;
+typedef void *MonoMethod;
+typedef void *MonoString;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ MonoDomain *mono_domain_get();
+ MonoAssembly *mono_domain_assembly_open(MonoDomain *domain, const char *assemblyName);
+ MonoImage *mono_assembly_get_image(MonoAssembly *assembly);
+ MonoMethodDesc *mono_method_desc_new(const char *methodString, int useNamespace);
+ MonoMethodDesc *mono_method_desc_free(MonoMethodDesc *desc);
+ MonoMethod *mono_method_desc_search_in_image(MonoMethodDesc *methodDesc, MonoImage *image);
+ MonoObject *mono_runtime_invoke(MonoMethod *method, void *obj, void **params, MonoObject **exc);
+ MonoString *mono_string_new(MonoDomain *domain, const char *text);
+#ifdef __cplusplus
+}
+#endif
+
+static BOOL inEditor;
+static MonoDomain *monoDomain;
+static MonoAssembly *monoAssembly;
+static MonoImage *monoImage;
+static MonoMethodDesc *monoDesc;
+static MonoMethod *monoMethod;
+
+static void UnitySendMessage(
+ const char *gameObject, const char *method, const char *message)
+{
+ if (monoMethod == 0) {
+ NSString *assemblyPath;
+ if (inEditor) {
+ assemblyPath =
+ @"Library/ScriptAssemblies/Assembly-CSharp-firstpass.dll";
+ } else {
+ NSString *dllPath =
+ @"Contents/Resources/Data/Managed/Assembly-CSharp-firstpass.dll";
+ assemblyPath = [[[NSBundle mainBundle] bundlePath]
+ stringByAppendingPathComponent:dllPath];
+ }
+ monoDomain = mono_domain_get();
+ monoDesc = mono_method_desc_new(
+ "UnitySendMessageDispatcher:Dispatch(string,string,string)", FALSE);
+
+ monoAssembly =
+ mono_domain_assembly_open(monoDomain, [assemblyPath UTF8String]);
+
+ if (monoAssembly != 0) {
+ monoImage = mono_assembly_get_image(monoAssembly);
+ monoMethod = mono_method_desc_search_in_image(monoDesc, monoImage);
+ }
+
+
+ if (monoMethod == 0) {
+ if (inEditor) {
+ assemblyPath =
+ @"Library/ScriptAssemblies/Assembly-CSharp.dll";
+ } else {
+ NSString *dllPath =
+ @"Contents/Resources/Data/Managed/Assembly-CSharp.dll";
+ assemblyPath = [[[NSBundle mainBundle] bundlePath]
+ stringByAppendingPathComponent:dllPath];
+ }
+ monoAssembly =
+ mono_domain_assembly_open(monoDomain, [assemblyPath UTF8String]);
+
+ if (monoAssembly != 0) {
+ monoImage = mono_assembly_get_image(monoAssembly);
+ monoMethod = mono_method_desc_search_in_image(monoDesc, monoImage);
+ }
+ }
+ }
+
+ if (monoMethod == 0) {
+ return;
+ }
+
+ void *args[] = {
+ mono_string_new(monoDomain, gameObject),
+ mono_string_new(monoDomain, method),
+ mono_string_new(monoDomain, message),
+ };
+
+ mono_runtime_invoke(monoMethod, 0, args, 0);
+}
+
+@interface CWebViewPlugin : NSObject
+{
+ NSWindow *window;
+ NSWindowController *windowController;
+ WKWebView *webView;
+ NSString *gameObject;
+ NSString *ua;
+ NSBitmapImageRep *bitmap;
+ int textureId;
+ BOOL needsDisplay;
+ NSMutableDictionary *customRequestHeader;
+}
+@end
+
+@implementation CWebViewPlugin
+
+- (id)initWithGameObject:(const char *)gameObject_ transparent:(BOOL)transparent width:(int)width height:(int)height ua:(const char *)ua_
+{
+ self = [super init];
+ monoMethod = 0;
+ customRequestHeader = [[NSMutableDictionary alloc] init];
+
+ WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
+ WKUserContentController *controller = [[WKUserContentController alloc] init];
+ WKPreferences *preferences = [[WKPreferences alloc] init];
+ preferences.javaScriptEnabled = true;
+ preferences.plugInsEnabled = true;
+ [controller addScriptMessageHandler:self name:@"unityControl"];
+ configuration.userContentController = controller;
+ // configuration.preferences = preferences;
+ NSRect frame = NSMakeRect(0, 0, width / 2, height / 2);
+ webView = [[WKWebView alloc] initWithFrame:frame
+ configuration:configuration];
+ [[[webView configuration] preferences] setValue:@YES forKey:@"developerExtrasEnabled"];
+ webView.UIDelegate = self;
+ webView.navigationDelegate = self;
+ webView.hidden = NO;
+ if (transparent) {
+ // [webView setDrawsBackground:NO];
+ }
+ [webView setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)];
+ // [webView setFrameLoadDelegate:(id)self];
+ // [webView setPolicyDelegate:(id)self];
+ webView.UIDelegate = self;
+ webView.navigationDelegate = self;
+ gameObject = [[NSString stringWithUTF8String:gameObject_] retain];
+ if (ua_ != NULL && strcmp(ua_, "") != 0) {
+ ua = [[NSString stringWithUTF8String:ua_] retain];
+ [webView setCustomUserAgent:ua];
+ }
+
+ window = [[[NSWindow alloc] initWithContentRect:frame
+ styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskResizable
+ backing:NSBackingStoreBuffered
+ defer:NO] autorelease];
+ [window setContentView:webView];
+ [window orderFront:NSApp];
+ windowController = [[NSWindowController alloc] initWithWindow:window];
+
+ return self;
+}
+
+- (void)dealloc
+{
+ @synchronized(self) {
+ if (webView != nil) {
+ // [webView setFrameLoadDelegate:nil];
+ // [webView setPolicyDelegate:nil];
+ webView.UIDelegate = nil;
+ webView.navigationDelegate = nil;
+ [webView stopLoading:nil];
+ [webView release];
+ webView = nil;
+ }
+ if (gameObject != nil) {
+ [gameObject release];
+ gameObject = nil;
+ }
+ if (ua != nil) {
+ [ua release];
+ ua = nil;
+ }
+ if (bitmap != nil) {
+ [bitmap release];
+ bitmap = nil;
+ }
+ if (window != nil) {
+ [window release];
+ window = nil;
+ }
+ if (windowController != nil){
+ [windowController release];
+ windowController = nil;
+ }
+ }
+ [super dealloc];
+}
+
+
+/*
+- (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
+{
+ UnitySendMessage([gameObject UTF8String], "CallOnError", [[error description] UTF8String]);
+}
+
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
+{
+ UnitySendMessage([gameObject UTF8String], "CallOnLoaded", [[[[[frame dataSource] request] URL] absoluteString] UTF8String]);
+}
+
+- (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener
+{
+ NSString *url = [[request URL] absoluteString];
+ if ([url hasPrefix:@"unity:"]) {
+ UnitySendMessage([gameObject UTF8String], "CallFromJS", [[url substringFromIndex:6] UTF8String]);
+ [listener ignore];
+ } else {
+ if ([customRequestHeader count] > 0) {
+ bool isCustomized = YES;
+
+ // Check for additional custom header.
+ for (NSString *key in [customRequestHeader allKeys])
+ {
+ if (![[[request allHTTPHeaderFields] objectForKey:key] isEqualToString:[customRequestHeader objectForKey:key]]) {
+ isCustomized = NO;
+ break;
+ }
+ }
+
+ // If the custom header is not attached, give it and make a request again.
+ if (!isCustomized) {
+ [listener ignore];
+ [frame loadRequest:[self constructionCustomHeader:request]];
+ return;
+ }
+ }
+
+ [listener use];
+ }
+}
+*/
+
+- (void)webView:(WKWebView*)wkWebView didCommitNavigation:(null_unspecified WKNavigation *)navigation
+{
+ UnitySendMessage([gameObject UTF8String], "CallOnLoaded", "Unknown URL");
+
+}
+
+- (void)webView:(WKWebView *)wkWebView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
+{
+ if (webView == nil) {
+ decisionHandler(WKNavigationActionPolicyCancel);
+ return;
+ }
+ NSURL *url = [navigationAction.request URL];
+ //if ([url.absoluteString rangeOfString:@"//itunes.apple.com/"].location != NSNotFound) {
+ // [[UIApplication sharedApplication] openURL:url];
+ // decisionHandler(WKNavigationActionPolicyCancel);
+ //} else
+ if ([url.absoluteString hasPrefix:@"unity:"]) {
+ UnitySendMessage([gameObject UTF8String], "CallFromJS", [[url.absoluteString substringFromIndex:6] UTF8String]);
+ decisionHandler(WKNavigationActionPolicyCancel);
+ } else if (navigationAction.navigationType == WKNavigationTypeLinkActivated
+ && (!navigationAction.targetFrame || !navigationAction.targetFrame.isMainFrame)) {
+ // cf. for target="_blank", cf. http://qiita.com/ShingoFukuyama/items/b3a1441025a36ab7659c
+ [webView loadRequest:navigationAction.request];
+ decisionHandler(WKNavigationActionPolicyCancel);
+ } else {
+ decisionHandler(WKNavigationActionPolicyAllow);
+ }
+}
+
+
+- (void)userContentController:(WKUserContentController *)userContentController
+ didReceiveScriptMessage:(WKScriptMessage *)message {
+
+ // Log out the message received
+ NSLog(@"Received event %@", message.body);
+ UnitySendMessage([gameObject UTF8String], "CallFromJS",
+ [[NSString stringWithFormat:@"%@", message.body] UTF8String]);
+
+ /*
+ // Then pull something from the device using the message body
+ NSString *version = [[UIDevice currentDevice] valueForKey:message.body];
+
+ // Execute some JavaScript using the result?
+ NSString *exec_template = @"set_headline(\"received: %@\");";
+ NSString *exec = [NSString stringWithFormat:exec_template, version];
+ [webView evaluateJavaScript:exec completionHandler:nil];
+ */
+}
+
+- (void)setRect:(int)width height:(int)height
+{
+ if (webView == nil)
+ return;
+ NSRect frame;
+ frame.size.width = width / 2;
+ frame.size.height = height / 2;
+ frame.origin.x = 0;
+ frame.origin.y = 0;
+ webView.frame = frame;
+ if (bitmap != nil) {
+ [bitmap release];
+ bitmap = nil;
+ }
+}
+
+- (void)setVisibility:(BOOL)visibility
+{
+ if (webView == nil)
+ return;
+ // webView.hidden = visibility ? NO : YES;
+}
+
+- (NSURLRequest *)constructionCustomHeader:(NSURLRequest *)originalRequest
+{
+ NSMutableURLRequest *convertedRequest = originalRequest.mutableCopy;
+ for (NSString *key in [customRequestHeader allKeys]) {
+ [convertedRequest setValue:customRequestHeader[key] forHTTPHeaderField:key];
+ }
+ return convertedRequest;
+}
+
+- (void)loadURL:(const char *)url
+{
+ if (webView == nil)
+ return;
+ NSString *urlStr = [NSString stringWithUTF8String:url];
+ NSURL *nsurl = [NSURL URLWithString:urlStr];
+ NSURLRequest *request = [NSURLRequest requestWithURL:nsurl];
+
+ if ([nsurl.absoluteString hasPrefix:@"file:"]) {
+ NSURL *top = [NSURL URLWithString:[[nsurl absoluteString] stringByDeletingLastPathComponent]];
+ [webView loadFileURL:nsurl allowingReadAccessToURL:top];
+ } else {
+ [webView loadRequest:request];
+ }
+}
+
+- (void)loadHTML:(const char *)html baseURL:(const char *)baseUrl
+{
+ if (webView == nil)
+ return;
+ NSString *htmlStr = [NSString stringWithUTF8String:html];
+ NSString *baseStr = [NSString stringWithUTF8String:baseUrl];
+ NSURL *baseNSUrl = [NSURL URLWithString:baseStr];
+ [webView loadHTMLString:htmlStr baseURL:baseNSUrl];
+}
+
+- (void)evaluateJS:(const char *)js
+{
+ if (webView == nil)
+ return;
+ NSString *jsStr = [NSString stringWithUTF8String:js];
+ [webView evaluateJavaScript:jsStr completionHandler:nil];
+}
+
+- (BOOL)canGoBack
+{
+ if (webView == nil)
+ return false;
+ return [webView canGoBack];
+}
+
+- (BOOL)canGoForward
+{
+ if (webView == nil)
+ return false;
+ return [webView canGoForward];
+}
+
+- (void)goBack
+{
+ if (webView == nil)
+ return;
+ [webView goBack];
+}
+
+- (void)goForward
+{
+ if (webView == nil)
+ return;
+ [webView goForward];
+}
+
+- (void)update:(int)x y:(int)y deltaY:(float)deltaY buttonDown:(BOOL)buttonDown buttonPress:(BOOL)buttonPress buttonRelease:(BOOL)buttonRelease keyPress:(BOOL)keyPress keyCode:(unsigned short)keyCode keyChars:(const char*)keyChars
+{
+ if (webView == nil)
+ return;
+
+ NSView *view = webView;
+ NSGraphicsContext *context = [NSGraphicsContext currentContext];
+ NSEvent *event;
+ NSString *characters;
+
+ if (buttonDown) {
+ if (buttonPress) {
+ event = [NSEvent mouseEventWithType:NSLeftMouseDown
+ location:NSMakePoint(x, y) modifierFlags:nil
+ timestamp:GetCurrentEventTime() windowNumber:0
+ context:context eventNumber:nil clickCount:1 pressure:1];
+ [view mouseDown:event];
+ } else {
+ event = [NSEvent mouseEventWithType:NSLeftMouseDragged
+ location:NSMakePoint(x, y) modifierFlags:nil
+ timestamp:GetCurrentEventTime() windowNumber:0
+ context:context eventNumber:nil clickCount:0 pressure:1];
+ [view mouseDragged:event];
+ }
+ } else if (buttonRelease) {
+ event = [NSEvent mouseEventWithType:NSLeftMouseUp
+ location:NSMakePoint(x, y) modifierFlags:nil
+ timestamp:GetCurrentEventTime() windowNumber:0
+ context:context eventNumber:nil clickCount:0 pressure:0];
+ [view mouseUp:event];
+ }
+
+ if (keyPress) {
+ characters = [NSString stringWithUTF8String:keyChars];
+ event = [NSEvent keyEventWithType:NSKeyDown
+ location:NSMakePoint(x, y) modifierFlags:nil
+ timestamp:GetCurrentEventTime() windowNumber:0
+ context:context
+ characters:characters
+ charactersIgnoringModifiers:characters
+ isARepeat:NO keyCode:(unsigned short)keyCode];
+ [view keyDown:event];
+ }
+
+ if (deltaY != 0) {
+ CGEventRef cgEvent = CGEventCreateScrollWheelEvent(NULL,
+ kCGScrollEventUnitLine, 1, deltaY * 3, 0);
+ NSEvent *scrollEvent = [NSEvent eventWithCGEvent:cgEvent];
+ CFRelease(cgEvent);
+ [view scrollWheel:scrollEvent];
+ }
+
+ @synchronized(self) {
+ if (bitmap == nil)
+ bitmap = [[webView bitmapImageRepForCachingDisplayInRect:webView.frame] retain];
+ memset([bitmap bitmapData], 0, [bitmap bytesPerRow] * [bitmap pixelsHigh]);
+ [webView cacheDisplayInRect:webView.frame toBitmapImageRep:bitmap];
+ needsDisplay = YES; // TODO (bitmap == nil || [view needsDisplay]);
+ }
+}
+
+- (int)bitmapWide
+{
+ @synchronized(self) {
+ return (bitmap == nil) ? 0 : (int)[bitmap pixelsWide];
+ }
+}
+
+- (int)bitmapHigh
+{
+ @synchronized(self) {
+ return (bitmap == nil) ? 0 : (int)[bitmap pixelsHigh];
+ }
+}
+
+- (void)setTextureId:(int)tId
+{
+ @synchronized(self) {
+ textureId = tId;
+ }
+}
+
+- (void)render
+{
+ @synchronized(self) {
+ if (webView == nil)
+ return;
+ if (!needsDisplay)
+ return;
+ if (bitmap == nil)
+ return;
+
+ int samplesPerPixel = (int)[bitmap samplesPerPixel];
+ int rowLength = 0;
+ int unpackAlign = 0;
+ glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowLength);
+ glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpackAlign);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)[bitmap bytesPerRow] / samplesPerPixel);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ if (![bitmap isPlanar] && (samplesPerPixel == 3 || samplesPerPixel == 4)) {
+ glTexSubImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ 0,
+ 0,
+ (GLsizei)[bitmap pixelsWide],
+ (GLsizei)[bitmap pixelsHigh],
+ samplesPerPixel == 4 ? GL_RGBA : GL_RGB,
+ GL_UNSIGNED_BYTE,
+ [bitmap bitmapData]);
+ }
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, rowLength);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, unpackAlign);
+ }
+}
+
+- (void)addCustomRequestHeader:(const char *)headerKey value:(const char *)headerValue
+{
+ NSString *keyString = [NSString stringWithUTF8String:headerKey];
+ NSString *valueString = [NSString stringWithUTF8String:headerValue];
+
+ [customRequestHeader setObject:valueString forKey:keyString];
+}
+
+- (void)removeCustomRequestHeader:(const char *)headerKey
+{
+ NSString *keyString = [NSString stringWithUTF8String:headerKey];
+
+ if ([[customRequestHeader allKeys]containsObject:keyString]) {
+ [customRequestHeader removeObjectForKey:keyString];
+ }
+}
+
+- (void)clearCustomRequestHeader
+{
+ [customRequestHeader removeAllObjects];
+}
+
+- (const char *)getCustomRequestHeaderValue:(const char *)headerKey
+{
+ NSString *keyString = [NSString stringWithUTF8String:headerKey];
+ NSString *result = [customRequestHeader objectForKey:keyString];
+ if (!result) {
+ return NULL;
+ }
+
+ const char *s = [result UTF8String];
+ char *r = (char *)malloc(strlen(s) + 1);
+ strcpy(r, s);
+ return r;
+}
+
+@end
+
+typedef void (*UnityRenderEventFunc)(int eventId);
+#ifdef __cplusplus
+extern "C" {
+#endif
+const char *_CWebViewPlugin_GetAppPath();
+void *_CWebViewPlugin_Init(
+ const char *gameObject, BOOL transparent, int width, int height, const char *ua, BOOL ineditor);
+void _CWebViewPlugin_Destroy(void *instance);
+void _CWebViewPlugin_SetRect(void *instance, int width, int height);
+void _CWebViewPlugin_SetVisibility(void *instance, BOOL visibility);
+void _CWebViewPlugin_LoadURL(void *instance, const char *url);
+void _CWebViewPlugin_LoadHTML(void *instance, const char *html, const char *baseUrl);
+void _CWebViewPlugin_EvaluateJS(void *instance, const char *url);
+BOOL _CWebViewPlugin_CanGoBack(void *instance);
+BOOL _CWebViewPlugin_CanGoForward(void *instance);
+void _CWebViewPlugin_GoBack(void *instance);
+void _CWebViewPlugin_GoForward(void *instance);
+void _CWebViewPlugin_Update(void *instance, int x, int y, float deltaY,
+ BOOL buttonDown, BOOL buttonPress, BOOL buttonRelease,
+ BOOL keyPress, unsigned char keyCode, const char *keyChars);
+int _CWebViewPlugin_BitmapWidth(void *instance);
+int _CWebViewPlugin_BitmapHeight(void *instance);
+void _CWebViewPlugin_SetTextureId(void *instance, int textureId);
+void _CWebViewPlugin_SetCurrentInstance(void *instance);
+void UnityRenderEvent(int eventId);
+UnityRenderEventFunc GetRenderEventFunc();
+void _CWebViewPlugin_AddCustomHeader(void *instance, const char *headerKey, const char *headerValue);
+void _CWebViewPlugin_RemoveCustomHeader(void *instance, const char *headerKey);
+void _CWebViewPlugin_ClearCustomHeader(void *instance);
+const char *_CWebViewPlugin_GetCustomHeaderValue(void *instance, const char *headerKey);
+#ifdef __cplusplus
+}
+#endif
+
+const char *_CWebViewPlugin_GetAppPath()
+{
+ const char *s = [[[[NSBundle mainBundle] bundleURL] absoluteString] UTF8String];
+ char *r = (char *)malloc(strlen(s) + 1);
+ strcpy(r, s);
+ return r;
+}
+
+static NSMutableSet *pool;
+
+void *_CWebViewPlugin_Init(
+ const char *gameObject, BOOL transparent, int width, int height, const char *ua, BOOL ineditor)
+{
+ if (pool == 0)
+ pool = [[NSMutableSet alloc] init];
+
+ inEditor = ineditor;
+ id instance = [[CWebViewPlugin alloc] initWithGameObject:gameObject transparent:transparent width:width height:height ua:ua];
+ [pool addObject:[NSValue valueWithPointer:instance]];
+ return (void *)instance;
+}
+
+void _CWebViewPlugin_Destroy(void *instance)
+{
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)instance;
+ [webViewPlugin release];
+ [pool removeObject:[NSValue valueWithPointer:instance]];
+}
+
+void _CWebViewPlugin_SetRect(void *instance, int width, int height)
+{
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)instance;
+ [webViewPlugin setRect:width height:height];
+}
+
+void _CWebViewPlugin_SetVisibility(void *instance, BOOL visibility)
+{
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)instance;
+ [webViewPlugin setVisibility:visibility];
+}
+
+void _CWebViewPlugin_LoadURL(void *instance, const char *url)
+{
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)instance;
+ [webViewPlugin loadURL:url];
+}
+
+void _CWebViewPlugin_LoadHTML(void *instance, const char *html, const char *baseUrl)
+{
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)instance;
+ [webViewPlugin loadHTML:html baseURL:baseUrl];
+}
+
+void _CWebViewPlugin_EvaluateJS(void *instance, const char *js)
+{
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)instance;
+ [webViewPlugin evaluateJS:js];
+}
+
+BOOL _CWebViewPlugin_CanGoBack(void *instance)
+{
+ CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
+ return [webViewPlugin canGoBack];
+}
+
+BOOL _CWebViewPlugin_CanGoForward(void *instance)
+{
+ CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
+ return [webViewPlugin canGoForward];
+}
+
+void _CWebViewPlugin_GoBack(void *instance)
+{
+ CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
+ [webViewPlugin goBack];
+}
+
+void _CWebViewPlugin_GoForward(void *instance)
+{
+ CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
+ [webViewPlugin goForward];
+}
+
+void _CWebViewPlugin_Update(void *instance, int x, int y, float deltaY,
+ BOOL buttonDown, BOOL buttonPress, BOOL buttonRelease, BOOL keyPress,
+ unsigned char keyCode, const char *keyChars)
+{
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)instance;
+ [webViewPlugin update:x y:y deltaY:deltaY buttonDown:buttonDown
+ buttonPress:buttonPress buttonRelease:buttonRelease keyPress:keyPress
+ keyCode:keyCode keyChars:keyChars];
+}
+
+int _CWebViewPlugin_BitmapWidth(void *instance)
+{
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)instance;
+ return [webViewPlugin bitmapWide];
+}
+
+int _CWebViewPlugin_BitmapHeight(void *instance)
+{
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)instance;
+ return [webViewPlugin bitmapHigh];
+}
+
+void _CWebViewPlugin_SetTextureId(void *instance, int textureId)
+{
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)instance;
+ [webViewPlugin setTextureId:textureId];
+}
+
+static void *_instance;
+
+void _CWebViewPlugin_SetCurrentInstance(void *instance)
+{
+ _instance = instance;
+}
+
+void UnityRenderEvent(int eventId)
+{
+ @autoreleasepool {
+ if (_instance == nil) {
+ return;
+ }
+ if ([pool containsObject:[NSValue valueWithPointer:(void *)_instance]]) {
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)_instance;
+ _instance = nil;
+ [webViewPlugin render];
+ }
+ }
+}
+
+UnityRenderEventFunc GetRenderEventFunc()
+{
+ return UnityRenderEvent;
+}
+
+void _CWebViewPlugin_AddCustomHeader(void *instance, const char *headerKey, const char *headerValue)
+{
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)instance;
+ [webViewPlugin addCustomRequestHeader:headerKey value:headerValue];
+}
+
+void _CWebViewPlugin_RemoveCustomHeader(void *instance, const char *headerKey)
+{
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)instance;
+ [webViewPlugin removeCustomRequestHeader:headerKey];
+}
+
+const char *_CWebViewPlugin_GetCustomHeaderValue(void *instance, const char *headerKey)
+{
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)instance;
+ return [webViewPlugin getCustomRequestHeaderValue:headerKey];
+}
+
+void _CWebViewPlugin_ClearCustomHeader(void *instance)
+{
+ CWebViewPlugin *webViewPlugin = (CWebViewPlugin *)instance;
+ [webViewPlugin clearCustomRequestHeader];
+}
+
+
diff --git a/plugins/Mac/WebView.xcodeproj/project.pbxproj b/plugins/Mac/WebView.xcodeproj/project.pbxproj
index ac55345f..23a5f229 100644
--- a/plugins/Mac/WebView.xcodeproj/project.pbxproj
+++ b/plugins/Mac/WebView.xcodeproj/project.pbxproj
@@ -3,10 +3,16 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 46;
+ objectVersion = 48;
objects = {
/* Begin PBXBuildFile section */
+ 183C36501EA488E50071D97B /* WebViewSeparated.m in Sources */ = {isa = PBXBuildFile; fileRef = 183C364F1EA488E50071D97B /* WebViewSeparated.m */; };
+ 18E975FA1EA4873F00083D49 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81B8C53715108B89000C56DC /* Carbon.framework */; };
+ 18E975FB1EA4873F00083D49 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81B8C534151078DB000C56DC /* WebKit.framework */; };
+ 18E975FC1EA4873F00083D49 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81F81AEC14D76D2400845D4C /* OpenGL.framework */; };
+ 18E975FD1EA4873F00083D49 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81E2C20B14C5684A004CE5C2 /* Cocoa.framework */; };
+ 18E975FF1EA4873F00083D49 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8102525514C569D80022296D /* InfoPlist.strings */; };
8102525814C569D80022296D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8102525514C569D80022296D /* InfoPlist.strings */; };
81B8C535151078DB000C56DC /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81B8C534151078DB000C56DC /* WebKit.framework */; };
81B8C53815108B89000C56DC /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81B8C53715108B89000C56DC /* Carbon.framework */; };
@@ -16,6 +22,9 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
+ 183C364F1EA488E50071D97B /* WebViewSeparated.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; name = WebViewSeparated.m; path = Sources/WebViewSeparated.m; sourceTree = ""; };
+ 18E976041EA4873F00083D49 /* WebViewSeparated.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WebViewSeparated.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+ 18E976051EA4873F00083D49 /* Info-WebViewSeparated.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; name = "Info-WebViewSeparated.plist"; path = "Resources/Info-WebViewSeparated.plist"; sourceTree = ""; };
8102525414C569D80022296D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Resources/Info.plist; sourceTree = SOURCE_ROOT; };
8102525514C569D80022296D /* InfoPlist.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = InfoPlist.strings; path = Resources/InfoPlist.strings; sourceTree = SOURCE_ROOT; };
8102525614C569D80022296D /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Prefix.pch; path = Resources/Prefix.pch; sourceTree = SOURCE_ROOT; };
@@ -30,6 +39,17 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
+ 18E975F91EA4873F00083D49 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 18E975FA1EA4873F00083D49 /* Carbon.framework in Frameworks */,
+ 18E975FB1EA4873F00083D49 /* WebKit.framework in Frameworks */,
+ 18E975FC1EA4873F00083D49 /* OpenGL.framework in Frameworks */,
+ 18E975FD1EA4873F00083D49 /* Cocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
81E2C20514C5684A004CE5C2 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -48,6 +68,7 @@
isa = PBXGroup;
children = (
81F4B4D814C6888B001B4465 /* WebView.m */,
+ 183C364F1EA488E50071D97B /* WebViewSeparated.m */,
);
name = Sources;
sourceTree = "";
@@ -66,6 +87,7 @@
isa = PBXGroup;
children = (
81E2C20814C5684A004CE5C2 /* WebView.bundle */,
+ 18E976041EA4873F00083D49 /* WebViewSeparated.bundle */,
);
name = Products;
sourceTree = "";
@@ -87,6 +109,7 @@
isa = PBXGroup;
children = (
8102525414C569D80022296D /* Info.plist */,
+ 18E976051EA4873F00083D49 /* Info-WebViewSeparated.plist */,
8102525514C569D80022296D /* InfoPlist.strings */,
8102525614C569D80022296D /* Prefix.pch */,
);
@@ -97,6 +120,24 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
+ 18E975F61EA4873F00083D49 /* WebViewSeparated */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 18E976011EA4873F00083D49 /* Build configuration list for PBXNativeTarget "WebViewSeparated" */;
+ buildPhases = (
+ 18E975F71EA4873F00083D49 /* Sources */,
+ 18E975F91EA4873F00083D49 /* Frameworks */,
+ 18E975FE1EA4873F00083D49 /* Resources */,
+ 18E976001EA4873F00083D49 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = WebViewSeparated;
+ productName = WebView;
+ productReference = 18E976041EA4873F00083D49 /* WebViewSeparated.bundle */;
+ productType = "com.apple.product-type.bundle";
+ };
81E2C20714C5684A004CE5C2 /* WebView */ = {
isa = PBXNativeTarget;
buildConfigurationList = 81E2C21A14C5684A004CE5C2 /* Build configuration list for PBXNativeTarget "WebView" */;
@@ -121,14 +162,15 @@
81E2C1FF14C5684A004CE5C2 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0420;
+ LastUpgradeCheck = 0820;
};
buildConfigurationList = 81E2C20214C5684A004CE5C2 /* Build configuration list for PBXProject "WebView" */;
- compatibilityVersion = "Xcode 3.2";
+ compatibilityVersion = "Xcode 8.0";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
+ Base,
);
mainGroup = 81E2C1FD14C5684A004CE5C2;
productRefGroup = 81E2C20914C5684A004CE5C2 /* Products */;
@@ -136,11 +178,20 @@
projectRoot = "";
targets = (
81E2C20714C5684A004CE5C2 /* WebView */,
+ 18E975F61EA4873F00083D49 /* WebViewSeparated */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
+ 18E975FE1EA4873F00083D49 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 18E975FF1EA4873F00083D49 /* InfoPlist.strings in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
81E2C20614C5684A004CE5C2 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -152,6 +203,19 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
+ 18E976001EA4873F00083D49 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "";
+ };
81F4B4F514C696C4001B4465 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -168,6 +232,14 @@
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
+ 18E975F71EA4873F00083D49 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 183C36501EA488E50071D97B /* WebViewSeparated.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
81E2C20414C5684A004CE5C2 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -179,15 +251,62 @@
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
+ 18E976021EA4873F00083D49 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_CXX_LIBRARY = "compiler-default";
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Resources/Prefix.pch;
+ INFOPLIST_FILE = "Resources/Info-WebViewSeparated.plist";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
+ LD_RUNPATH_SEARCH_PATHS = "";
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
+ PRODUCT_BUNDLE_IDENTIFIER = "net.gree.unitywebview.${PRODUCT_NAME:rfc1034identifier}";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ VALID_ARCHS = x86_64;
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Debug;
+ };
+ 18E976031EA4873F00083D49 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_CXX_LIBRARY = "compiler-default";
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Resources/Prefix.pch;
+ INFOPLIST_FILE = "Resources/Info-WebViewSeparated.plist";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
+ LD_RUNPATH_SEARCH_PATHS = "";
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
+ PRODUCT_BUNDLE_IDENTIFIER = "net.gree.unitywebview.${PRODUCT_NAME:rfc1034identifier}";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ VALID_ARCHS = x86_64;
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Release;
+ };
81E2C21814C5684A004CE5C2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
- ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
@@ -198,6 +317,9 @@
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "";
MACOSX_DEPLOYMENT_TARGET = 10.6;
@@ -214,15 +336,28 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
- ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "";
MACOSX_DEPLOYMENT_TARGET = 10.6;
@@ -238,12 +373,14 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ CLANG_CXX_LIBRARY = "compiler-default";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Resources/Prefix.pch;
INFOPLIST_FILE = Resources/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
LD_RUNPATH_SEARCH_PATHS = "";
LIBRARY_SEARCH_PATHS = "$(inherited)";
+ PRODUCT_BUNDLE_IDENTIFIER = "net.gree.unitywebview.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = bundle;
};
@@ -253,12 +390,14 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ CLANG_CXX_LIBRARY = "compiler-default";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Resources/Prefix.pch;
INFOPLIST_FILE = Resources/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
LD_RUNPATH_SEARCH_PATHS = "";
LIBRARY_SEARCH_PATHS = "$(inherited)";
+ PRODUCT_BUNDLE_IDENTIFIER = "net.gree.unitywebview.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = bundle;
};
@@ -267,6 +406,15 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
+ 18E976011EA4873F00083D49 /* Build configuration list for PBXNativeTarget "WebViewSeparated" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 18E976021EA4873F00083D49 /* Debug */,
+ 18E976031EA4873F00083D49 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
81E2C20214C5684A004CE5C2 /* Build configuration list for PBXProject "WebView" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/plugins/Mac/WebView.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/plugins/Mac/WebView.xcodeproj/project.xcworkspace/contents.xcworkspacedata
deleted file mode 100644
index e970017a..00000000
--- a/plugins/Mac/WebView.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
diff --git a/plugins/Mac/WebView.xcodeproj/xcshareddata/xcschemes/WebView.xcscheme b/plugins/Mac/WebView.xcodeproj/xcshareddata/xcschemes/WebView.xcscheme
deleted file mode 100644
index 0f50d2d9..00000000
--- a/plugins/Mac/WebView.xcodeproj/xcshareddata/xcschemes/WebView.xcscheme
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/plugins/Mac/WebViewSeparated.bundle.meta b/plugins/Mac/WebViewSeparated.bundle.meta
new file mode 100644
index 00000000..c96417d4
--- /dev/null
+++ b/plugins/Mac/WebViewSeparated.bundle.meta
@@ -0,0 +1,57 @@
+fileFormatVersion: 2
+guid: 5ad99e2446f6f450185b777a22f98f2a
+folderAsset: yes
+PluginImporter:
+ serializedVersion: 1
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ platformData:
+ Android:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ Any:
+ enabled: 0
+ settings: {}
+ Editor:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ DefaultValueInitialized: true
+ OS: OSX
+ Linux:
+ enabled: 0
+ settings:
+ CPU: x86
+ Linux64:
+ enabled: 0
+ settings:
+ CPU: x86_64
+ OSXIntel:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ OSXIntel64:
+ enabled: 1
+ settings:
+ CPU: x86_64
+ OSXUniversal:
+ enabled: 0
+ settings: {}
+ Win:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ Win64:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ iOS:
+ enabled: 0
+ settings:
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/plugins/Mac/install.sh b/plugins/Mac/install.sh
index 0e2a2f66..cc1160ba 100755
--- a/plugins/Mac/install.sh
+++ b/plugins/Mac/install.sh
@@ -1,8 +1,10 @@
#!/bin/sh
DSTDIR="../../build/Packager/Assets/Plugins"
rm -rf DerivedData
-xcodebuild -scheme WebView -configuration Release -arch i386 -arch x86_64 build CONFIGURATION_BUILD_DIR='DerivedData'
+xcodebuild -target WebView -configuration Release -arch i386 -arch x86_64 build CONFIGURATION_BUILD_DIR='DerivedData'
+xcodebuild -target WebViewSeparated -configuration Release -arch x86_64 build CONFIGURATION_BUILD_DIR='DerivedData'
mkdir -p $DSTDIR
cp -r DerivedData/WebView.bundle $DSTDIR
+cp -r DerivedData/WebViewSeparated.bundle $DSTDIR
rm -rf DerivedData
-cp WebView.bundle.meta $DSTDIR
+cp *.bundle.meta $DSTDIR
diff --git a/plugins/WebViewObject.cs b/plugins/WebViewObject.cs
index 0dbe327f..dadc042a 100644
--- a/plugins/WebViewObject.cs
+++ b/plugins/WebViewObject.cs
@@ -86,6 +86,64 @@ public bool IsKeyboardVisible
}
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
+#if WEBVIEW_SEPARATED
+ [DllImport("WebViewSeparated")]
+ private static extern string _CWebViewPlugin_GetAppPath();
+ [DllImport("WebViewSeparated")]
+ private static extern IntPtr _CWebViewPlugin_Init(
+ string gameObject, bool transparent, int width, int height, string ua, bool ineditor);
+ [DllImport("WebViewSeparated")]
+ private static extern int _CWebViewPlugin_Destroy(IntPtr instance);
+ [DllImport("WebViewSeparated")]
+ private static extern void _CWebViewPlugin_SetRect(
+ IntPtr instance, int width, int height);
+ [DllImport("WebViewSeparated")]
+ private static extern void _CWebViewPlugin_SetVisibility(
+ IntPtr instance, bool visibility);
+ [DllImport("WebViewSeparated")]
+ private static extern void _CWebViewPlugin_LoadURL(
+ IntPtr instance, string url);
+ [DllImport("WebViewSeparated")]
+ private static extern void _CWebViewPlugin_LoadHTML(
+ IntPtr instance, string html, string baseUrl);
+ [DllImport("WebViewSeparated")]
+ private static extern void _CWebViewPlugin_EvaluateJS(
+ IntPtr instance, string url);
+ [DllImport("WebViewSeparated")]
+ private static extern bool _CWebViewPlugin_CanGoBack(
+ IntPtr instance);
+ [DllImport("WebViewSeparated")]
+ private static extern bool _CWebViewPlugin_CanGoForward(
+ IntPtr instance);
+ [DllImport("WebViewSeparated")]
+ private static extern void _CWebViewPlugin_GoBack(
+ IntPtr instance);
+ [DllImport("WebViewSeparated")]
+ private static extern void _CWebViewPlugin_GoForward(
+ IntPtr instance);
+ [DllImport("WebViewSeparated")]
+ private static extern void _CWebViewPlugin_Update(IntPtr instance,
+ int x, int y, float deltaY, bool down, bool press, bool release,
+ bool keyPress, short keyCode, string keyChars);
+ [DllImport("WebViewSeparated")]
+ private static extern int _CWebViewPlugin_BitmapWidth(IntPtr instance);
+ [DllImport("WebViewSeparated")]
+ private static extern int _CWebViewPlugin_BitmapHeight(IntPtr instance);
+ [DllImport("WebViewSeparated")]
+ private static extern void _CWebViewPlugin_SetTextureId(IntPtr instance, int textureId);
+ [DllImport("WebViewSeparated")]
+ private static extern void _CWebViewPlugin_SetCurrentInstance(IntPtr instance);
+ [DllImport("WebViewSeparated")]
+ private static extern IntPtr GetRenderEventFunc();
+ [DllImport("WebViewSeparated")]
+ private static extern void _CWebViewPlugin_AddCustomHeader(IntPtr instance, string headerKey, string headerValue);
+ [DllImport("WebViewSeparated")]
+ private static extern string _CWebViewPlugin_GetCustomHeaderValue(IntPtr instance, string headerKey);
+ [DllImport("WebViewSeparated")]
+ private static extern void _CWebViewPlugin_RemoveCustomHeader(IntPtr instance, string headerKey);
+ [DllImport("WebViewSeparated")]
+ private static extern void _CWebViewPlugin_ClearCustomHeader(IntPtr instance);
+#else
[DllImport("WebView")]
private static extern string _CWebViewPlugin_GetAppPath();
[DllImport("WebView")]
@@ -142,7 +200,7 @@ private static extern void _CWebViewPlugin_Update(IntPtr instance,
private static extern void _CWebViewPlugin_RemoveCustomHeader(IntPtr instance, string headerKey);
[DllImport("WebView")]
private static extern void _CWebViewPlugin_ClearCustomHeader(IntPtr instance);
-
+#endif
#elif UNITY_IPHONE
[DllImport("__Internal")]
private static extern IntPtr _CWebViewPlugin_Init(string gameObject, bool transparent, bool enableWKWebView);
diff --git a/plugins/iOS/WebView.mm b/plugins/iOS/WebView.mm
index a2640905..310621f2 100644
--- a/plugins/iOS/WebView.mm
+++ b/plugins/iOS/WebView.mm
@@ -117,7 +117,7 @@ - (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void
@end
-@interface CWebViewPlugin : NSObject
+@interface CWebViewPlugin : NSObject
{
UIView *webView;
NSString *gameObjectName;
@@ -135,7 +135,11 @@ - (id)initWithGameObjectName:(const char *)gameObjectName_ transparent:(BOOL)tra
UIView *view = UnityGetGLViewController().view;
if (enableWKWebView && [WKWebView class]) {
- webView = [[WKWebView alloc] initWithFrame:view.frame];
+ WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
+ WKUserContentController *controller = [[WKUserContentController alloc] init];
+ [controller addScriptMessageHandler:self name:@"unityControl"];
+ configuration.userContentController = controller;
+ webView = [[WKWebView alloc] initWithFrame:view.frame configuration:configuration];
webView.UIDelegate = self;
webView.navigationDelegate = self;
} else {
@@ -176,6 +180,25 @@ - (void)dealloc
customRequestHeader = nil;
}
+- (void)userContentController:(WKUserContentController *)userContentController
+ didReceiveScriptMessage:(WKScriptMessage *)message {
+
+ // Log out the message received
+ NSLog(@"Received event %@", message.body);
+ UnitySendMessage([gameObjectName UTF8String], "CallFromJS",
+ [[NSString stringWithFormat:@"%@", message.body] UTF8String]);
+
+ /*
+ // Then pull something from the device using the message body
+ NSString *version = [[UIDevice currentDevice] valueForKey:message.body];
+
+ // Execute some JavaScript using the result?
+ NSString *exec_template = @"set_headline(\"received: %@\");";
+ NSString *exec = [NSString stringWithFormat:exec_template, version];
+ [webView evaluateJavaScript:exec completionHandler:nil];
+ */
+}
+
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change