Unity和iOS 原生专题二 Unity和iOS原生交互相互传值的两个方案

一 、方案一 通过指针传值和使用 MonoPInvokeCallback 从C#层向C层注册回调函数

1.1 iOS调用Unity函数Unity 给iOS传值

第一步C#端 定义 C#调用 ios 原生函数标识 固定写法

cs 复制代码
 /// <summary>
        /// 定义 C#调用 ios 原生函数标识 固定写法
        /// </summary>
        private const string DLLName = "__Internal";
        [UsedImplicitly, DllImport(DLLName)]
        private static extern void MobileNumberAuthiOS_Initialize(string secret, AliMobileAuthLogCallback logCallback,
            NumberAuthInitCallback initCallback);

第二步C#端 定义c# 传递到原生的的委托代理

cs 复制代码
 /// <summary>
        /// 定义c# 传递到原生的的委托代理,接收ios原生回传的值
        /// </summary>
        private delegate void AliMobileAuthLogCallback(string log);

        private delegate void NumberAuthInitCallback(int success, string msg);

第三步C# 端 定义C#端的代理函数,接收ios 传递过来的值

cs 复制代码
 /// <summary>
        /// 定义C#端的代理函数,用于接收ios 传递过来的值
        /// </summary>
        /// <param name="log"></param>
        [MonoPInvokeCallback(typeof(AliMobileAuthLogCallback))]
        private static void HandleOnAliMobileAuthLogCallback(string log)
        {
            InfoLog(log);
        }

        [MonoPInvokeCallback(typeof(NumberAuthInitCallback))]
        private static void HandleOnSmsAuthInitCallback(int success, string msg)
        {
            InfoLog($"开始初始化回调,success:{success} msg: {msg}");
            _initializeCallback?.Invoke(success, msg);
        }

第四步 C#端 调用上面定的调用ios 的函数

cs 复制代码
  /// C# 调用上面定的调用ios 的函数 ,secret 参数,HandleOnAliMobileAuthLogCallback,HandleOnSmsAuthInitCallback 要传递过去的代理函数
            MobileNumberAuthiOS_Initialize(secret, HandleOnAliMobileAuthLogCallback, HandleOnSmsAuthInitCallback);

第五步 ios 端 ios 定义c#调用的ios 方法 固定写法

objectivec 复制代码
///ios 定义c#调用的ios 方法  固定写法
#if defined(__cplusplus)
extern "C" {
#endif
    void MobileNumberAuthiOS_Initialize(const char* secret ,void(*aliMobileAuthLogCallback)(const char* log), void(*initSDKCallback)(int, const char * )){
        ///将c#的代理指针赋值给ios的块指针
        AliMobileAuthLogCallback = aliMobileAuthLogCallback;
        InitSDKCallback = initSDKCallback;
        ///调用ios的方法
        [[AliMobileNumberAuth sharedManager] Initialize:secret];
    }
    
#if defined(__cplusplus)
}
#endif

第六步ios 端 定义接收c#要传递过来的代理指针

objectivec 复制代码
///定义接收c#要传递过来的代理指针
static void (*AliMobileAuthLogCallback)(const char* log);
static void(*InitSDKCallback)(int,const char *);

第七步ios 端 在ios函数中 回调c#的代码函数,将ios这边的值传递到c#

objectivec 复制代码
-(void)Initialize:(const char*)key {
    ///接收c#传递过来的值
    NSString * dataString  = [NSString stringWithFormat:@"%s",key];
    ///ios 回调c#的代码函数,将ios这边的值传递到c#
    if (InitSDKCallback) {
        NSString * dataString = @"回传值";
        int code = 1;
      InitSDKCallback(code,[dataString UTF8String]);
      }
    
}

以上就是unity和ios 原生交互 通过指针传值和代理(delegate)回传值 定义和接收值的完整实现过程

第八步 C# 和ios 完整代码部分

8.1 ios 代码
objectivec 复制代码
//ios 代码
#import "AliMobileNumberAuth.h"


