unity和iOS交互的心得

本质是oc和c的交互 c#和c交互
用的很少,但是如果自己做一套需要支持跨平台的时候可以采取下下策,当然你没办法的时候...譬如说c c++ 或者c#其他平台有现成的稳定的库,其它平台就想直接用怎么办??但是实施起来还是比较困难因为编译器这关是个难题.不过倒是有了思路如何去做跨平台的东西,规划好这一套的工作量需要踩各大平台的坑,知道哪些特性是可以用的哪些是不可以用的还要做大量的调研测试说不定还要有一定的反编译功底去看函数原型,各种类型转换,才能搞.现目前只结合到用过c# oc swift java c 这些的交互操作也c#和oc这边交互用的核心是C 和Java这边用的是AndroidJavaClass 和 AndroidProxy
但如果是做一套可维护的接入方案,自己可实现一套复用的工具类专门封装与iOS和Android接口交互操作 经过一段时间的反复测试和验证
string float int long bool这些基本类型 是能很好的支持iOS和Android
但是在验证使用是否支持闭包和代理 函数指针的方案时 遇到了些障碍
如 iOS的闭包里面只能放char * char **和void (这种是可以的不过void * 是表示任意类型的 拿到的时候应该需要转换一下)的方式的参数回调 ,所以为了让unity那边能响应 iOS 的自定义数据 都会将其转换为json字符串,毕竟走整个流程调试是个麻烦的事情,将会花费在大量时间用于平台的切换测试,平台自己去解析 android 是可以支持自定义对象类型的不过操作是通过AndroidJavaObject 来call 实例化方法的方法名反射实现的
对于iOS这边遇到的坑吧
核心
*[DllImport("__Internal")] //需要引入using System.Runtime.InteropServices; 定义相关要调用sdk的c函数 这句直接复制吧我自己少写了__ 两道杠fuck

*使用到设置委托的需要使用AOT.MonoPInvokeCallback 标注切必须是static类型的不信邪的可以自己试试可以的话请告诉我,c#定义的委托在.mm中可以使用typedef void (*yourcallbacl)(arg1s) 具体定义格式可以查看demo中.mm的定义方式
*添加Assetsm目录下建立 Plugins/IOS/ xxx.mm文件,实现脚本文件定义的c函数这里就比较讲究了名字必须一样然后是参数类型的问题c# string 对应的是.mm中 char *类型的

//当然要使用swift的东西还是在这里引入即可<framework/head-Swift.h>即可

使用xxx.mm文件即可 mm中对于

//这里你可以各种骚操作 oc 还是引入其他库
extern "c"{
      //c这边支持void  void* int char* char **  int long 这些
  //定义的各种函数       名字必须一样
  void  Ctest(  这里参数也只能是这些){
                                      
   }
}

这里有个最精简的demo包括oc如何为c#这边提供 委托方式的回调 实现一个最简单的登录注销操作 都是通过oc这边操作的 而不需要unitymessagesend的方式做额外的操作

https://github.com/lotawei/IosUnityFrameTest
使用方式 unity打开项目 直接打包 对比着.mm实现函数和.cs的函数可以看到完整的打印信息在xcode中.

文章更新下补充:

关于如何使用 swift 和 oc 跟 unity 交互的细节,
Ccharp 传基本类型的这种上面已经叙述完毕,在考虑sdk的层面时 ,
Oc虽然是可以通过unity打包出来会自带
本身的unitysendmsg 方法去调用到但是这种对于sdk层面来说是不恰的,因为本质解耦是希望达到
unity 我只管调用和接收 SDK 只管处理和分发, 如何更方便 如 希望C-charp 这边参数是个回调函数
然后 oc这边是可以拿到 回调函数地址 , 处理完毕后主动 触发这个回调
让c-charp这边更好处理
但是sdk 不管swift 还是oc 交互实际本质都要先跟c c++ 交互的那么 如何使用c++来定义类似 oc 的protocol和闭包方式确实可行方案

这里以oc来举例 因为 swift 是可以直接与oc闭包方式交互的
因为SDK 这边基本要么是使用协议或者block的方式 去处理

  • 思路1:尝试用协议protocol与c++交互 额这个目前死路一条基本上
  • 思路2:尝试用block于 c++交互 查了下资料是可以的可行

\color{green}{举例说明}

  typedef void(^SDKProcesscall)(NSString*);#oc定义一个闭包方式

对应c++如何定义

typedef void (*SDKProcesscall)(const char *data);

然后在mm文件中实现c# 那边写好定以的方法 c#那边定以如下

    public delegate void iosMsgcallback(string datajson);
       [DllImport("__Internal")]
    public extern static void dealcallback(string params,iosMsgcallback callback);
    [AOT.MonoPInvokeCallback(typeof(iosMsgcallback))]
    public static void recieveCallBack(string result)
    {
        
                //这里可以拿到sdk处理的结果
               //进行以后的处理

    }

.mm文件

extern "C"{
   void  sdkdealprocess(const char *params ,SDKProcesscall back){
            //char * 转为 NSString 类型的 
            //当然这个 swift  和oc类似
             [SDkProcess  sdkdealprocess:str delaprocessblock:^(NSString result)  {
                     //  const char * result = ;
                      back(result);
              }];
        
        
    }
}

这样一个完整的交互流程就好了
在需要调用sdk处理的地方c#这边 这里只能 让aot 方式来处理回调自己写的sdk就会不认识了 会找不到这个回调 因此只能用 [AOT.MonoPInvokeCallback(typeof(iosMsgcallback))]标注的类型函数来处理结果

 
 dealcallback("{\"username\":\"hitbit\"}", recieveCallBack)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,161评论 1 32
  • __block和__weak修饰符的区别其实是挺明显的:1.__block不管是ARC还是MRC模式下都可以使用,...
    LZM轮回阅读 3,407评论 0 6
  • 一个单位的属性(攻击力、最大血量、防御力等)一般由多个模块决定,比如我们游戏的属性由三块决定: 基础属性:由单位的...
    水风阅读 837评论 0 1
  • Truth Is Discovered,Not Created (真理是被发现的,不是被创造出来的 ) 思想容易被...
    Duan__阅读 108评论 0 1
  • 很多事情都难以掌握,难以预计 在世界万物间,我们是那么渺小 局限生活在上班下班路上,我似乎已看不到再多 是不是该静...
    依稀也阅读 158评论 0 2