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

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

第一步C#端 定义 C#调用 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);

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

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

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

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

 /// <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 的函数

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

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

///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#要传递过来的代理指针


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

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

-(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 代码
//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;
}

-(void)MobileNumberAuthiOS_CheckEnvironment{
    
    [self LogMessage:@"开始检测当前环境是否支持一键登录"];
    __block BOOL support = YES;
    [[TXCommonHandler sharedInstance] checkEnvAvailableWithAuthType:PNSAuthTypeLoginToken complete:^(NSDictionary * _Nullable resultDic) {
        NSString *dataStirng = [[resultDic objectForKey:@"msg"] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSString * code = [resultDic objectForKey:@"resultCode"];
        if (CheckEnvironmentCallback) {
            support = [PNSCodeSuccess isEqualToString:code];
            CheckEnvironmentCallback(support ? 1 : [code intValue],[dataStirng UTF8String]);
            CheckEnvironmentCallback = nil;
        }
        
        [self LogMessage:[NSString stringWithFormat:@"检测一键登录resultmsg:%@  resultCode:%@,是否支持一键登录:%d",[resultDic objectForKey:@"resultCode"],dataStirng,support]];
    }];
}
-(void)MobileNumberAuthiOS_GetToken{
    //3. 开始一键登录流程
    //3.1 调用加速授权页弹起接口,提前获取必要参数,为后面弹起授权页加速
UIViewController *rootViewController = [self topViewController];
    self.rootViewController = rootViewController;
__weak typeof(self) weakSelf = self;
TXCustomModel *model = [DoraemonModelCreate createAlert];
    
    [[TXCommonHandler sharedInstance] accelerateLoginPageWithTimeout:3.0 complete:^(NSDictionary * _Nonnull resultDic) {
        NSString *code = [resultDic objectForKey:@"resultCode"];
        NSString *dataStirng = [[resultDic objectForKey:@"msg"] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        [self LogMessage:[NSString stringWithFormat:@"dataStirng%@",dataStirng]];
        if ([PNSCodeSuccess isEqualToString:[resultDic objectForKey:@"resultCode"]] == NO) {
            if (NumberAuthGetTokenCallback) {
                NumberAuthGetTokenCallback([code UTF8String] ,[dataStirng UTF8String]);
                [rootViewController dismissViewControllerAnimated:YES completion:nil];
                NumberAuthGetTokenCallback = nil;
            }
            [self LogMessage:[NSString stringWithFormat:@"加速授权页弹起失败%@",dataStirng]];
            return ;
        }
        
        //3.2 调用获取登录Token接口,可以立马弹起授权页,model的创建需要放在主线程
        [[TXCommonHandler sharedInstance] getLoginTokenWithTimeout:1.0 controller:rootViewController model:model complete:^(NSDictionary * _Nonnull resultDic) {
            NSString *code = [resultDic objectForKey:@"resultCode"];
            NSString *dataStirng = [[resultDic objectForKey:@"msg"] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
            if ([PNSCodeLoginControllerPresentSuccess isEqualToString:code]) {
                [self LogMessage:@"弹起授权页成功"];
            } else if ([PNSCodeLoginControllerClickCancel isEqualToString:code]) {
                [self LogMessage:@"点击了授权页的返回"];
                if (NumberAuthGetTokenCallback) {
                    NumberAuthGetTokenCallback([code UTF8String] ,[dataStirng UTF8String]);
                    NumberAuthGetTokenCallback = nil;
                }
                [rootViewController dismissViewControllerAnimated:YES completion:nil];
            } else if ([PNSCodeLoginControllerClickChangeBtn isEqualToString:code]) {
                [self LogMessage:@"点击切换其他登录方式按钮"];

            } else if ([PNSCodeLoginControllerClickLoginBtn isEqualToString:code]) {
                if ([[resultDic objectForKey:@"isChecked"] boolValue] == YES) {
                    [self LogMessage:@"点击了登录按钮,check box选中,SDK内部接着会去获取登陆Token"];
                } else {
                    [[ToastUtil toast] showToast:@"请先同意协议"];
                    [self LogMessage:@"点击了登录按钮,check box未选中,SDK内部不会去获取登陆Token"];
                }
            } else if ([PNSCodeLoginControllerClickCheckBoxBtn isEqualToString:code]) {
                [self LogMessage:@"点击check box"];
            } else if ([PNSCodeLoginControllerClickProtocol isEqualToString:code]) {
                [self LogMessage:@"点击了协议富文本"];
            } else if ([PNSCodeSuccess isEqualToString:code]) {
                //点击登录按钮获取登录Token成功回调
                NSString *token = [resultDic objectForKey:@"token"];
                if (NumberAuthGetTokenCallback) {
                    NumberAuthGetTokenCallback([code UTF8String],[token UTF8String]);
                    [rootViewController dismissViewControllerAnimated:YES completion:nil];
                    NumberAuthGetTokenCallback = nil;
                }
                [[TXCommonHandler sharedInstance] hideLoginLoading];
                [self LogMessage:[NSString stringWithFormat:@"获取登录Token成功"]];
            } else{
                if (NumberAuthGetTokenCallback) {
                    NumberAuthGetTokenCallback([code UTF8String] ,[dataStirng UTF8String]);
                    NumberAuthGetTokenCallback = nil;
                }
                [[TXCommonHandler sharedInstance] hideLoginLoading];
                [self LogMessage:[NSString stringWithFormat:@"获取登录Token失败 "]];
            }
            [self LogMessage:[NSString stringWithFormat:@"授权框框操作日志msg:%@ code %@",dataStirng,code]];
        }];
    }];
    
}
-(void)MobileNumberAuthiOS_Dispose{
    
    [self.rootViewController dismissViewControllerAnimated:YES completion:nil];
}
#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# 代码

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
上一篇:[iOS]使用CocoaPods发布私有库


下一篇:2024深圳杯数学建模挑战赛B题:批量工件并行切割下料问题思路代码成品论文分析