///定义接收c#要传递过来的代理指针
static void (*AliMobileAuthLogCallback)(const char* log);
static void(*InitSDKCallback)(int,const char *);


static bool EnableLog;
@interface  AliMobileNumberAuth()
@end

@implementation AliMobileNumberAuth

///ios 定义c#调用的ios 方法  固定写法
#if defined(__cplusplus)
extern "C" {
#endif
    void MobileNumberAuthiOS_Initialize(const char* secret ,void(*aliMobileAuthLogCallback)(const char* log), void(*initSDKCallback)(int, const char * )){
        ///将c#的代理指针赋值给ios的块指针
        AliMobileAuthLogCallback = aliMobileAuthLogCallback;
        InitSDKCallback = initSDKCallback;
        ///调用ios的方法
        [[AliMobileNumberAuth sharedManager] Initialize:secret];
    }
    
#if defined(__cplusplus)
}
#endif

-(void)Initialize:(const char*)key {
    ///接收c#传递过来的值
    NSString * dataString  = [NSString stringWithFormat:@"%s",key];
    ///ios 回调c#的代码函数,将ios这边的值传递到c#
    if (InitSDKCallback) {
        NSString * dataString = @"回传值";
        int code = 1;
      InitSDKCallback(code,[dataString UTF8String]);
      }
    
}
#pragma mark - LifeCycle
+(instancetype)sharedManager {
    static dispatch_once_t onceToken;
    static AliMobileNumberAuth *instance;
    dispatch_once(&onceToken, ^{
        instance = [[AliMobileNumberAuth alloc] init];
    });
    return instance;
}
}
8.2 c# 代码
cs 复制代码
using System;
using System.Runtime.InteropServices;
using AOT;
using Bao.Debug;
using JetBrains.Annotations;

namespace Bao.Account.SDK
{
    public class MobileNumberAuthiOS 
    {
        #region 初始化🇭相关

        public static MobileNumberAuthiOS _instance;
        public static  Action<int, string> _initializeCallback;
       
        private Action<bool, string> _heckEnvironmentCallback;
        private Action<bool, string> _getTokenCallback;

        
        /// <summary>
        /// 定义c# 传递到原生的的委托代理,接收ios原生回传的值
        /// </summary>
        private delegate void AliMobileAuthLogCallback(string log);

        private delegate void NumberAuthInitCallback(int success, string msg);

        #endregion

        #region Native Methods
#if UNITY_IOS 
        /// <summary>
        /// 定义 C#调用 ios 原生函数标识 固定写法
        /// </summary>
        private const string DLLName = "__Internal";
        [UsedImplicitly, DllImport(DLLName)]
        private static extern void MobileNumberAuthiOS_Initialize(string secret, AliMobileAuthLogCallback logCallback,
            NumberAuthInitCallback initCallback);
#endif
        #endregion

        private static void InfoLog(string msg)
        {
            LogFile.get.Log($"阿里一键登录, iOS, {msg}");
        }
        
        public void Initialize(string secret, Action<int, string> callback, bool enableLog)
        {
            /// C# 调用上面定的调用ios 的函数 ,secret 参数,HandleOnAliMobileAuthLogCallback,HandleOnSmsAuthInitCallback 要传递过去的代理函数
            MobileNumberAuthiOS_Initialize(secret, HandleOnAliMobileAuthLogCallback, HandleOnSmsAuthInitCallback);
        }
        
        /// <summary>
        /// 定义C#端的代理函数,用于接收ios 传递过来的值
        /// </summary>
        /// <param name="log"></param>
        [MonoPInvokeCallback(typeof(AliMobileAuthLogCallback))]
        private static void HandleOnAliMobileAuthLogCallback(string log)
        {
            InfoLog(log);
        }

        [MonoPInvokeCallback(typeof(NumberAuthInitCallback))]
        private static void HandleOnSmsAuthInitCallback(int success, string msg)
        {
            InfoLog($"开始初始化回调,success:{success} msg: {msg}");
            _initializeCallback?.Invoke(success, msg);
        }

    }
}

