flutter-unity-view-widget
flutter-unity-view-widget copied to clipboard
I'm stuck for 2 days: can not run on iPhone device
Describe the bug I followed the instruction on pub.dev page and get building on Android perfectly. But when I export release for iOS, and config follow the guiding, I run on iPhone 7+, iOS version 15+. It crash instantly after installing successfully. I captured a screenshot about the log on console.
Hope someone can rescue me from this trouble :) Thanks a lot!
Screenshots
Unity (please complete the following information):
- OS: MacOS 13.4.1
- Version: 2022.3.4f
Smartphone (please complete the following information):
- Device: iPhone 7 plus
- iOS version: 15+
@timbotimbo @juicycleff Tagging you both to bring this to your notice. I am facing the same problem.
Adding some more context on what I am trying: I have a Niantic ARDK 3.0 app on Unity which I am trying to integrate with FUW.
The lightship ardk is trying to load the plugin like this:
// Put this into LightshipArPlugin/Runtime/Plugins/iOS
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "IUnityInterface.h"
// UI loaded observer from https://blog.eppz.eu/override-app-delegate-unity-ios-macos-2/
@interface RegisterPlugin : NSObject
@end
__strong RegisterPlugin *_instance;
@implementation RegisterPlugin
+(void)load
{
NSLog(@"[Override_iOS load]");
_instance = [RegisterPlugin new];
[[NSNotificationCenter defaultCenter] addObserver:_instance
selector:@selector(applicationDidFinishLaunching:)
name:UIApplicationDidFinishLaunchingNotification
object:nil];
}
-(void)applicationDidFinishLaunching:(NSNotification*) notification
{
NSLog(@"[Override_iOS applicationDidFinishLaunching:%@]",
UnityRegisterRenderingPluginV5(&UnityPluginLoad, &UnityPluginUnload);
}
@end
And, this line UnityRegisterRenderingPluginV5(&UnityPluginLoad, &UnityPluginUnload); throws a bad access exception. I was trying to find how ARKit plugin does it loading, such that it is UnityRegisterRenderingPluginV5(&UnityPluginLoad, NULL); is called only once Unity is loaded. However the lightship Register plugin is called as soon as the applicationDidFinishLaunching due to the UI Kit notification.
I do not have plugin building experience, so any pointers on this would be super helpful.
PS: Found this blog from the niantic register plugin https://blog.eppz.eu/override-app-delegate-unity-ios-macos-2/ This is exactly how they are registering their plugin (Framework, unlike the arkit .a library)
Once an export is completed, ios/UnityLibrary/Classes/UnityAppController.mm
contains a line that triggers a notification to signal unity is loaded.
- (void)startUnity:(UIApplication*)application
{
NSAssert(_unityAppReady == NO, @"[UnityAppController startUnity:] called after Unity has been initialized");
UnityInitApplicationGraphics();
// we make sure that first level gets correct display list and orientation
[[DisplayManager Instance] updateDisplayListCacheInUnity];
UnityLoadApplication();
Profiler_InitProfiler();
[self showGameUI];
[self createDisplayLink];
UnitySetPlayerFocus(1);
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
// If Unity audio is disabled, we set the category to ambient to make sure we don't mute other app's audio. We set the audio session
// to active so we can get outputVolume callbacks. If Unity audio is enabled, FMOD should have already handled all of this AVAudioSession init.
if (!UnityIsAudioManagerAvailableAndEnabled())
{
[audioSession setCategory: AVAudioSessionCategoryAmbient error: nil];
[audioSession setActive: YES error: nil];
}
[audioSession addObserver: self forKeyPath: @"outputVolume" options: 0 context: nil];
UnityUpdateMuteState([audioSession outputVolume] < 0.01f ? 1 : 0);
#if UNITY_REPLAY_KIT_AVAILABLE
void InitUnityReplayKit(); // Classes/Unity/UnityReplayKit.mm
InitUnityReplayKit();
#endif
// Modified by https://github.com/juicycleff/flutter-unity-view-widget
+ [[NSNotificationCenter defaultCenter] postNotificationName: @"UnityReady" object:self];
}
Maybe you can observe this notification instead of applicationDidFinishLaunching, or add your own custom notification that is triggered in the same location.
Thank-you @timbotimbo You are awesome!!
Just got confirmation on the Discord that the suggestion above can get it to work.
You need to edit this file in the export.
ios/UnityLibrary/Libraries/com.nianticlabs.lightship/Runtime/Plugins/iOS/RegisterPlugin.mm
+(void)load
{
NSLog(@"[Override_iOS load]");
_instance = [RegisterPlugin new];
[[NSNotificationCenter defaultCenter] addObserver:_instance
selector:@selector(applicationDidFinishLaunching:)
- name:UIApplicationDidFinishLaunchingNotification
+ name:@"UnityReady"
object:nil];
}
Now the ARDK plugin should register when the UnityWidget is loaded instead of when the Flutter app loads.