Unity iOS Plugin part 2

This time I’ll create the same sort of test plugin from the previous tutorial but with a precompiled iOS library. This option is ideal if you intend to create a plugin and sell it in the Asset store because your code will remain invisible to users.

Here are the steps…

Create an iOS static library in XCode

So go to Xcode and create a new iOS static library. I called mine MyPluginTest

Now go to a previously build iOS Unity project and look for these header files: UnityForwardDecls.h, UnityInterface.h, UnityRendering.h

Copy and paste them inside a folder called Unity, in your brand new library project folder and then import the folder to your project inside Xcode.

These headers will allow you to use UnitySendMessage.

Add UiKit

Depending on what you need your plugin to accomplish you will also need to add new frameworks to your library. But even the most basic plugin will need UIKit.

So go to “Build Phases” in your project Settings, and inside “Link Binary with Libraries” add UIKit.framework

Add The Logic

1
2
3
4
5
6
7
8
9
10
11
12
#import "MyPluginTest.h"
#import "Unity/UnityInterface.h"
 
@implementation MyPluginTest
 
void iOSPluginMethod () {
 
    NSLog(@"Call to iOS Method from Unity Sucessful");
 
    UnitySendMessage("iOSReceiver", "MyMethod", "MyMessage");
}
@end

I created a class and header called MyPluginTest and added this logic. Once again if you need to use C++ or Objective-C++ wrap the logic inside an extern “C” block and change the extension of your class file.

Configure Build Settings

Still inside your project settings, move to the Build Settings tab and under Architectures make sure the option “Build Active Architecture Only” is set to “NO”

Also, set the Target SDK to the lowest you have available, but above 6 (You might need to change this under Deployment as well). My Unity editor builds projects to 6.1 by default so that’s what I use usually. Of course if you need a specific feature from a specific, more recent SDK, target that instead.

Add library to plugin folder

Build the library and grab the .a file inside Products. Mine is called libMyPluginTest.a

Drop this inside your Unity Plugin/iOS folder.

Use C# bridge

Now we can create the C# bridge as we did in the previous example.

One good thing to do now is to create a Prefab that contains the bridge as well as being the gameobject your plugin logic refers to in every UnitySendMessage call. This way you can make sure the code in the prefab sets the gameobject instance to the correct name listed in the iOS code. So if your UnitySendMessage calls refer to gameobject called MyGameObject make sure on Awake your prefab sets:

1
gameObject.name = "MyGameObject";

Of course, this can be made even better if we turn the C# bridge into a pre-compiled .dll, I’ll cover that next.

Creating a Bridge Dll

Usually you will want to build your plugin this way

– Create iOS plugin as a static library

– Create a prefab for the C# Bridge

– Make sure the prefab name is set in code, (otherwise user could change that and break everything)

– Compile the C# bridge as a DLL

For the last step here’s what you need to do. I used MonoDevelop for these steps but they are not very different in Visual Studio.

– Create Class Library


– Change Build settings target to Mono/.Net 2.0


– Edit the References in your project, and under the .Net Assemblies tab add the UnityEngine.dll (in my mac I find it inside Applications/Unity/Unity.app/Contents/Frameworks/Managed/) to your project references.

– Add the bridge logic to your class.

– Compile (Run) and grab the library dll from inside the solution’s bin folder.

– This next step is optional: You may need to support serialisation, or serialised data, in your plugin and this means adding support for the ahead of time compilation used by iOS (for the Android target you don’t need to worry about this because Android supports the just in time compilation model. In any event, when targeting iOS it may be necessary to create an AOT compiled version of your library. This involves creating another C# solution, but this time a Console Application. Edit the .Net Assemblies reference and add the dll from the previous build. And inside the console application program class, in the main method add something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Program
{
	static void Main(string[] args)
	{
		var typeModel = TypeModel.Create();
 
		typeModel.Add(typeof(YOUR C# BRIDGE CLASS), true);
		typeModel.Add(typeof(AND ALL C# BRIDGE CLASSES WHICH REQUIRE SERIALIZATION), true);
		typeModel.AllowParseableTypes = true;
		typeModel.AutoAddMissingTypes = true;
 
		typeModel.Compile("MyPluginBridge", "MyPluginBridge.dll");
	}
}

If you are not certain whether or not you need to add this step, ignore it and then test your iOS build. Trust me, it will tell you if you need this or not! 🙂

– Grab the built dll (whichever you chose to build) and add it to your plugin folder inside Unity.

– Link your Prefab to the Bridge class inside the dll and you should be good to go.

(Again, make sure the bridge code sets the proper name for the instantiated gameobject)

And that’s it, you’re done!