I am writing iOS plugins for Unity. I need to call the function below from Unity. The target function is written in Swift.
How can I convert Swift completion block/closure to C#.
What should I write in place of completionHandler
?
#if UNITY_IOS
[DllImport("__Internal")]
private static extern void initializeSDK(string name, string apiKey, completionHandler );
#endif
static func init(name: String?, apiKey: String?, completionHandler: @escaping (Bool) -> Void) {
// do some stuffs..
completionHandler(status) // status is of Bool type.
}
CodePudding user response:
If I understand correctly, completionHandler
seems to be a callback and if so we can use p-invoke delegate prototypes.
Given this native code:
static func init(name: String?, apiKey: String?, completionHandler: @escaping (Bool) -> Void) {
...we define the prototype of:
public delegate void MyCompletionHandler(bool x);
...and use it in this p-invoke import:
#if UNITY_IOS
[DllImport("__Internal")]
private static extern void initializeSDK(string name, string apiKey, MyCompletionHandler handler);
#endif
Complete:
#if UNITY_IOS
public delegate void MyCompletionHandler(bool x);
[DllImport("__Internal")]
private static extern void initializeSDK(string name, string apiKey, MyCompletionHandler handler);
#endif
You can use
Tell me more
CodePudding user response:
When dealing with Unity, include a MonoPInvokeCallback attribute decorated method. So, your definition would look like this:
[DllImport("__Internal")]
private static extern void initializeSDK( string name, string apiKey, Action<bool> completionHandler );
And your callback method would look like this:
[MonoPInvokeCallback ( typeof ( Action<bool> ) )]
private static void completionHandler ( bool success )
{
Debug.Log ( $"completionHandler ({success})" );
}
And to start the ball rolling, you would call your plugin method like so:
initializeSDK("myApp1","122332443",completionHandler);
Full Code:
using UnityEngine;
using System.Runtime.InteropServices;
using System;
using AOT;
public static class AwesomeShow
{
#if UNITY_IOS
[DllImport("__Internal")]
private static extern void AwesomeSDK_runNativeCode(string name);
[DllImport("__Internal")]
static extern long AwesomeSDK_toNumber(string numberString);
[DllImport("__Internal")]
private static extern void AwesomeSDK_initializeSDK(string name, string apiKey, Action<bool> completionHandler);
#endif
[MonoPInvokeCallback ( typeof ( Action<bool> ) )]
private static void completionHandler ( bool success )
{
Debug.Log ( "result is: " success );
}
public static void RunNativeCode ( string name )
{
#if UNITY_IOS
AwesomeSDK_runNativeCode(name);
Debug.Log("number is " AwesomeSDK_toNumber("30"));
AwesomeSDK_initializeSDK("myApp1","122332443",completionHandler);
#else
Debug.Log ( "No ios device" );
#endif
}
}