Added basic iOS support (no messaging yet)

This commit is contained in:
Kris Pypen 2019-08-01 10:43:34 +02:00
parent 5277f942a8
commit 18c013a374
9 changed files with 190 additions and 164 deletions

View File

@ -1,25 +0,0 @@
//
// Created by rex on 19/03/2019.
//
#ifndef FLUTTER_UNITY_WIDGET_FLUTTERUNITY_H
#define FLUTTER_UNITY_WIDGET_FLUTTERUNITY_H
#import <Flutter/Flutter.h>
@interface FlutterUnityController : NSObject <FlutterPlatformView>
- (instancetype)initWithWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
- (UIView*)view;
@end
@interface FlutterUnityFactory : NSObject <FlutterPlatformViewFactory>
- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
@end
#endif //FLUTTER_UNITY_WIDGET_FLUTTERUNITY_H

View File

@ -1,87 +0,0 @@
//
// Created by rex on 19/03/2019.
//
#include "FlutterUnity.h"
@implementation FlutterUnityFactory {
NSObject<FlutterBinaryMessenger>* _messenger;
}
- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
self = [super init];
if (self) {
_messenger = messenger;
}
return self;
}
@implementation FlutterUnityController {
WKWebView* _webView;
int64_t _viewId;
FlutterMethodChannel* _channel;
}
- (instancetype)initWithWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
if ([super init]) {
_viewId = viewId;
_webView = [[WKWebView alloc] initWithFrame:frame];
NSString* channelName = [NSString stringWithFormat:@"nativeweb_%lld", viewId];
_channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger];
__weak __typeof__(self) weakSelf = self;
[_channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
[weakSelf onMethodCall:call result:result];
}];
}
return self;
}
- (UIView*)view {
return _webView;
}
- (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([[call method] isEqualToString:@"postMessage"]) {
[self postMessage:call result:result];
} else if ([[call method] isEqualToString:@"isReady"]) {
[self postMessage:call result:result];
} else if ([[call method] isEqualToString:@"createUnity"]) {
[self postMessage:call result:result];
} else if ([[call method] isEqualToString:@"pause"]) {
[self postMessage:call result:result];
} else if ([[call method] isEqualToString:@"resume"]) {
[self postMessage:call result:result];
} else {
result(FlutterMethodNotImplemented);
}
}
- (void)postMessage:(FlutterMethodCall*)call result:(FlutterResult)result {
NSString* url = [call arguments];
if (![self postMessage:url]) {
result([FlutterError errorWithCode:@"loadUrl_failed"
message:@"Failed parsing the URL"
details:[NSString stringWithFormat:@"URL was: '%@'", url]]);
} else {
result(nil);
}
}
- (bool)onPostMessage:(NSString*)url {
NSURL* nsUrl = [NSURL URLWithString:url];
if (!nsUrl) {
return false;
}
NSURLRequest* req = [NSURLRequest requestWithURL:nsUrl];
[_webView loadRequest:req];
return true;
}
@end

View File

@ -0,0 +1,18 @@
//
// FlutterUnityView.h
// FlutterUnityView
//
// Created by krispypen on 8/1/2019
//
#import <UIKit/UIKit.h>
#import "UnityUtils.h"
@interface FlutterUnityView : UIView
@property (nonatomic, strong) UIView* uView;
- (void)setUnityView:(UIView *)view;
@end

View File

@ -0,0 +1,37 @@
//
// FlutterUnityView.m
// FlutterUnityView
//
// Created by krispypen on 8/1/2019
//
#import "FlutterUnityView.h"
@implementation FlutterUnityView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
return self;
}
- (void)dealloc
{
}
- (void)setUnityView:(UIView *)view
{
self.uView = view;
[self setNeedsLayout];
}
- (void)layoutSubviews
{
[super layoutSubviews];
[(UIView *)self.uView removeFromSuperview];
[self insertSubview:(UIView *)self.uView atIndex:0];
((UIView *)self.uView).frame = self.bounds;
[(UIView *)self.uView setNeedsLayout];
}
@end

View File

@ -1,4 +1,25 @@
//
// FlutterUnityWidgetPlugin.h
// FlutterUnityWidgetPlugin
//
// Created by Kris Pypen on 8/1/19.
//
#import <Flutter/Flutter.h>
@interface FlutterUnityWidgetPlugin : NSObject<FlutterPlugin>
@end
@interface FUController : NSObject <FlutterPlatformView>
- (instancetype)initWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
- (UIView*)view;
@end
@interface FUViewFactory : NSObject <FlutterPlatformViewFactory>
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar;
@end

View File

