Issue with integration into native iOS app

Hello,

After following this tutorial (the-nerd.be) I managed to integrate a Unity app into a native iOS app. The problem I’m currently facing is when I try to go back from the Unity part to native iOS.

For Android I solved this by doing something like:

public void ReturnToNative()
{
#if UNITY_ANDROID
    AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
    AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
    jo.Call ("goBack");
#endif

#if UNITY_IOS
    Application.Quit();
#endif
}

The native Java method “goBack” basically stops and then finishes an activity that contains the Unity part.

I know that for iOS the solution is not an Application.Quit(), I should use an iOS Plugin.

So my question is, what should this plugin do? How could I make it work?

I know how to create plugins, but I don’t know what this particular plugin should contain.

Any help / hint / direction is greatly appreciated!!

First of all, you can create a Unity view, but once it’s started you cannot kill it (if you kill it you cannot reopen it again - this is where my app was crashing). So to go back to native, you have to hide the Unity view.

In my app specifically, I was integrating VR into a native app, so I had an intro scene that contained a button “Enter VR mode”, which loaded the next scene. That being said, my quit was:

public void QuitApp()
    {
        #if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
        #endif

        #if UNITY_IOS && !UNITY_EDITOR
        LoadingScene.UnityPaused = true;
        SceneManager.LoadScene("LoadingScene");
        #endif

        #if UNITY_ANDROID && !UNITY_EDITOR
        AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
        AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
        jo.Call ("goBack");
        #endif
    }

Then in my Loading Scene I had:

    public static bool UnityPaused = false;

    #if UNITY_IOS && !UNITY_EDITOR
    [DllImport("__Internal")]
    private static extern void UnityRequestHide_MyPlugin();
    #endif

	void Start ()
    {
        #if UNITY_IOS && !UNITY_EDITOR
        if (LoadingScene.UnityPaused)
        {
            // if UnityPaused is true, Unity should go on background
            Debug.Log("Going back to native");
            UnityRequestHide_MyPlugin();
        }
        #endif
    }

In addition, inside Plugins/iOS, I added the following code (note, I didn’t create a new plugin. Instead, I just added this method inside the existing CardboardAppController.mm that I already had imported with the GVR SDK. If you don’t have any existing plugin or wish to create one, read the docs):

void UnityRequestHide_MyPlugin() {
  if (GetAppController().quitHandler)
    GetAppController().quitHandler();
}

If you followed the same tutorial for integration into native iOS, you’ll have to make the following changes in the exported XCode project.

Inside UnityAppController.h, replace:

inline UnityAppController* GetAppController()
{
    return (UnityAppController*)[UIApplication sharedApplication].delegate;
}

with:

#import "AppDelegate.h"

inline UnityAppController* GetAppController()
{
    AppDelegate *delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
    return [delegate unityController];
}

And inside UnityAppController.mm, find this method:

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions

And add this at the beginning:

_quitHandler = ^{
[[NSNotificationCenter defaultCenter] postNotificationName:hideVR object:nil];
};

I hope this helps/guides any one who’s running into similar issues.