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

落花浮王杯 提交于 2019-11-27 13:50:05

编者语:入门总是用一个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转换

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

           MAMapKit转换

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 需要用到的。

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

     修正后为
     
public enum MAOfflineCityStatus : uint
{
	None = MAOfflineItemStatus.None,
	Cached = MAOfflineItemStatus.Cached,
	Installed = MAOfflineItemStatus.Installed,
	Expired = MAOfflineItemStatus.Expired
}

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

		// extern NSString *const AMapFoundationName;
		[Field("AMapFoundationName", "__Internal")]
		NSString AMapFoundationName { get; }

		// extern NSString *const MAMapKitVersion;
		[Field("MAMapKitVersion", "__Internal")]
		NSString MAMapKitVersion { get; }

		// extern NSString *const MAMapKitName;
		[Field("MAMapKitName", "__Internal")]
		NSString MAMapKitName { get; }
		// extern const MAMapSize MAMapSizeWorld;
		[Field("MAMapSizeWorld", "__Internal")]
		MAMapSize MAMapSizeWorld { get; }

		// extern const MAMapRect MAMapRectWorld;
		[Field("MAMapRectWorld", "__Internal")]
		MAMapRect MAMapRectWorld { get; }

		// extern const MAMapRect MAMapRectNull;
		[Field("MAMapRectNull", "__Internal")]
		MAMapRect MAMapRectNull { get; }

		// extern const MAMapRect MAMapRectZero;
		[Field("MAMapRectZero", "__Internal")]
		MAMapRect MAMapRectZero { get; }

		// extern NSString *const kMAMapLayerCenterMapPointKey;
		[Field("kMAMapLayerCenterMapPointKey", "__Internal")]
		NSString kMAMapLayerCenterMapPointKey { get; }

		// extern NSString *const kMAMapLayerZoomLevelKey;
		[Field("kMAMapLayerZoomLevelKey", "__Internal")]
		NSString kMAMapLayerZoomLevelKey { get; }

		// extern NSString *const kMAMapLayerRotationDegreeKey;
		[Field("kMAMapLayerRotationDegreeKey", "__Internal")]
		NSString kMAMapLayerRotationDegreeKey { get; }

		// extern NSString *const kMAMapLayerCameraDegreeKey;
		[Field("kMAMapLayerCameraDegreeKey", "__Internal")]
		NSString kMAMapLayerCameraDegreeKey { get; }

		[Field("MAOfflineMapDownloadReceivedSizeKey", "__Internal")]
		NSString MAOfflineMapDownloadReceivedSizeKey { get; }

		// extern NSString *const MAOfflineMapDownloadExpectedSizeKey;
		[Field("MAOfflineMapDownloadExpectedSizeKey", "__Internal")]
		NSString MAOfflineMapDownloadExpectedSizeKey { get; }
		[Field("MAOfflineMapErrorDomain", "__Internal")]
		NSString MAOfflineMapErrorDomain { get; }
	}
        这里有一些接口的错误
        
        修改为:
        
        需要修正命名错误,用sharpie转换很容易把不同方法转换成同个名字
        

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

		// -(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;
		[Export("renderLinesWithPoints:pointCount:strokeColor:lineWidth:looped:LineJoinType:LineCapType:lineDash:")]
		unsafe void RenderLinesWithPoints(CGPoint* points, nuint pointCount, UIColor strokeColor, nfloat lineWidth, bool looped, MALineJoinType lineJoinType, MALineCapType lineCapType, bool lineDash);
         还是Verify字段要去掉

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

       

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

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

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

      

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

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

        

        在Info.plist中 Location Always Usage Description

               

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

        

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

        

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

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

          

      爽爽!!

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


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!