Xamarin之iOS绑定高德Amap那些坑

将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调用也不可行;因此回调事件为静态事件 ==

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容