@ -1,20 +1,84 @@
//
// FlutterUnityWidgetPlugin.m
// FlutterUnityWidgetPlugin
//
// Created by Kris Pypen on 8/1/19.
//
#import "FlutterUnityWidgetPlugin.h"
#import <flutter_unity_widget/flutter_unity_widget-Swift.h>
#import "UnityUtils.h"
#import "FlutterUnityView.h"
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FlutterNativeWebFactory* webviewFactory =
[[FlutterNativeWebFactory alloc] initWithMessenger:registrar.messenger];
[registrar registerViewFactory:webviewFactory withId:@"unity_view"];
}
/*
#import "FlutterUnityWidgetPlugin.h"
#import <flutter_unity_widget/flutter_unity_widget-Swift.h>
#include <UnityFramework/UnityFramework.h>
@implementation FlutterUnityWidgetPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
[SwiftFlutterUnityWidgetPlugin registerWithRegistrar:registrar];
FUViewFactory* fuviewFactory = [[FUViewFactory alloc] initWithRegistrar:registrar];
[registrar registerViewFactory:fuviewFactory withId:@"unity_view"];
}
@end
*/
@implementation FUViewFactory {
NSObject<FlutterPluginRegistrar>* _registrar;
}
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
self = [super init];
if (self) {
_registrar = registrar;
}
return self;
}
- (NSObject<FlutterMessageCodec>*)createArgsCodec {
return [FlutterStandardMessageCodec sharedInstance];
}
- (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args {
FUController* controller = [[FUController alloc] initWithFrame:frame
viewIdentifier:viewId
arguments:args
binaryMessenger:_registrar];
return controller;
}
@end
@implementation FUController {
FlutterUnityView* _uView;
int64_t _viewId;
FlutterMethodChannel* _channel;
}
- (instancetype)initWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
if ([super init]) {
_viewId = viewId;
NSString* channelName = [NSString stringWithFormat:@"unity_view_%lld", viewId];
_channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger];
}
return self;
}
- (UIView*)view {
_uView = [[FlutterUnityView alloc] init];
if ([UnityUtils isUnityReady]) {
[_uView setUnityView: (UIView*)[GetAppController() unityView]];
} else {
[UnityUtils createPlayer:^{
[_uView setUnityView: (UIView*)[GetAppController() unityView]];
}];
}
return _uView;
}
@end

View File

@ -1,27 +1,23 @@
//
// Created by rex on 15/03/2019.
//
#ifndef FLUTTER_UNITY_WIDGET_UNITYUTILS_H
#define FLUTTER_UNITY_WIDGET_UNITYUTILS_H
#import <Foundation/Foundation.h>
#ifndef UnityUtils_h
#define UnityUtils_h
#ifdef __cplusplus
extern "C" {
#endif
void InitArgs(int argc, char* argv[]);
void InitArgs(int argc, char* argv[]);
bool UnityIsInited(void);
bool UnityIsInited(void);
void InitUnity();
void InitUnity();
void UnityPostMessage(NSString* gameObject, NSString* methodName, NSString* message);
void UnityPostMessage(NSString* gameObject, NSString* methodName, NSString* message);
void UnityPauseCommand();
void UnityPauseCommand();
void UnityResumeCommand();
void UnityResumeCommand();
#ifdef __cplusplus
} // extern "C"
@ -40,5 +36,4 @@ void UnityResumeCommand();
@end
#endif //FLUTTER_UNITY_WIDGET_UNITYUTILS_H
#endif /* UnityUtils_h */

View File

@ -1,10 +1,8 @@
#include "RegisterMonoModules.h"
#include "RegisterFeatures.h"
#include <csignal>
#import <UIKit/UIKit.h>
#import "UnityInterface.h"
#import "UnityUtils.h"
#import "UnityAppController.h"
#include <UnityFramework/UnityFramework.h>
// Hack to work around iOS SDK 4.3 linker problem
// we need at least one __TEXT, __const section entry in main application .o files
@ -18,6 +16,8 @@ char** g_argv;
void UnityInitTrampoline();
UnityFramework* ufw;
extern "C" void InitArgs(int argc, char* argv[])
{
g_argc = argc;
@ -29,6 +29,19 @@ extern "C" bool UnityIsInited()
return unity_inited;
}
UnityFramework* UnityFrameworkLoad()
{
NSString* bundlePath = nil;
bundlePath = [[NSBundle mainBundle] bundlePath];
bundlePath = [bundlePath stringByAppendingString: @"/Frameworks/UnityFramework.framework"];
NSBundle* bundle = [NSBundle bundleWithPath: bundlePath];
if ([bundle isLoaded] == false) [bundle load];
UnityFramework* ufw = [bundle.principalClass getInstance];
return ufw;
}
extern "C" void InitUnity()
{
if (unity_inited) {
@ -36,41 +49,28 @@ extern "C" void InitUnity()
}
unity_inited = true;
UnityInitStartupTime();
ufw = UnityFrameworkLoad();
@autoreleasepool
{
UnityInitTrampoline();
UnityInitRuntime(g_argc, g_argv);
RegisterMonoModules();
NSLog(@"-> registered mono modules %p\n", &constsection);
RegisterFeatures();
// iOS terminates open sockets when an application enters background mode.
// The next write to any of such socket causes SIGPIPE signal being raised,
// even if the request has been done from scripting side. This disables the
// signal and allows Mono to throw a proper C# exception.
std::signal(SIGPIPE, SIG_IGN);
}
[ufw setDataBundleId: "com.unity3d.framework"];
[ufw frameworkWarmup: g_argc argv: g_argv];
}
extern "C" void UnityPostMessage(NSString* gameObject, NSString* methodName, NSString* message)
{
UnitySendMessage([gameObject UTF8String], [methodName UTF8String], [message UTF8String]);
////UnitySendMessage([gameObject UTF8String], [methodName UTF8String], [message UTF8String]);
}
extern "C" void UnityPauseCommand()
{
dispatch_async(dispatch_get_main_queue(), ^{
UnityPause(1);
[ufw pause:true];
});
}
extern "C" void UnityResumeCommand()
{
dispatch_async(dispatch_get_main_queue(), ^{
UnityPause(0);
[ufw pause:false];
});
}

View File

@ -17,5 +17,8 @@ Flutter unity 3D widget for embedding unity in flutter
s.dependency 'Flutter'
s.ios.deployment_target = '8.0'
s.xcconfig = {
'FRAMEWORK_SEARCH_PATHS' => '$(inherited) "${PODS_ROOT}/../.symlinks/flutter/ios-release" "${PODS_ROOT}/../Unity3Export" "${PODS_CONFIGURATION_BUILD_DIR}"',
'OTHER_LDFLAGS' => '$(inherited) -framework UnityFramework ${PODS_LIBRARIES}'
}
end