Flutter笔记-调用原生IOS高德地图sdk

一、前言

2017年底因公司业务组合部门调整,新的团队部分维护的项目用React Native技术混合开发。为适应环境变化,开启疯狂RN学习之旅,晚上回来啃资料看视频。可能由于本身对RN技术体验不感冒或者在环境之下强迫学习有点不爽。开始寻找代替方案,Fluter像一束曙光引起了我的注意,之后一直关注并利用闲余时间开始探索。2018年一直学习到使用Flutter写项目,从0.2.0开始到现在1.5版本的发布,终于开始慢慢的爬出坑位了,但是因为部分控件感觉还是不如原生控件好用,因而Flutter提供了PlatformView部件。近期因项目中严重使用依赖地图,故而做了Fluterr使用原生IOS高德地图调研。因为我本身是一名android开发人员,初学IOS并记录下来。

二、什么是 PlatformView?

PlatformView是 flutter 官方提供的一个可以嵌入 Android 和 iOS 平台原生 view 的小部件。

在我们实际开发中,我们遇到一些 flutter 官方没有提供的插件可以自己创建编写插件来实现部分功能,但是原生View在 flutter 中会遮挡住flutter 中的小部件,比如你想使用高德地图sdk、视频播放器、直播等原生控件,就无法很好的与 flutter 项目结合。

Flutter 中嵌套使用ios原生组件的步骤基本上可以描述为:

1、info.plist文件设置

2、 ios 端实现原生组件PlatformView提供原生view

3 、ios 端创建PlatformViewFactory用于生成PlatformView

4、 ios 端创建FlutterPlugin用于注册原生组件

5 、flutter 平台嵌入 原生view

三、制作本地插件

1、info.plist文件设置

iOS端的UiKitView目前还只是preview状态, 默认是不支持的, 需要手动打开开关, 在info.plist文件中新增一行io.flutter.embedded_views_preview为true.


image.png
2、创建IOS 原生MApView

创建类 FlutterMapView 并实现FlutterPlatformView 协议
FlutterMapView.h

#import <Foundation/Foundation.h>
#import "Flutter/Flutter.h"

NS_ASSUME_NONNULL_BEGIN

@interface FlutterMapView : NSObject <FlutterPlatformView>

-(instancetype)initWithWithFrame:(CGRect)frame
                  viewIdentifier:(int64_t)viewId
                       arguments:(id _Nullable)args
                 binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
@end

NS_ASSUME_NONNULL_END

FlutterMapView.m

#import "FlutterMapView.h"

@implementationFlutterMapView {

   //FlutterIosTextLabel 创建后的标识
   int64_t_viewId;

   MAMapView*_mapView;

   //消息回调

   FlutterMethodChannel* _channel;

   }

   //在这里只是创建了一个UILabel

   -(instancetype)initWithWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args binaryMessenger:(NSObject *)messenger{

       if([superinit]) {

           ///  创建地图view与展示逻辑
       }
       returnself;
   }

   - (nonnullUIView*)view {

       return_mapView;

   }

@end
3、创建PlatformViewFactory

FlutterMapFactory.h

#import  <Foundation/Foundation.h>

#import  <Flutter/Flutter.h>

NS_ASSUME_NONNULL_BEGIN

@interfaceFlutterMapFactory :  NSObject<FlutterPlatformViewFactory>

- (instancetype)initWithMessenger:(NSObject*)messager;

@end

NS_ASSUME_NONNULL_END

FlutterMapFactory.m

#import "FlutterMapFactory.h"

#import "FlutterMapView.h"

@implementationFlutterMapFactory{

  NSObject<FlutterBinaryMessenger>*_messenger;

}

    - (instancetype)initWithMessenger:(NSObject *)messager{

        self= [superinit];

        if(self) {
            _messenger= messager;

        }
        returnself;

    }

    //设置参数的编码方式

    -(NSObject *)createArgsCodec{

        return [FlutterStandardMessageCodec sharedInstance];

    }

    //用来创建 ios 原生view

    - (nonnullNSObject *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id_Nullable)args {

        //args 为flutter 传过来的参数

        FlutterMapView *mapView = [[FlutterMapView alloc] initWithWithFrame:frame viewIdentifier:viewId arguments:args binaryMessenger:_messenger];

        returnmapView;

    }
@end
4、创建Plugin

FlutterMapPlugin.h

#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>

NS_ASSUME_NONNULL_BEGIN

@interfaceFlutterMapPlugin :NSObject

@end

NS_ASSUME_NONNULL_END

FlutterMapPlugin.m

#import "FlutterMapPlugin.h"

#import "FlutterMapFactory.h"

@implementationFlutterMapPlugin

