Swift project type API reference
API documentation and reference for Swift project type.
Read time 11 minutesLast updated 20 days ago
This document provides an API reference for the Swift project type in Unity.
- Pause and Resume
- Lifecycle events
- Claim notification completion handlers
- Send messages to C# scripts
- Display content on top of applications
- Low-level native plug-in API
- PBXProject API
- Identify a Swift project type
Pause and resume the Unity Player
You can use native plug-ins to pause and resume the execution of the Unity Player. When you call the method, Unity pauses execution after the current player loop finishes. Unity also invokes with a parameter.
pause()MonoBehaviour.OnApplicationPausetrueWhen you call , Unity calls with a parameter, and the player loop continues as normal. The method returns after you call , and after you call .
resume()OnApplicationPausefalseisPaused()truepause()falseresume()Public API: class
UnityPlayerstatic var shared: UnityPlayerfunc pause()func resume()func isPaused() -> Bool
Usage 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]
Listen for lifecycle events
Use the following Lifecycle APIs to allow a plug-in to react to application lifecycle events.
On iOS, applications typically handle lifecycle events in or . However, an application can only have one delegate, which is a challenge because multiple plug-ins, including Unity's internal , often need to handle these events. To solve this, Unity provides a mechanism to share these events with plug-ins through notifications.
UIApplicationDelegateUISceneDelegateUnityPlayerTo receive these events, subscribe to the notification center using in Objective-C or in Swift. To avoid duplicating existing system notifications, Unity provides only the notifications that are otherwise unavailable.
NSNotificationCenterNotificationCenterThe following notifications are available:
Notification | Type | Description |
|---|---|---|
| object | A class object to store the notification references. |
| var | |
| var | |
| var | A string value for the dictionary key for the error value. |
| var | |
| var | A string value for the dictionary key that contains the remote notification payload. |
| var | A string value for the dictionary key that contains the completion handler, wrapped in a |
| var | |
| var | A string value for the dictionary key that contains the device token. |
| var | |
| var | A string value for the dictionary key that contains the URL session identifier. |
| var | A string value for the dictionary key that contains the completion handler block. |
| var | |
| var | A string value for the dictionary key that contains the scene instance. |
| var | A string value for the dictionary key that contains the set of URL contexts. |
| var | |
| var | A string value for the dictionary key that contains the |
| var | |
| var | |
| var | |
Unity provides proxy implementations of and that pass all events to the for internal handling. You can replace these default implementations with your own.
UIApplicationDelegateUISceneDelegateUnityPlayerTo ensure Unity continues to work as expected, your custom implementation must call the respective methods. The following list shows the required calls:
UnityPlayerUnityPlayer.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.sceneDidEnterBackground(_:)UnityPlayer.sceneWillEnterForeground(_:)UnityPlayer.sceneWillResignActive(_:)UnityPlayer.sceneDidBecomeActive(_:)UnityPlayer.scene(_:openURLContexts:)UnityPlayer.scene(_:continue:)
Claim completion handlers for notifications
Two of the notifications in the previous table deliver a system completion handler that you must call after you finish processing the event: and . 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 dictionary:
UnityNotifications.applicationDidReceiveRemoteNotificationUnityNotifications.applicationHandleEventsForBackgroundURLSessionuserInfo- provides a
UnityNotifications.applicationDidReceiveRemoteNotificationunder theUnityRemoteNotificationCompletionHandlerkey.remoteNotificationFetchCompletionHandlerKey - provides a
UnityNotifications.applicationHandleEventsForBackgroundURLSessionunder theUnityBackgroundURLSessionCompletionHandlerkey.backgroundURLSessionCompletionHandlerKey
To take ownership of the handler, call 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 . If returns , another plug-in or Unity itself has already taken the handler, so your plug-in must not call it. Check to determine whether the handler is still available before you claim it.
claim()nilclaim()nilisClaimedFollow these rules when you work with the wrappers:
- Claim the underlying handler rather than keeping a reference to the wrapper. After the notification finishes, Unity invokes any unclaimed handler (using for remote notifications), and the wrapper is no longer valid.
UIBackgroundFetchResult.noData - Call only while the notification is being delivered, synchronously from your observer callback. Claiming after the notification completes triggers an assertion failure.
claim() - If you claim the handler, you must invoke it once you finish handling the event. For remote notifications, pass the appropriate .
UIBackgroundFetchResult
Public API: class
UnityRemoteNotificationCompletionHandlerThis class wraps the completion handler from .
application(_:didReceiveRemoteNotification:fetchCompletionHandler:)- : Wraps a remote notification completion handler. Unity creates the instance for you. Don't construct it directly.
init(_ handler: @escaping (UIBackgroundFetchResult) -> Void) - : Returns
var isClaimed: Boolafter the handler has been claimed, which indicates that another plug-in is handling the event.true - : Returns the wrapped handler the first time you call it, and
func claim() -> ((UIBackgroundFetchResult) -> Void)?on every subsequent call. Invoke the returned handler with anilonce you finish processing the notification.UIBackgroundFetchResult
Public API: class
UnityBackgroundURLSessionCompletionHandlerThis class wraps the completion handler from .
application(_:handleEventsForBackgroundURLSession:completionHandler:)- : Wraps a background URL session completion handler. Unity creates the instance for you. Don't construct it directly.
init(_ handler: @escaping () -> Void) - : Returns
var isClaimed: Boolafter the handler has been claimed, which indicates that another plug-in is handling the event.true - : Returns the wrapped handler the first time you call it, and
func claim() -> (() -> Void)?on every subsequent call. Invoke the returned handler once you finish handling the events for the session.nil
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() }}
Send messages to C# scripts
To send a message from your plug-in to a C# script, you can use the function. The public API for is as follows:
UnitySendMessageUnitySendMessageSymbol:
void UnitySendMessage(const char* gameObjectName, const char* method, const char* argument);UnityPlayer function:func sendMessage(toGameObject:method:argument:)
This function is equivalent to the method in the scripting API, with the following differences:
GameObject.SendMessage- You identify the GameObject by its name.
- A receiver isn't required.
- The argument can only be a string. To call a method without parameters, pass or
NULLas the argument.nil
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 :
ObjectNameusing 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 from Objective-C, C++, or C, import the header.
UnitySendMessageUnityPluginInterface.hDisplay content on top of applications
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:
- : The same view that Unity renders to.
renderingView - : The root view controller of the window where the Unity view is rendering.
rootViewController
You can access the view and view controller that Unity renders to through the following properties:
UnityPlayerUnityPlayer:renderingView: UIView?rootViewController: UIViewController?
Use the low-level native plug-in API
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 directory.
UnityAPI/UnityPluginInterface/These are:
IUnityEventQueue.hIUnityGraphics.hIUnityGraphicsMetal.hIUnityInterface.hIUnityLog.hIUnityMemoryManager.hIUnityProfiler.hIUnityProfilerCallbacks.hIUnityRenderingExtensions.h
You must load low-level plug-ins after the Unity runtime initializes. On iOS, subscribe to 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.
UnityNotifications.unityDidInitializeRuntimePBXProject API
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 property.
UnityEditor.PlayerSettings.XcodeProjectTypeThe Swift project type adds a target alongside the existing and targets. Use 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 for the Objective-C project type; check the result for before you use it.
UnityAPIUnity-iPhoneUnityFrameworkPBXProject.GetUnityAPITargetGuidnullnullIdentify a Swift project type
Unity defines a preprocessor macro, , that you can use to conditionally compile code for the Swift project type.
UNITY_XCODE_PROJECT_TYPE_SWIFTUsage:
#if UNITY_XCODE_PROJECT_TYPE_SWIFT <Swift trampoline specific code>#endif