How to Integrate a Native Android/iOS SDK into Unity (and When to Hire It Out)
Sooner or later every Unity team hits the same wall: the ads network, analytics platform, payment provider, or hardware SDK you need only ships for native Android and iOS. There’s no Unity package, no C# API — just a .aar file and a doc page written for Kotlin developers.
This post explains your three options, what building a bridge actually involves, and the pitfalls that separate a clean integration from months of mystery crashes.
Your three options
- Use an existing Unity wrapper. Check the vendor’s site, GitHub, and OpenUPM first. If an official, maintained wrapper exists, use it. (Beware abandoned community wrappers — an SDK three versions behind is a liability, not a shortcut.)
- Build the bridge in-house. Completely doable if your team has native experience. The rest of this post is the map — and my public Android-Native repo shows a working Unity ↔ Android bridge you can read alongside it.
- Hire a specialist. Usually the right call when the SDK touches money (ads, payments), when you have no Kotlin/Swift experience on the team, or when the deadline can’t absorb the learning curve.
What a Unity native bridge actually is
A bridge has three layers, and each one has to be right:
The native layer. On Android, your code is Kotlin or Java, compiled into an AAR that Unity’s Gradle build consumes. On iOS, it’s Swift or Objective-C in a framework, plus extern "C" functions that Unity’s IL2CPP build can link against.
The interop layer. Android calls go through JNI — in Unity terms, AndroidJavaClass and AndroidJavaObject:
using (var bridge = new AndroidJavaClass("com.example.sdkbridge.Bridge"))
{
bridge.CallStatic("initialize", apiKey);
}
On iOS, you import C entry points directly:
[DllImport("__Internal")]
private static extern void sdkbridge_initialize(string apiKey);
The C# API layer. This is the part your gameplay team actually touches, and it should feel like it was never native at all: async methods or events instead of raw callbacks, one initialization call, and zero platform #if blocks leaking into game code.
The pitfalls that cause the mystery crashes
If you build in-house, these five issues cause most of the pain:
- Threading. Native SDKs fire callbacks on their own threads; Unity’s API is main-thread-only. Every callback must be marshalled back — a dispatcher queue drained from
Update()is the standard pattern. Miss one and you get crashes that reproduce only on devices, only sometimes. - Dependency conflicts. Your new SDK wants one version of a support library; your ads mediation wants another. On Android this is Gradle dependency hell — the External Dependency Manager (EDM4U) exists for exactly this, and it needs to be configured deliberately, not by trial and error.
- Code stripping. ProGuard/R8 on Android and IL2CPP stripping on iOS will happily remove “unused” classes that are only reached via reflection. You need keep-rules and
link.xmlentries, and you’ll only find out they’re missing in release builds. - Build post-processing. iOS integrations usually need automated Xcode project edits — entitlements,
Info.plistkeys, privacy manifests, framework embedding. Doing this by hand after every build doesn’t survive a team or CI. - API design debt. The bridge that “just works” as a pile of static methods becomes untestable glue everywhere in your codebase. Wrap it once, cleanly, and the SDK can be swapped or upgraded without touching game code.
Package it or regret it
However the bridge gets built, deliver it to your team as a UPM package — its own repo, versioned, with a sample scene and setup docs — rather than files dumped into Assets/. That’s the difference between “install in one line” and “ask the one dev who remembers how it works.”
When hiring it out makes sense
Building your first production bridge in-house typically costs weeks of a senior developer’s time plus the crash-hunting tax afterwards. A specialist who has built these before delivers a tested, packaged bridge in a fraction of that — with the threading, stripping, and dependency traps already handled.
If that’s the position you’re in, this is one of my specialties: I build native plugins and SDK-to-Unity bridges for client teams, delivered as clean UPM packages. Tell me about your SDK and I’ll give you an honest estimate — including whether you even need a custom bridge at all.