private delegate void OnViewClosed(int result, string msg);   // 

[MonoPInvokeCallback(OnViewClosed)]
static void CalledByNativeC(int result, string msg)
{
    // some logic here
}

// ... 

#if UNITY_IPHONE || UNITY_IOS
[DllImport("__Internal")]
private static extern void SetOnViewClosed(OnViewClosed);
#endif

// ...
SetOnViewClosed(CalledByNativeC);    // 把C#中的回调函数传给C

二 、方案二 UnitySendMessage

2.1 使用 UnitySendMessage 时具有以下限制:

1.通过原生代码,只能调用与以下签名对应的脚本方法:void MethodName(string message);。

2.对 UnitySendMessage 的调用是异步的,并有一帧延迟

3.如果两个或多个游戏对象具有相同的名称,则在使用 UnitySendMessage 时可能导致冲突

4.无论使用什么方式调用UnitySendMessage方法,方法最终会使用主线程运行。

2.2 UnitySendMessage 使用方法

UnitySendMessage("[gameobject_name]", "[method_name]", "[string_param]");

这个方法要求场景中有个特定名称的GameObject对象,同时该对象上应该挂载某个MonoBehaviour脚本,在该脚本中包含有一个特定的方法(如下所示),当然如果该对象上挂载了多个脚本,并且这些脚本中都有该方法,那么这些方法都会被调用的!

2.3 iOS 向C# 发送消息

MessageReceiver (MessageReceiver脚本绑定到MessageReceiver该游戏对象上)

cs 复制代码
UnitySendMessage("MessageReceiver", "OnMessageReceived", "Hello from iOS!");
cs 复制代码
using UnityEngine;

public class MessageReceiver : MonoBehaviour
{
    public void OnMessageReceived(string message)
    {
        Debug.Log("Received message from iOS: " + message);
    }
}

2.4 Unity调用iOS原生方法

cs 复制代码
using UnityEngine;
using System.Runtime.InteropServices;

public class NativeMethodCaller : MonoBehaviour
{
    [DllImport("__Internal")]
    private static extern void CallNativeMethod(string message);

    public void CalliOSMethod(string message)
    {
        CallNativeMethod(message);
    }
}

2.5 ios 实现方法

cs 复制代码
extern "C" {
    int CallNativeMethod(const char *msg) {
        
    }
}
相关推荐
missmisslulu7 小时前
电容笔值得买吗?2024精选盘点推荐五大惊艳平替电容笔!
学习·ios·电脑·平板
GEEKVIP8 小时前
手机使用技巧:8 个 Android 锁屏移除工具 [解锁 Android]
android·macos·ios·智能手机·电脑·手机·iphone
GEEKVIP8 小时前
如何在 Windows 10 上恢复未保存/删除的 Word 文档
macos·ios·智能手机·电脑·word·笔记本电脑·iphone
奇客软件9 小时前
iPhone使用技巧:如何恢复变砖的 iPhone 或 iPad
数码相机·macos·ios·电脑·笔记本电脑·iphone·ipad
Death20020 小时前
Qt 6 相比 Qt 5 的主要提升与更新
开发语言·c++·qt·交互·数据可视化
Artistation Game1 天前
九、怪物行为逻辑
游戏·unity·游戏引擎
百里香酚兰1 天前
【AI学习笔记】基于Unity+DeepSeek开发的一些BUG记录&解决方案
人工智能·学习·unity·大模型·deepseek
dangoxiba1 天前
[Unity Demo]从零开始制作空洞骑士Hollow Knight第十三集:制作小骑士的接触地刺复活机制以及完善地图的可交互对象
游戏·unity·visualstudio·c#·游戏引擎
奇客软件1 天前
如何从相机的记忆棒(存储卡)中恢复丢失照片
深度学习·数码相机·ios·智能手机·电脑·笔记本电脑·iphone
GEEKVIP2 天前
如何修复变砖的手机并恢复丢失的数据
macos·ios·智能手机·word·手机·笔记本电脑·iphone