Xamarin的坑 - 绑定(二) - 高德iOS SDK(.Framework)绑定的一些事
2017-10-07

编者语:入门总是用一个hello world,总会让人觉得写code会是很容易的事。开篇绑定了一下微信SDK,不会有太多的难点,可是接下来的这个例子如果欠缺一些耐心,估计你整个人就崩溃了(我从来不会放弃任何的事)。ps这里得谢谢CSDN回帖的人,提示我把一些概念搞错了。嗯!我会修正回来。 我直接拿名家@onevat的日志重新把静态库(.a)和动态框架(Framework)的概念重新引用一次,哈哈希望不会有任何理解上的.

       
       了解更多可以看 https://onevcat.com/2016/01/create-framework/

       第三库在iOS 8后更多用Framework进行封装。本篇以高德SDK为例去完成一个Xamarin对Framework绑定的示例, 我乐意为大家填坑。
       高德地图iOS SDK http://lbs.amap.com/api/ios-sdk/summary 

       我在这里主要用3D地图,主要涉及两个Framework AMapFoundationKit.framework(这是高德的基础库任意地方都需要使用) 和 MAMapKit.framework(3D地图库) 。
       

       1. 在命令行下通过sharpie把两个framework进行分别转换
           AMapFoundationKit转换

  1. sharpie bind -framework /your path/AMapFoundationKit.framework -sdk iphoneos10.2  


           MAMapKit转换

  1.   sharpie bind -framework /your path/MAMapKit.framework -sdk iphoneos10.2  
       2. 分别创建对应于AMapFoundationKit和MAMapKit Binding项目,并把生成文件嵌入对应项目中(你可以参照本系列一进行操作http://blog.csdn.net/u014388424/article/details/55517845),还有把Framework放进Binding项目中的Native References文件夹中。
       
      2. 首先尝试编译AMap.iOS Binding ,估计都不会成功的啦,这是常识吧!
      
      看看错误在Structs
      

      是类型错,一般nint需要转换为C#的类型,我这里把它转换成ulong就基本上完事了。 再编译会提示Verify的问题了,把它注释掉。再重新编译就可以顺利把AMapFoundationKit的Binding解决了。(这个和WeChat SDK差不多)。还有别忘记加入using CoreLocation 因为 CLLocationCoordinate2D 需要用到的。

   转换时的命名错误也是需要修改
   

     修正后为     

  1. public enum MAOfflineCityStatus : uint  
  2. {  
  3.     None = MAOfflineItemStatus.None,  
  4.     Cached = MAOfflineItemStatus.Cached,  
  5.     Installed = MAOfflineItemStatus.Installed,  
  6.     Expired = MAOfflineItemStatus.Expired  

 
     2. 入坑后,再编译AMap.iOS.3D Binding估计你就会哭了,别怕哥帮你刷眼泪。不过这也是一个很好的长经验例子。
      
      初始错误分几种
      a. Structs.cs类型错,这种和第一步一样修正为long
       
      b.ApiDefinition.cs [Verify(ConstantsInterfaceAssociation)]
         这里得说明一下,除了注释这个字段外,还需要合并多个partial interface Constants为一个Constants。

  1. partial interface Constants  
  2.     {  
  3.         // extern NSString *const AMapFoundationVersion;  
  4.         [Field("AMapFoundationVersion", "__Internal")]  
  5.         NSString AMapFoundationVersion { get; }  
  6.   
  7.         // extern NSString *const AMapFoundationName;  
  8.         [Field("AMapFoundationName", "__Internal")]  
  9.         NSString AMapFoundationName { get; }  
  10.   
  11.         // extern NSString *const MAMapKitVersion;  
  12.         [Field("MAMapKitVersion", "__Internal")]  
  13.         NSString MAMapKitVersion { get; }  
  14.   
  15.         // extern NSString *const MAMapKitName;  
  16.         [Field("MAMapKitName", "__Internal")]  
  17.         NSString MAMapKitName { get; }  
  18.         // extern const MAMapSize MAMapSizeWorld;  
  19.         [Field("MAMapSizeWorld", "__Internal")]  
  20.         MAMapSize MAMapSizeWorld { get; }  
  21.   
  22.         // extern const MAMapRect MAMapRectWorld;  
  23.         [Field("MAMapRectWorld", "__Internal")]  
  24.         MAMapRect MAMapRectWorld { get; }  
  25.   
  26.         // extern const MAMapRect MAMapRectNull;  
  27.         [Field("MAMapRectNull", "__Internal")]  
  28.         MAMapRect MAMapRectNull { get; }  
  29.   
  30.         // extern const MAMapRect MAMapRectZero;  
  31.         [Field("MAMapRectZero", "__Internal")]  
  32.         MAMapRect MAMapRectZero { get; }  
  33.   
  34.         // extern NSString *const kMAMapLayerCenterMapPointKey;  
  35.         [Field("kMAMapLayerCenterMapPointKey", "__Internal")]  
  36.         NSString kMAMapLayerCenterMapPointKey { get; }  
  37.   
  38.         // extern NSString *const kMAMapLayerZoomLevelKey;  
  39.         [Field("kMAMapLayerZoomLevelKey", "__Internal")]  
  40.         NSString kMAMapLayerZoomLevelKey { get; }  
  41.   
  42.         // extern NSString *const kMAMapLayerRotationDegreeKey;  
  43.         [Field("kMAMapLayerRotationDegreeKey", "__Internal")]  
  44.         NSString kMAMapLayerRotationDegreeKey { get; }  
  45.   
  46.         // extern NSString *const kMAMapLayerCameraDegreeKey;  
  47.         [Field("kMAMapLayerCameraDegreeKey", "__Internal")]  
  48.         NSString kMAMapLayerCameraDegreeKey { get; }  
  49.   
  50.         [Field("MAOfflineMapDownloadReceivedSizeKey", "__Internal")]  
  51.         NSString MAOfflineMapDownloadReceivedSizeKey { get; }  
  52.   
  53.         // extern NSString *const MAOfflineMapDownloadExpectedSizeKey;  
  54.         [Field("MAOfflineMapDownloadExpectedSizeKey", "__Internal")]  
  55.         NSString MAOfflineMapDownloadExpectedSizeKey { get; }  
  56.         [Field("MAOfflineMapErrorDomain", "__Internal")]  
  57.         NSString MAOfflineMapErrorDomain { get; }  
  58.     }  
        这里有一些接口的错误
        
        修改为:
        
        需要修正命名错误,用sharpie转换很容易把不同方法转换成同个名字
        

        还有把Objective-C的指针*作为变量加上去了(这个也够搞笑,希望Sharpie下个版本能修正),都要删除掉*就解决了  

  1. // -(void)renderLinesWithPoints:(CGPoint *)points pointCount:(NSUInteger)pointCount strokeColor:(UIColor *)strokeColor lineWidth:(CGFloat)lineWidth looped:(BOOL)looped LineJoinType:(MALineJoinType)lineJoinType LineCapType:(MALineCapType)lineCapType lineDash:(BOOL)lineDash;  
  2. [Export("renderLinesWithPoints:pointCount:strokeColor:lineWidth:looped:LineJoinType:LineCapType:lineDash:")]  
  3. unsafe void RenderLinesWithPoints(CGPoint* points, nuint pointCount, UIColor strokeColor, nfloat lineWidth, bool looped, MALineJoinType lineJoinType, MALineCapType lineCapType, bool lineDash);  
         还是Verify字段要去掉

        
       这里有一个更好玩的事,就是扩展方法这里转换老提示以下错误

       

       我查看了一下,发现是怎么也不认扩展方法,看了看stackoverflow ,发现需要把每个属性的get/set通过方法描述解决,这也是醉了。。。。。如这个


  1. [Export("allowsAnnotationViewSorting")]  
  2. bool AllowsAnnotationViewSorting { get; set; }  
       需要修正为:

  1. [Export("allowsAnnotationViewSorting")]  
  2. //bool AllowsAnnotationViewSorting { get; set; }  
  3. bool AllowsAnnotationViewSorting();  
  4. [Export("setAllowsAnnotationViewSorting:")]  
  5. void SetAllowsAnnotationViewSorting(bool allowsAnnotationViewSorting);   
      按照上述步骤基本上就可以把项目编译成功了。         


      

      3.接下来就是添加一个iOS项目,做一个简单测试。

      这里需要补充一下,需要对MAMapKit.framework补充关联

        

        在Info.plist中 Location Always Usage Description

               

        还需要把两个绑定Binding引用进去

        

        还需要把AMap资源引用去Resource目录(bundle在MAMapKit.framework内)

        

        最后只需要在ViewController.cs添加如下代码就可以了


  1. AMapServices.SharedServices.ApiKey = "你申请的key";  
  2. AMapServices.SharedServices.EnableHTTPS = true;  
  3. MAMapView map = new MAMapView();  
  4. map.Frame = this.View.Bounds;  
  5. map.SetShowsUserLocation(true);  
  6. map.SetUserTrackingMode(MAUserTrackingMode.Follow);  
  7. this.View.AddSubview(map);  
       Rebuild一下运行


          

      爽爽!!

      代码在github上 https://github.com/lokinfey/AMapSDK,由于时间有限我只会暂时先放一个简单的定位功能上去。给有缘人自己添加功能了。

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