# Initialization paths for native iOS plug-ins

> Learn about the different initialization paths available for native iOS plug-ins.

Learn about the different initialization paths available for native iOS plug-ins.

Unity and Apple platforms provide multiple mechanisms for initializing a native plug-in. The best approach depends on whether you need to initialize the plug-in early (at application startup) or lazily (on its first use). You can perform initialization from managed C# code, native code, or within Unity's generated Xcode project code.

## Managed C# initialization paths

* **RuntimeInitializeOnLoadMethodAttribute**: Automatically runs a method at different points in the application lifecycle, such as `BeforeSplashScreen` or `AfterSceneLoad`. Use `RuntimeInitializeOnLoadMethodAttribute` to initialize your plug-in’s C# API and make the first call into native code. For more information, refer to [RuntimeInitializeOnLoadMethodAttribute](/engine/6000.6/script-reference/unityengine/runtimeinitializeonloadmethodattribute.md).
* **SceneManager Callbacks**: Use `SceneManager.sceneLoaded` and `SceneManager.sceneUnloaded` for lazy initialization tied to specific scene content.
* **MonoBehaviour Lifecycle**: Use standard `MonoBehaviour` methods like `Awake`, `OnEnable`, and `Start` for initialization tied to a `GameObject`'s lifecycle. Refer to [Event function execution order](/engine/6000.6/manual/scripting/managing-update-order/execution-order.md) for more information.

## Native initialization paths

The native initialization paths and their timing differ depending on your plug-in's language. Swift follows a different path than C++ or Objective-C. The following sections outline the various initialization paths available for native code.

### C++ and Objective-C++ initialization paths

You can use a global C++ object's constructor to run code before `main()` and its destructor to run code after `main()` completes. A global C++ object constructor is invoked automatically when the application binary loads and its destructor is invoked when the binary unloads.

#### Characteristics:

* **Timing**: Before `main()`.
* **Execution order**: Non-deterministic.
* **Unity state**: Unity isn't initialized.
* **Execution**: Triggered automatically on binary load and unload.
* **Compatibility**: Works with `.c`, `.cpp`, `.m`, `.mm`, and `.a` files.
* **Dependency**: Behavior depends on `UnityFramework.framework` linking (static versus dynamic).

#### Code example

```lang-c
// Global object — constructor runs before main(), destructor after main()

struct GlobalFoo {
    GlobalFoo() {
        std::cout << "GlobalFoo constructor running!\n";
    }

    ~GlobalFoo() {
        std::cout << "GlobalFoo destructor running!\n";
    }
};

GlobalFoo g_foo;
```

### Clang and GCC initialization paths

This method uses the `__attribute__((constructor))` and `__attribute__((destructor))` attributes to register functions that run when a library loads and unloads.

#### Characteristics:

* **Timing:** Runs before `main()`.
* **Execution order:** Non-deterministic.
* **Unity state:** Unity isn't initialized.
* **Execution:** Triggered automatically on binary load and unload.
* **Compatibility:** Works with `.c`, `.cpp`, `.m`, and `.mm` files.
* **Dependency:** Behavior depends on `UnityFramework.framework` linking.

#### Example

```lang-c
// runs before main
__attribute__((constructor))
static void MyInit() {
    printf("Init called\n");
}

// after program exit/shared library unload
__attribute__((destructor))
static void MyDone() {
    printf("Done called\n");
}
```

### Objective-C

These methods are for use in `.m` and `.mm` files.

#### +load

The `+load` method is executed by the Objective-C runtime when a class loads, which occurs before `main()` and before C++ global constructors.

##### Characteristics:

* **Timing:** Early. Runs before `main()`.
* **Execution order:** Non-deterministic.
* **Unity state:** Unity isn't initialized.
* **Execution:** Runs automatically for every class and category that implements it, even if never referenced. Can't be disabled.
* **Compatibility:** Works with `.m` and `.mm` files.
* **Dependency:** Behavior depends on `UnityFramework.framework` linking.

##### Example

```lang-c
// Runs as soon as the Obj-C runtime loads the class (before main()).
// Categories get +load before classes
@implementation MyClass
+ (void)load {
    NSLog(@"+load called");
}
@end
```

### +initialize

The `+initialize` method is invoked lazily, just before the first message is sent to the class. It's ideal for on-demand initialization.

#### Characteristics:

* **Timing:** Runs on the first message sent to the class.
* **Execution order:** Deterministic.
* **Unity state:** Unity might be initialized, depending on when the first message is sent.
* **Execution:** Lazy. Doesn't run if the class is never used, thread-safe, and runs exactly once per class.
* **Compatibility:** Works with `.m` and `.mm` files.

#### Example:

```lang-c
// Called on first message dispatch to the class
@implementation MyClass
+ (void)initialize {
    NSLog(@"+initialize called");
}
@end
```

### Swift

In Swift, global variables and objects are lazily initialized. This means the `NativeManager` constructor runs only when the `manager` object is accessed for the first time. The initial access occurs when calling `GetValueFromManager`.

#### Characteristics:

* **Timing:** On first use.
* **Execution order:** Deterministic.
* **Execution:** Lazy.

#### Example:

```lang-swift
class NativeManager {
init() { rint("NativeManager initialized") }
func value() -> Int { return 42 }
}

// global object
let manager = NativeManager()

@_cdecl("GetValueFromManager")
public func GetValueFromManager() -> Int { return manager.value() }
```

### Change App Controller Class

You can modify the Unity-provided `AppController` class to customize your application's startup behavior. The `IMPL_APP_CONTROLLER_SUBCLASS` macro achieves this by replacing Unity’s default `AppController` class with your own custom Objective-C subclass.

`IMPL_APP_CONTROLLER_SUBCLASS` works as follows:

1. Declare an Objective-C category on your subclass.
2. Use `+load` (executed before `main()`) to override the global `AppControllerClassName` symbol that Unity uses to decide which `UIApplicationDelegate` or `AppController` class to instantiate.

Use `IMPL_APP_CONTROLLER_SUBCLASS` if you need early lifecycle hooks, such as:

* `preStartUnity`
* `startUnity`
* `initUnityWithScene`
* `application:didFinishLaunchingWithOptions`
* `applicationDidEnterBackground`
* `applicationWillTerminate`
* App-level system integrations that must run before Unity initializes.

#### Characteristics:

* **Dependency:** Only compatible with an Objective-C project type.
* **Compatibility:** Works with `.m` and `.mm` files.

#### Code example:

```lang-c
// MyAppController.mm
#import "UnityAppController.h"

// Custom AppController
@interface MyAppController : UnityAppController
@end

@implementation MyAppController

    (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
    {
    NSLog(@"MyAppController didFinishLaunching");
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
    }
    @end

// Register this class as Unity's AppController
IMPL_APP_CONTROLLER_SUBCLASS(MyAppController)
```

## Additional resources

* [Configure a plug-in for iOS with the Inspector window](/engine/6000.6/manual/platform-specific/iphone/ios-developing/plugins-for-ios/ios-native-plugin-automated-integration.md)
* [Conditional compilation behavior for native iOS plug-ins](/engine/6000.6/manual/platform-specific/iphone/ios-developing/plugins-for-ios/ios-native-plugin-conditional-compilation.md)
