Xamarin的坑 - 绑定(一) - 拿微信iOS SDK 简单说起
2017-10-07

编者语:Xamarin 并入微软快一年了,在国内推广还是慢,主要有两个方面,Xamarin在国内的本地化不足真正在国内的解决方案基本上没有,第二就是和本土的一些主要SDK接入案例基本上也没有。上述原因令不少企业放弃使用这个很好的跨平台解决方案。在新一年本人觉得是时候把本人的东西贡献给各界友好了,希望把这几年开发的心得一次过给大家。当然在国内Xamarin社区也开始起步,如衣哥,guitarpark,周岳等Xamarin专家也会分享他们的经验。小弟只是做那么的一点点事摆了。

       大家希望有一些本地化的SDK和Xamarin的整合,这无可避免地需要和一些Static Library 和 Dynamic Framework进行整合。这个时候就需要Binding了。Xamarin 给大家提供一个命令行工具Sharpie,对传统的iOS Static Library 和 iOS Framework 进行转换适配C#的项目。

       先看看Sharpie, Sharpie是一个命令。其实是通过Clang对调用Static Library /Dynamic Framework 时所需要的头文件进行转换,把C++/Objective-C转换成C#。 在Xamarin的网站你可以下载( https://download.xamarin.com/objective-sharpie/ObjectiveSharpie.pkg )。这里补充一点,在使用Sharpie你还是得有对Static Library / Framework 的基本知识,否则你遇到问题时,你就无法入手了。(多次说跨平台不是不学每个平台)。
       这里补充一下Static Library和Framework的知识。

       Static Library(静态库) - 从源代码编译的目标文件的集合,其实就是一个源代码的实现所对应的二进制实现。配合上提供的头文件(.h),可以获取到静态库中(.a)暴露的属性和方法。
       Dynamic Framework(动态库)- 相当于一个包,随时可以调用,像iOS的UIKit之类的就是动态库。它对比起静态库不需要.h文件就可以调用,而且只需要加载一次,对程序的执行效率相对于静态库有所提高。

       很多第三方的组件都喜欢为iOS提供静态库和动态库,像微信就提供了静态库给iOS调用。
       
       微信就提供了libWeChatSDK.a的静态库,和三个头文件,分别对应了微信提供的验证,API, 基础类三个头文件。而Sharpie需要做的是把这三个基于Objective-C的头文件转换为C#.
       

       下面我们尝试去做转换看看有哪些值得注意的地方。      

       1. 做转换让 Sharpie帮你把.h头文件转换成ApiDefinition.cs和Structs.cs

[plain] view plain copy print?
  1. sharpie bind --output=WeChat.iOS --namespace=WeChat.iOS --sdk=iphoneos10.2 /Users/lujianhui/Desktop/OpenSDK1.7.6/WechatAuthSDK.h /Users/lujianhui/Desktop/OpenSDK1.7.6/WXApi.h /Users/lujianhui/Desktop/OpenSDK1.7.6/WXApiObject.h  
       
       转换成功后,会在你指定的文件夹生成ApiDefinitions.cs和StructsAndEnums.cs。


       2. 打开你的Xamarin Studio / Visual Studio for Mac/ Visual Studio (我这里用Visual Studio for Mac)创建iOS Bindings Library 项目
       
       把刚才生成的文件分别放进对应的ApiDefinition.cs和Structs.cs里面
       
       这里马上遇到我们的一个坑了,首先如果你尝试去编译,你会发现你是编译不过的。别慌,哥在!!
       

       首先这是一个标签[Verify(MethodToProperty)],这是需要你去确认,这些地方是否转换正确,因为在OC是一个静态方法,现在在C#会帮你转换成属性,你可以通过原有的头文件转换检查确认无误后,你可以删除/注释掉它。还有一些提示出错的如BaseType不用理,这个只是编辑器不支持这个标签,不影响项目编译和运行。(这里赞赞Sharpie还是转换类挺高的,当然也得赞微信团队,做的东西也是蛮标准的。)重新编译后就能通过了。

   3.把libWeChatSDK.a添加进项目中的Native References文件夹内
   
   这里是另一个坑,由于静态库会有对iOS的不同依赖,所以必须根据要求,对刚加进来的静态库进行调整。
   根据微信文档
   
   我们需要点击libWeChatSDK右键跳到属性,进行修改,首先我们需要把Smart Link 和Force Load钩上,因为这个静态库是必须加载的,其次按照上面的文件,把Frameworks和LinkFlags补上,最后效果如下:
   
   这样我们重新编译就把Binding基本上完成了。
   4.我们尝试把这个项目接入一个Xamarin.iOS做一个简单的测试看看是否成功
     
   接下来按照微信的接入步骤,把一些配置先弄好
   
   还有Bundle ID必须和你在微信注册时候是一致的
   接下来我定义一个简单的类去做一个接入和发送信息到朋友圈的例子。
   先定义一个WeChatAPI类

[csharp] view plain copy print?
  1. using System;  
  2. using WeChat.iOS;  
  3.   
  4. namespace WeChat.iOS.Samples  
  5. {  
  6.     public class WeChatAPI: WXApiDelegate  
  7.     {  
  8.         //微信登录  
  9.         public bool Log(string appID)  
  10.         {  
  11.             var result = WXApi.RegisterApp(appID);  
  12.             return result;  
  13.         }  
  14.         //微信链接打开  
  15.         public bool Open(NSUrl url)  
  16.         {  
  17.             var result = WXApi.HandleOpenURL(url, this);  
  18.             return result;  
  19.         }  
  20.         //请求打开微信  
  21.         public override void OnReq(BaseReq req)  
  22.         {  
  23.   
  24.         }  
  25.         //响应微信  
  26.         public override void OnResp(BaseResp resp)  
  27.         {  
  28.   
  29.         }  
  30.   
  31.         //发送信息到朋友圈  
  32.         public bool SendText(string text)  
  33.         {  
  34.             SendMessageToWXReq req = new SendMessageToWXReq();  
  35.             req.Text = text;  
  36.             req.BText = true;  
  37.             req.Scene = 1;  
  38.             WXApi.SendReq(req);  
  39.   
  40.             return true;  
  41.         }  
  42.   
  43.     }  
  44. }  
    在AppDelegate.cs添加如下代码


    
    并在Storyboard添加一个Button,并做一个响应事件
    
    运行看看
    
   是不是很有成就感呢?其实绑定还有一堆坑的,Sharpie随着版本的不断改进,对第三方的SDK兼容性越做越好了。接下来我会说说更多的案例,希望大家看了后有所启发。祝大家有个愉快的周末.

   程序示例https://github.com/lokinfey/WeChatSDK   

原文地址: http://blog.csdn.net/kinfey/article/details/55517845