+ (void)registerWithRegistrar:(nonnullNSObject *)registrar {

    //注册插件

    //注册 FlutterIosTextLabelFactory

    //com.flutter_to_native_lbs.amap 为flutter 调用此  map 的标识

    [registrarregisterViewFactory:[[FlutterMapFactory alloc] initWithMessenger:registrar.messenger] withId:@"com.flutter_to_native_lbs.amap"];

}
@end
5、AppDelegate 中注册插件
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
#include "FlutterNativePlugin.h"
#include "FlutterMapPlugin.h"

#import <AMapFoundationKit/AMapFoundationKit.h>

//需要引入AMapFoundationKit.h头文件

@implementation AppDelegate

- (BOOL)application:(UIApplication*)application

    didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {

  [GeneratedPluginRegistrant registerWithRegistry:self];

  // Override point for customization after application launch.

  [FlutterNativePlugin registerWithRegistrar: [self registrarForPlugin:@"FlutterNativePlugin"]];

   //本地插件 高德地图

   [FlutterMapPlugin registerWithRegistrar:[self registrarForPlugin:@"FlutterMapPlugin"]];

  return [super application:application didFinishLaunchingWithOptions:launchOptions];

}
@end

四、集成IOS高德sdk

1、获取高德Key

请前往高德开放平台控制台申请 iOS Key。
注意:Bundle Identifier需要与申请的时候填写的一致

image
2、配置Info.plist 文件
<key>NSLocationWhenInUseUsageDescription</key>
<string>定位用来干什么,需要描述清楚</string>
3、添加依赖的库

地图依赖的库列举如下:

基础 SDK AMapFoundationKit.framework

第一步:将解压后的MAMapKit.framework 文件copy拖拽到工程文件夹中,左侧目录选中工程名,在 TARGETS->Build Phases-> Link Binary With Libaries 中点击“+”按钮,在弹出的窗口中点击“Add Other”按钮,选择工程目录下的 MAMapKit.framework 文件添加到工程中。

18808122-52bbb4dcd0aebe6b.png

千万不要忘记将AMapFoundationKit也一起加入工程。

3D地图正确配置应如下图所示:


image.png
第 2 步:需要引入的资源文件

需要引入的资源文件包括:AMap.bundle,其中:AMap.bundle 在 MAMapKit.framework 包中,AMap.bundle资源文件中存储了定位、默认大头针标注视图等图片,可利用这些资源图片进行开发。

左侧目录中选中工程名,在右键菜单中选择Add Files to “工程名”…,从MAMapKit.framework中选择AMap.bundle文件,并勾选“Copy items if needed”复选框,单击“Add”按钮,将资源文件添加到工程中。

image.png
4、配置高德Key至AppDelegate.m文件
#import<AMapFoundationKit/AMapFoundationKit.h>//需要引入AMapFoundationKit.h头文件……

(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{ 

    [AMapServices sharedServices].apiKey = @"您的Key";

    ……
}
5、加载地图 <FlutterMapView.m完整代码>
#import "FlutterMapView.h"
#import  <MAMapKit/MAMapKit.h>
#import  <AMapFoundationKit/AMapFoundationKit.h>

@implementationFlutterMapView {

    //FlutterIosTextLabel 创建后的标识
    int64_t_viewId;

    MAMapView*_mapView;

    //消息回调
    FlutterMethodChannel* _channel;

    }

    //在这里只是创建了一个UILabel

    -(instancetype)initWithWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args binaryMessenger:(NSObject *)messenger{

        if([superinit]) {

            ///地图需要v4.5.0及以上版本才必须要打开此选项(v4.5.0以下版本,需要手动配置info.plist)

            [AMapServices sharedServices].enableHTTPS = YES;


            _mapView= [[MAMapViewalloc]initWithFrame:self.view.bounds];

            _viewId= viewId;

            ///如果您需要进入地图就显示定位小蓝点,则需要下面两行代码

            _mapView.showsUserLocation = YES;

            _mapView.userTrackingMode = MAUserTrackingModeFollow;

            MAUserLocationRepresentation *r = [[MAUserLocationRepresentation alloc] init];

           // r.showsAccuracyRing = NO;///精度圈是否显示,默认YES

            r.strokeColor = [UIColor blueColor];///精度圈 边线颜色, 默认 kAccuracyCircleDefaultColor

            r.fillColor = [UIColor redColor];///精度圈 填充颜色, 默认 kAccuracyCircleDefaultColor

            //r.locationDotBgColor = [UIColor greenColor];///定位点背景色,不设置默认白色

            [_mapView updateUserLocationRepresentation:r];

           // [_mapView setMapType:MAMapTypeStandardNavi];

        }

        returnself;

    }

    - (nonnullUIView*)view {
        return_mapView;
    }
@end
最后一步操作 Flutter调用
 body:Container(
    child:UiKitView(viewType:"com.flutter_to_native_lbs.amap"), // 设置标识 
)

成功跑起来 。。 。

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