This document provides an API reference for the Swift project type in Unity.
You can use native plug-ins to pause and resume the execution of the Unity Player. When you call the pause() method, Unity pauses execution after the current player loop finishes. Unity also invokes MonoBehaviour.OnApplicationPause with a true parameter.
When you call resume(), Unity calls OnApplicationPause with a false parameter, and the player loop continues as normal. The isPaused() method returns true after you call pause(), and false after you call resume().
Public API: UnityPlayer class
static var shared: UnityPlayerfunc pause()func resume()func isPaused() -> BoolUsage examples:
Use the following code format for Swift plug-ins:
UnityPlayer.shared.isPaused()
UnityPlayer.shared.pause()
UnityPlayer.shared.resume()
Use the following code format for Objective-C plug-ins:
[[UnityPlayer shared] isPaused]
[[UnityPlayer shared] pause]
[[UnityPlayer shared] resume]
Use the following Lifecycle APIs to allow a plug-in to react to application lifecycle events.
On iOS, applications typically handle lifecycle events in UIApplicationDelegate or UISceneDelegate. However, an application can only have one delegate, which is a challenge because multiple plug-ins, including Unity’s internal UnityPlayer, often need to handle these events. To solve this, Unity provides a mechanism to share these events with plug-ins through notifications.
To receive these events, subscribe to the notification center using NSNotificationCenter in Objective-C or NotificationCenter in Swift. To avoid duplicating existing system notifications, Unity provides only the notifications that are otherwise unavailable.
The following notifications are available:
| Notification | Type | Description |
|---|---|---|
class UnityNotifications |
object | A class object to store the notification references. |
UnityNotifications.applicationWillFinishLaunching |
var |
UnityPlayer posts this notification after it handles application(_:willFinishLaunchingWithOptions:). |
UnityNotifications.applicationDidFailToRegisterForRemoteNotifications |
var |
UnityPlayer posts this notification after it handles application(_:didFailToRegisterForRemoteNotificationsWithError:). The notification’s userInfo dictionary contains the registration error under the remoteNotificationsErrorKey key. |
UnityNotifications.remoteNotificationsErrorKey |
var | A string value for the dictionary key for the error value. |
UnityNotifications.applicationDidReceiveRemoteNotification |
var |
UnityPlayer posts this notification after it handles application(_:didReceiveRemoteNotification:fetchCompletionHandler:). The notification’s userInfo dictionary contains the remote notification payload and the fetch completion handler under the remoteNotificationFetchCompletionHandlerKey, wrapped in a UnityRemoteNotificationCompletionHandler. Refer to Claim completion handlers for notifications for more information. |
UnityNotifications.applicationDidRegisterForRemoteNotifications |
var |
UnityPlayer posts this notification after it handles application(_:didRegisterForRemoteNotificationsWithDeviceToken:). The notification’s userInfo dictionary contains the device token under the remoteNotificationsDeviceTokenKey key. |
UnityNotifications.remoteNotificationsDeviceTokenKey |
var | A string value for the dictionary key that contains the device token. |
UnityNotifications.applicationHandleEventsForBackgroundURLSession |
var |
UnityPlayer posts this notification after it handles application(_:handleEventsForBackgroundURLSession:completionHandler:). The notification’s userInfo dictionary contains both the URL session identifier under the backgroundURLSessionIdentifierKey, and the completion handler under the backgroundURLSessionCompletionHandlerKey key wrapped in a UnityBackgroundURLSessionCompletionHandler. Refer to Claim completion handlers for notifications for more information. |
UnityNotifications.backgroundURLSessionIdentifierKey |
var | A string value for the dictionary key that contains the URL session identifier. |
UnityNotifications.backgroundURLSessionCompletionHandlerKey |
var | A string value for the dictionary key that contains the completion handler block. |
UnityNotifications.sceneOpenURLContexts |
var |
UnityPlayer posts this notification after it handles scene(_:openURLContexts:). The notification’s userInfo dictionary contains the scene instance under sceneKey and the URL contexts set under openURLContextsKey. |
UnityNotifications.sceneKey |
var | A string value for the dictionary key that contains the scene instance. |
UnityNotifications.openURLContextsKey |
var | A string value for the dictionary key that contains the set of URL contexts. |
UnityNotifications.unityDidInitializeRuntime |
var |
UnityPlayer posts this notification when the Unity runtime initializes, before any game logic or rendering starts. This provides an opportunity for low-level plug-ins to initialize before the first scene loads. At this point, the Unity runtime is ready but no game code is running. |
UnityNotifications.unityDidUnload |
var |
UnityPlayer posts this notification when Application.Unload is called from C# scripting. |
UnityNotifications.unityDidQuit |
var |
UnityPlayer posts this notification when Application.Quit is called from C# scripting. |
Unity provides proxy implementations of UIApplicationDelegate and UISceneDelegate that pass all events to the UnityPlayer for internal handling. You can replace these default implementations with your own.
To ensure Unity continues to work as expected, your custom implementation must call the respective UnityPlayer methods. The following list shows the required calls:
UnityPlayer.application(_:willFinishLaunchingWithOptions:)
UnityPlayer.application(_:didFinishLaunchingWithOptions:)
UnityPlayer.application(_:didRegisterForRemoteNotificationsWithDeviceToken:)
UnityPlayer.application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
UnityPlayer.application(_:didFailToRegisterForRemoteNotificationsWithError:)
UnityPlayer.application(_:handleEventsForBackgroundURLSession:completionHandler:)
UnityPlayer.applicationWillTerminate(_:)
UnityPlayer.scene(_:willConnectTo:options:)
UnityPlayer.sceneWillResignActive(_:)
UnityPlayer.sceneDidBecomeActive(_:)
UnityPlayer.scene(_:openURLContexts:)
Note: Forcing orientation from C# scripts doesn’t work with a custom delegate implementation. If you replace the delegates, you’re responsible for your own application configuration, including any necessary orientation handling.
Two of the notifications in the previous table deliver a system completion handler that you must call after you finish processing the event: UnityNotifications.applicationDidReceiveRemoteNotification and UnityNotifications.applicationHandleEventsForBackgroundURLSession. Because any number of plug-ins can observe the same notification, Unity doesn’t pass the raw handler block directly. Instead, it wraps the handler in a class that guarantees the handler runs exactly once. Unity delivers the wrapper in the notification’s userInfo dictionary:
UnityNotifications.applicationDidReceiveRemoteNotification provides a UnityRemoteNotificationCompletionHandler under the remoteNotificationFetchCompletionHandlerKey key.UnityNotifications.applicationHandleEventsForBackgroundURLSession provides a UnityBackgroundURLSessionCompletionHandler under the backgroundURLSessionCompletionHandlerKey key.To take ownership of the handler, call claim() from inside your notification callback. The first caller to claim the handler receives the underlying block and becomes responsible for invoking it. Every subsequent call returns nil. If claim() returns nil, another plug-in or Unity itself has already taken the handler, so your plug-in must not call it. Check isClaimed to determine whether the handler is still available before you claim it.
Follow these rules when you work with the wrappers:
UIBackgroundFetchResult.noData for remote notifications), and the wrapper is no longer valid.claim() only while the notification is being delivered, synchronously from your observer callback. Claiming after the notification completes triggers an assertion failure.UIBackgroundFetchResult.
Public API: UnityRemoteNotificationCompletionHandler class
This class wraps the completion handler from application(_:didReceiveRemoteNotification:fetchCompletionHandler:).
init(_ handler: @escaping (UIBackgroundFetchResult) -> Void): Wraps a remote notification completion handler. Unity creates the instance for you. Don’t construct it directly.var isClaimed: Bool: Returns true after the handler has been claimed, which indicates that another plug-in is handling the event.func claim() -> ((UIBackgroundFetchResult) -> Void)?: Returns the wrapped handler the first time you call it, and nil on every subsequent call. Invoke the returned handler with a UIBackgroundFetchResult once you finish processing the notification.
Public API: UnityBackgroundURLSessionCompletionHandler class
This class wraps the completion handler from application(_:handleEventsForBackgroundURLSession:completionHandler:).
init(_ handler: @escaping () -> Void): Wraps a background URL session completion handler. Unity creates the instance for you. Don’t construct it directly.var isClaimed: Bool: Returns true after the handler has been claimed, which indicates that another plug-in is handling the event.func claim() -> (() -> Void)?: Returns the wrapped handler the first time you call it, and nil on every subsequent call. Invoke the returned handler once you finish handling the events for the session.
Note: Both wrappers are thread-safe. isClaimed and claim() can be called safely from any thread.
Usage examples:
Use the following example to understand how to handle a remote notification:
NotificationCenter.default.addObserver(
forName: UnityNotifications.applicationDidReceiveRemoteNotification,
object: nil,
queue: nil
) { notification in
guard let wrapper = notification.userInfo?[UnityNotifications.remoteNotificationFetchCompletionHandlerKey]
as? UnityRemoteNotificationCompletionHandler else { return }
// Decide whether this notification belongs to your plug-in.
// If it does, claim the handler and invoke it when you're done.
if let handler = wrapper.claim() {
// ... process the notification ...
handler(.newData)
}
// If claim() returns nil, another plug-in already handled it, so do nothing.
}
Use the following example to understand how to handle a background URL session:
NotificationCenter.default.addObserver(
forName: UnityNotifications.applicationHandleEventsForBackgroundURLSession,
object: nil,
queue: nil
) { notification in
guard let identifier = notification.userInfo?[UnityNotifications.backgroundURLSessionIdentifierKey] as? String,
let wrapper = notification.userInfo?[UnityNotifications.backgroundURLSessionCompletionHandlerKey]
as? UnityBackgroundURLSessionCompletionHandler else { return }
// Make sure the session identifier is yours before you claim the handler.
if identifier == myBackgroundSessionIdentifier, let handler = wrapper.claim() {
// ... finish handling the events for the session ...
handler()
}
}
To send a message from your plug-in to a C# script, you can use the UnitySendMessage function. The public API for UnitySendMessage is as follows:
Symbol:
void UnitySendMessage(const char* gameObjectName, const char* method, const char* argument);
UnityPlayer function:
func sendMessage(toGameObject:method:argument:)
This function is equivalent to the GameObject.SendMessage method in the scripting API, with the following differences:
NULL or nil as the argument.The message is sent asynchronously. You can call these functions from any thread, but Unity calls the scripting method only on the main thread.
Samples:
To test this example, attach this C# script to a GameObject and rename the object ObjectName:
using UnityEngine;
public class NewMonoBehaviourScript : MonoBehaviour
{
public void MyMethod()
{
Debug.Log("MyMethod called");
}
public void MyMethodWithArg(string argument)
{
Debug.Log($"MyMethodWithArg called with '{argument}'");
}
}
Then, depending on your plug-in language (Swift, Objective C, or C++), use the following code to send a message to your GameObject and invoke its C# methods. Swift:
UnityPlayer.shared.sendMessage(toGameObject: "ObjectName", method: "MyMethod")
UnityPlayer.shared.sendMessage(toGameObject: "ObjectName", method: "MyMethodWithArg", argument: "argument")
Objective-C:
[UnityPlayer.shared sendMessageToGameObject:@"ObjectName" method:@"MyMethod" argument:nil];
[UnityPlayer.shared sendMessageToGameObject:@"ObjectName" method:@"MyMethodWithArg" argument:@"argument"];
C/C++:
UnitySendMessage("ObjectName", "MyMethod", NULL);
UnitySendMessage("ObjectName", "MyMethodWithArg", "argument");
To use UnitySendMessage from Objective-C, C++, or C, import the UnityPluginInterface.h header.
To present native content on top of the Unity view, you can get the view or view controller that Unity renders to. Use the following properties to access them:
renderingView: The same view that Unity renders to.rootViewController: The root view controller of the window where the Unity view is rendering.You can access the view and view controller that Unity renders to through the following UnityPlayer properties:
UnityPlayer:
renderingView: UIView?
rootViewController: UIViewController?
Unity supports the low-level native plug-in API on iOS. The following registration functions are exposed:
UnityRegisterAudioPlugin(UnityPluginGetAudioEffectDefinitionsFunc getAudioEffectDefinitions)UnityRegisterPlugin(UnityPluginLoadFunc loadPlugin, UnityPluginUnloadFunc unloadPlugin)The necessary headers are located in the UnityAPI/UnityPluginInterface/ directory.
These are:
IUnityEventQueue.h
IUnityGraphics.h
IUnityGraphicsMetal.h
IUnityInterface.h
IUnityLog.h
IUnityMemoryManager.h
IUnityProfiler.h
IUnityProfilerCallbacks.h
IUnityRenderingExtensions.h
You must load low-level plug-ins after the Unity runtime initializes. On iOS, subscribe to UnityNotifications.unityDidInitializeRuntime and register the plug-in when the notification is sent. This is the recommended registration point because it occurs after the Unity runtime initializes but before the first scene loads. You can also register plug-ins later from other iOS notifications or directly from your C# scripts.
Note: The UnityNotifications.unityDidInitializeRuntime registration timing is a requirement for spatial audio plug-ins setup in the first scene. If a scene in your application contains a spatial audio source, you must register the plug-in before that scene loads.
You can use the PBXProject API in a C# post-process build step for both C# and Swift projects. To identify which project type is built, use the UnityEditor.PlayerSettings.XcodeProjectType property.
The Swift project type adds a UnityAPI target alongside the existing Unity-iPhone and UnityFramework targets. Use PBXProject.GetUnityAPITargetGuid to get its GUID, for example to add build settings or link libraries to it. This target exists only for the Swift project type, so the method returns null for the Objective-C project type; check the result for null before you use it.
Note: The Xcode project name now matches the Unity project name. To avoid issues with hard-coded project names in your plug-ins, update them to use the PBXProject.GetPBXProjectPath API.
Unity defines a preprocessor macro, UNITY_XCODE_PROJECT_TYPE_SWIFT, that you can use to conditionally compile code for the Swift project type.
Usage:
#if UNITY_XCODE_PROJECT_TYPE_SWIFT
<Swift trampoline specific code>
#endif