美文网首页
Xamarin之iOS绑定高德Amap那些坑

Xamarin之iOS绑定高德Amap那些坑

作者: pruple_Boy | 来源:发表于2017-09-11 15:04 被阅读0次

将iOS或Android的第三方SDK接入到Xamarin,不是一般的坑,虽然有官方文档,奈何奈何,依然十分滴蛋疼

在此,先感谢 前辈的分享 ,我直接入坑了

0.前言

  1. 一个Native Library Binding项目可绑定多个.Framework或.A类库

  2. 绑定MaMapKit和绑定FoundationKit方式相同 - 基础框架和地图框架

  3. .framework结尾可能为.a静态库,也可能为.dylib动态库

  4. 在Linker Flags添加动态库时,添加-ObjC -all_load,之后再添加动态库:各动态库以中横线开头

必须去掉lib的ib字母:官方说法要简写,如libz需要添加中横线且去掉ib:-lz(模拟器Debug编译OK,运行报错无效 IL Code,真机Release运行OK:猜测是模拟器可能没有加载进动态库,真机在Debug下编译报错:找不到引用的动态库)- 在Xcode内添加动态库依然是需要中横线打头的

  1. 尤其重要的声明:一定要在真机且Release下运行,否则可能编译失败或运行Crash:模拟器可访问静态方法 - 8.21 编译的DLL真机DEBUG下也能调试,DLL的DEBUG和RELEASE是一样的文件 - 若是引用DLL则DEBUG下也可运行,希望仅仅是我遇到这个BUG

  2. 无效 IL Code是针对创建对象的:虽然可以通过KVC赋值取值,通过运行时特性判断方法是否实现,但这些都是针对对象:C#不支持指针,我是没法写调用的了;这些方式都是针对于对象,类加[Static],若是类在模拟器的Debug下即使对象存在,访问其属性方法也会导致Crash

  3. 修改iOS项目的iOS Build下的Linker behavior为Link Framework SDKs Only:加载依赖库

  4. 集成MaMapKit时,需要在iOS项目下的Resources下添加MaMap.bundle,一些地图显示本地资源

1.语言转换

  • MaMapKit
sharpie bind --output=/users/timas-malk/desktop/MAMapKit --namespace=MAMapKit -framework /Users/timas-malk/Desktop/MAMapKit.framework -sdk iphoneos10.3
  • AMapFoundationKit
sharpie bind --output=/users/timas-malk/desktop/AMapFoundationKit --namespace=AMapFoundationKit -framework /Users/timas-malk/Desktop/AMapFoundationKit.framework -sdk iphoneos10.3
在此备注下说明:

1.sharpie bind 为Xamarin提供的将OC代码转为C#代码的工具,仅仅针对调用,会将OC中的类转为C#内的接口形式进行调用
2.output=为输出转换后文件夹的路径,默认就在当前用户目录下,整理修改为桌面
3.--namespace为转换的代码咋C#内添加一个命名空间,命名空间定义不清楚自行百度
4.-framework为当前绑定SDK的类型,后接的是需要转换的SDK路径
5.-sdk iphoneos10.3需要适配到的iOS系统版本

2.代码修改

  1. 修改ApiDefine文件的BuildAction为ObjcBindingAPIDefinition ; Struct文件BuildAction修改为ObjcBindingCoreSource

  2. 将Stucts文件内的uint更改为ulong:有负数则修改为int;C#不允许字符作为枚举类型,因此修改为数值

  3. [Verity]核对正确后注释掉 ; 在ApiDefine内将Constants的[Static]注释掉

  4. OC和C#方法命名方式不一样:因此Sharpie转换会出现很多同名方法,这不是重载。C#声明修改为不一样即可

  5. 合并同名的Constants接口,报错Unsupported type for Fields

  6. 某些类继承/接口,出现找不到该类,注释掉继承即可:C#实现都是通过接口形式,而不是类

  7. 去掉所有声明里面的*:C#没有指针概念

  8. OC点语法是编译器特性,其本质还是调用方法发送消息,因此若出现访问属性Crash可尝试将属性定义为方法

3.引用和依赖

  1. 引用:添加 Native References引用的framework文件:将引用的Framework文件拷贝到该绑定项目下,因为这是引用(引用的项目可以是.framework整个包,也可以是framework下的该类库文件:没有后缀)
  2. 依赖:右击添加引用的类库,弹出选择Properies,勾选Force Load和Smart Link;在Frameworks下添加.framework结尾的系统依赖库(.framework可能为.a,也可能为.dylib),在Linker Flags其她后缀的依赖库,这里基本为动态库
  3. 修改iOS项目的iOS Build下的Linker behavior为Link Framework SDKs Only:加载依赖库
  4. 集成MaMapKit时,需要在iOS项目下的Resources下添加MaMap.bundle,一些地必须的显示本地资源
添加的内容

1.Frameworks

OpenGLES UIKit Foundation CoreGraphics QuartzCore CoreLocation CoreTelephony SystemConfiguration Security AdSupport JavaScriptCore GLKit

2.Linker Flags

全写:-ObjC -all_load -libz -libc++ -libstdc++.6.0.9 (复制简写)
简写(官方说法:过长的描述可能导致引用失败):-ObjC -all_load -lz -lstdc++ -lc++

在Linker Flags添加动态库时,添加-ObjC -all_load,之后再添加动态库:各动态库以中横线开头:必须去掉lib的ib字母:官方说法要简写,如libz需要添加中横线且去掉ib:-lz(模拟器Debug编译OK,运行报错无效 IL Code,真机Release运行OK:猜测是模拟器可能没有加载进动态库,真机在Debug下编译报错:找不到引用的动态库)

4.权限设置

1.NSAppTransportSecurity字典下NSAllowsArbitraryLoads为BOOL类型其值为YES:兼容iOS 9 下版本
2.NSLocationUsageDescription:App需要您的同意,才能访问位置
3.NSLocationWhenInUseUsageDescription:App需要您的同意,才能在使用期间访问位置
4.NSLocationAlwaysUsageDescription:App需要您的同意,才能始终访问位置

若要后台定位,需要开启设置

5.新增接口

  1. 若该类有这个方法实现,Sharpie转换后没有生成,或是其父类的代码:此时都可以添加接口声明进行调用

  2. 若方法通过init...方式初始化,那么将alloc方法声明为[Static],之后init照常声明,调用时先调用alloc导出方法,在对应init...方法:这两个方法都是返回相同的对象,这是alloc没有参数:本质是alloc分配内存和初始化属性,iniit...才是自定义,因此init...在iOS中成为伪构造方法,若是init不做任何事,可直接调用new即可,new在C#中是可行的

6.代理使用

  1. C#将类库的所有调用都转为接口形式,协议只是加了 [Protocol, Model] 修饰,因此在C#调用还是要基于接口形式(在OC中协议有optional和require两种形式,Xamarin默认实现是通过类,声明其方法未virtual和abstract形式)

  2. C#也没有多继承,OC的多继承可通过协议实现;在C#中若要实现OC的协议,需要添加一个类,继承于该接口,在类的实现内重写接口内的实现,即OC协议的实现;将该类的对象赋值给代理,高德MaMapView代理有强弱两个,赋值其中一个就行:C#来实现OC协议可能会出现嵌套情况,因为针对没有协议都需要实现一个类

7.新增:地位集成(地位和地图是两套框架)

== 定位模块支持真机Debug和Release;模拟器只能获取到经纬度且不准确,没有地址描述 ==
== iOS项目在引用DLL时,需要设置iOS项目的iOS Build下的Linker Behavior为Link Framework SDKs Only ==

  • 语言转换
sharpie bind --output=/users/timas-malk/desktop/AMapLocationKit --namespace=AMapLocationKit -framework /Users/timas-malk/Desktop/AMapLocationKit.framework -sdk iphoneos10.3

备注:Define内的最外层 [Static] 是需要被注释掉的,Structs内是不用

== iOS的协议在C#中是通过类建立一对一联系的,因此若出现回调,需要将调用类继承于定位类:作强制类型转换后回调源对象代理事件 ==== 无效:高德地图的类映射到C#变成了接口,而不再是类了。例如,继承AMapLocationManager,定位会不准确,而且永远获取不到逆地理编码:定位失败 - base调用也不可行;因此回调事件为静态事件 ==

再次备注 参考链接,感谢作者的入门分享

相关文章

网友评论

      本文标题:Xamarin之iOS绑定高德Amap那些坑

      本文链接:https://www.haomeiwen.com/subject/tvjwjxtx.html