Flutter iOS 集成使用 fluter boost
在 Flutter项目中集成完 flutter boost,并且已经使用了 flutter boost进行了路由管理,这时如果需要和iOS混合开发,这时就要到 原生端进行集成。
注意:之前建的项目必须是 Flutter module项目,并且原生项目和flutter module项目在同一个文件夹下面
下面是原生端集成 flutter boost的步骤:
- 在原生项目的 Podfile文件中添加如下代码
# Uncomment the next line to define a global platform for your project
platform :ios, '12.0'flutter_application_path = '../my_flutter'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')target 'FlutterList' do# Comment the next line if you don't want to use dynamic frameworksuse_frameworks!# Pods for FlutterListinstall_all_flutter_pods(flutter_application_path)pod 'Masonry', '1.0.2'endpost_install do |installer|flutter_post_install(installer) if defined?(flutter_post_install)
end
填写完后指向 pod install。此时项目的pod目录下面就会出现 flutter相关的库

到此就完成 flutter混合开发的集成工作,接下来就是需要 编写使用代码
-
编写混合开发代码
这里没有跟着flutter boost 官网进行集成 https://github.com/alibaba/flutter_boost/blob/master/docs/install.md 创建代码,稍微进行了些改进。 -
HYFlutterBoostDelegate
-
HYFlutterViewContainer
-
HYFlutterViewController
分别创建了以上代码,并且在AppDelegate 中使用FlutterBoost。 -
HYFlutterBoostDelegate
import Foundation
import flutter_boostclass HYFlutterBoostDelegate: NSObject, FlutterBoostDelegate {///您用来push的导航栏var navigationController:UINavigationController? {return UINavigationController.topNavigationController()?.navigationController}///用来存返回flutter侧返回结果的表var resultTable:Dictionary<String,([AnyHashable:Any]?)->Void> = [:];func pushNativeRoute(_ pageName: String!, arguments: [AnyHashable : Any]!) {//可以用参数来控制是push还是poplet isPresent = arguments["isPresent"] as? Bool ?? falselet isAnimated = arguments["isAnimated"] as? Bool ?? true//这里根据pageName来判断生成哪个vc,这里给个默认的了let targetViewController = UIViewController()// 这里也可以使用路由进行跳转if(isPresent){self.navigationController?.present(targetViewController, animated: isAnimated, completion: nil)}else{self.navigationController?.pushViewController(targetViewController, animated: isAnimated)}}func pushFlutterRoute(_ options: FlutterBoostRouteOptions!) {let vc:HYFlutterViewController = HYFlutterViewController()vc.setName(options.pageName, uniqueId: options.uniqueId, params: options.arguments,opaque: options.opaque)vc.hidesBottomBarWhenPushed = true//对这个页面设置结果resultTable[options.pageName] = options.onPageFinished;if let nav = navigationController {nav.pushViewController(vc, animated: true)}}func popRoute(_ options: FlutterBoostRouteOptions!) {//如果当前被present的vc是container,那么就执行dismiss逻辑if let vc = self.navigationController?.presentedViewController as? HYFlutterViewController, vc.uniqueIDString() == options.uniqueId{//这里分为两种情况,由于UIModalPresentationOverFullScreen下,生命周期显示会有问题//所以需要手动调用的场景,从而使下面底部的vc调用viewAppear相关逻辑if vc.modalPresentationStyle == .overFullScreen {//这里手动beginAppearanceTransition触发页面生命周期self.navigationController?.topViewController?.beginAppearanceTransition(true, animated: false)vc.dismiss(animated: true) {self.navigationController?.topViewController?.endAppearanceTransition()}}else{//正常场景,直接dismissvc.dismiss(animated: true, completion: nil)}}else{self.navigationController?.popViewController(animated: true)}//否则直接执行pop逻辑//这里在pop的时候将参数带出,并且从结果表中移除if let onPageFinshed = resultTable[options.pageName] {onPageFinshed(options.arguments)resultTable.removeValue(forKey: options.pageName)}}}
- HYFlutterViewContainer
#import <flutter_boost/FlutterBoost.h>NS_ASSUME_NONNULL_BEGIN@interface HYFlutterViewContainer : FBFlutterViewContainer@endNS_ASSUME_NONNULL_END
#import "HYFlutterViewContainer.h"@interface HYFlutterViewContainer (){UINavigationBar *_bar;
}@property (nonatomic)BOOL navigationBarHidden;
@property (nonatomic, strong) FBVoidCallback removeEventCallback;@end@implementation HYFlutterViewContainer- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.
}- (void)viewWillAppear:(BOOL)animated {[super viewWillAppear:animated];[self.navigationController setNavigationBarHidden:YES animated:animated];
}/// 设置这个container对应的从flutter过来的事件监听
-(void)setupEventListeningFromFlutter{__weak typeof(self) weakSelf = self;// 为这个容器注册监听,监听内部的flutterPage往这个容器发的事件self.removeEventCallback = [FlutterBoost.instance addEventListener:^(NSString *name, NSDictionary *arguments) {__strong typeof(self) strongSelf = weakSelf;//事件名NSString *event = arguments[@"event"];//事件参数NSDictionary *args = arguments[@"args"];if ([event isEqualToString:@"enablePopGesture"]) {// 多page情况下的侧滑动态禁用和启用事件NSNumber *enableNum = args[@"enable"];BOOL enable = [enableNum boolValue];//右滑控制
// strongSelf.fd_interactivePopDisabled = !enable;}} forName:self.uniqueId];
}- (BOOL)navigationBarHidden {return YES;
}- (UINavigationBar *)navBar
{if (!_bar) {_bar = [UINavigationBar new];}return _bar;
}- (BOOL)shouldAutorotate
{return NO;
}- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{return UIInterfaceOrientationMaskPortrait;
}@end
- HYFlutterViewController
#import <UIKit/UIKit.h>
#import "HYFlutterViewContainer.h"@interface HYFlutterViewController : UIViewController@property (nonatomic, strong) HYFlutterViewContainer *container;- (NSString *)uniqueIDString;- (void)setName:(NSString *)name uniqueId:(NSString *)uniqueId params:(NSDictionary *)params opaque:(BOOL) opaque;@end
#import "HYFlutterViewController.h"
#import <Masonry/Masonry.h>
#import "UINavigationController+HY.h"@interface HYFlutterViewController ()@end@implementation HYFlutterViewController- (void)setName:(NSString *)name uniqueId:(NSString *)uniqueId params:(NSDictionary *)params opaque:(BOOL) opaque {_container = [HYFlutterViewContainer new];[_container setName:name uniqueId:uniqueId params:params opaque:opaque];
}- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.// 隐藏导航栏[self.container.navigationController setNavigationBarHidden:YES animated:YES];[self addChildViewController:_container];[_container didMoveToParentViewController:self];[self.view addSubview:_container.view];[_container.view mas_makeConstraints:^(MASConstraintMaker *make) {make.edges.mas_equalTo(UIEdgeInsetsZero);}];
}- (NSString *)uniqueIDString {return self.container.uniqueIDString;
}- (void)dealloc {[_container removeFromParentViewController];[_container didMoveToParentViewController:nil];
}@end
- AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {HYFlutterBoostDelegate* delegate = [[HYFlutterBoostDelegate alloc]init];[FlutterBoost.instance setup:application delegate:delegate callback:^(FlutterEngine *engine) {NSLog(@"FlutterBoost 开始操作");}];self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];self.window.backgroundColor = [UIColor whiteColor];ViewController* VC = [[ViewController alloc]init];UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:VC];self.window.rootViewController = nav;[self.window makeKeyAndVisible];return YES;
}
使用 Flutter boost进行调转
- (void)btnClick:(UIButton *)btn {FlutterBoostRouteOptions* option = [[FlutterBoostRouteOptions alloc]init];option.pageName = @"/";[[[FlutterBoost instance] plugin].delegate pushFlutterRoute:option];
}
到此flutter boost原生交互使用结束
相关文章:
Flutter iOS 集成使用 fluter boost
在 Flutter项目中集成完 flutter boost,并且已经使用了 flutter boost进行了路由管理,这时如果需要和iOS混合开发,这时就要到 原生端进行集成。 注意:之前建的项目必须是 Flutter module项目,并且原生项目和flutter m…...
node.js相关的npm包的集合
一、实用功能 1. qs 一个简单易用的字符串解析和格式化库 2.rxjs RxJS是一组模块化的库,用于使用 JavaScript 中的可观察集合和组合来组合异步和基于事件的程序。 3. mitt 微型 200b 功能事件发射器/发布订阅. 4.Underscore.js Underscore.js是一个用于 JavaScript…...
Android Ble蓝牙App(二)连接与发现服务
Ble蓝牙App(二)连接与发现服务 前言正文一、GATT回调二、连接和断连三、连接状态回调四、发现服务五、服务适配器六、显示服务七、源码 前言 在上一篇中我们进行扫描设备的处理,本文中进行连接和发现服务的数据处理,运行效果图如下…...
Android 自定义按钮(可滑动、点击)
按钮图片素材 https://download.csdn.net/download/Lan_Se_Tian_Ma/88151085 px 和 dp 转换工具类(Java) // px 和 dp 转换工具类 public class DensityUtil {/*** 根据手机的分辨率从 dip 的单位 转成为 px(像素)*/public static int dip2px(Conte…...
mac录屏怎么打开?很简单,让我来教你!
mac电脑作为一款广受欢迎的电脑系统,提供了多种方式来满足用户录屏的需求。无论您是要录制教学视频、制作演示文稿,还是记录游戏精彩瞬间,mac电脑都能帮助您实现这些目标。本文将为您介绍两种mac录屏的方法。通过本文的指导,您将能…...
Stable Diffusion AI绘画学习指南【插件安装设置】
插件安装的方式 可用列表方式安装,点开Extensions 选项卡,找到如下图,找到Available选项卡,点load from加载可用插件,在可用插件列表中找到要装的插件按install 按扭按装,安装完后(Apply and restart UI)应…...
APP开发中的性能优化:提升用户满意度的关键
APP开发中的性能优化是需要持续进行的,它不仅能够让用户体验到 APP的使用感受,还能在一定程度上提升用户的满意度,从而提升 APP的粘性和转化率。不过在实际开发中,很多 APP开发公司会存在性能优化上的问题,这就需要了解…...
Golang 切片 常用方法
文章目录 移除指定位置的元素查找元素的位置查找最大最小的元素去重随机打乱排序二维排序sort.Sort 排序 下面的方法省略一些校验,如数组越界等,且都采用泛型(要求go版本 > 1.18) 移除指定位置的元素 package mainimport ("fmt" )func Del…...
【Linux后端服务器开发】poll/epoll多路转接IO服务器
目录 一、poll原理 二、poll实现多路转接IO服务器 三、epoll函数接口 四、epoll的工作原理 五、epoll实现多路转接IO服务器 一、poll原理 poll函数接口 #include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout);// pollfd结构 struct pollfd …...
【设计模式——学习笔记】23种设计模式——命令模式Command(原理讲解+应用场景介绍+案例介绍+Java代码实现)
文章目录 案例引入介绍基础介绍登场角色 案例实现案例一实现 案例二介绍实现拓展 命令模式在JdbcTemplate源码中的应用总结文章说明 案例引入 有一套智能家电,其中有照明灯、风扇、冰箱、洗衣机,这些智能家电来自不同的厂家,我们不想针对每一…...
Rust中的高吞吐量流处理
本篇文章主要介绍了Rust中流处理的概念、方法和优化。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库,还使用这些库实现了一个流处理程序。 最后,作者介绍了如何通过测量空闲和阻塞时间来优化流处理程序的性能,并将这些内容同步至…...
探索编程世界的宝藏:程序员必掌握的20大算法
文章目录 1 引言2 冒泡排序算法:编程世界的排序魔法 🧙♀️🔢3 选择排序算法:排序世界的精确挑选器 🎯🔢4 插入排序算法:排序世界的巧妙插珠者 ✨🔢5 快速排序算法:排序…...
Android NFC通信示例
前言 近距离无线通信 (NFC) 是一组近距离无线技术,通常只有在距离不超过 4 厘米时才能启动连接。借助 NFC,您可以在 NFC 标签与 Android 设备之间或者两台 Android 设备之间共享小型负载。 支持 NFC 的 Android 设备同时支持以下三种主要操作模式&…...
2023年08月IDE流行度最新排名
点击查看最新IDE流行度最新排名(每月更新) 2023年08月IDE流行度最新排名 顶级IDE排名是通过分析在谷歌上搜索IDE下载页面的频率而创建的 一个IDE被搜索的次数越多,这个IDE就被认为越受欢迎。原始数据来自谷歌Trends 如果您相信集体智慧&am…...
使用Beego和MySQL实现帖子和评论的应用,并进行接口测试(附源码和代码深度剖析)
文章目录 小项目介绍源码分析main.gorouter.gomodels/user.gomodels/Post.gomodels/comment.gocontrollers/post.gocontrollers/comment.go 接口测试测试增加帖子测试查看帖子测试增加评论测试查看评论 小项目介绍 经过对需求的分析,我增加了一些额外的东西&#x…...
物联网潜在的巨大价值在于大数据分析
物联网潜在的巨大价值在于大数据分析 从数据里去挖掘市场或者用户的精准需求。 往小的说,后台可以统计用户家里各各插座一年甚至更久的用电情况,这些数据也可以通过app或者小程序展现给用户。 用户可以很直观看到自己一年的用电情况,哪个家…...
SSL原理详解
SSL协议结构: SSL协议分为两层,下层为SSL记录协议,上层为SSL握手协议、SSL密码变化协议和SSL警告协议。 1.下层为SSL记录协议,主要作用是为高层协议提供基本的安全服务 建立在可靠的传输之上,负责对上层的数据进行分块…...
linux下的etc目录代表什么意思
在Linux系统中,/etc目录是一个非常重要的目录,它包含了系统的配置文件和相关的配置信息。下面是一些/etc目录中常见的文件和目录: 1. /etc/passwd:此文件包含了所有用户账户的信息,包括用户名、用户ID、用户所属的组I…...
iOS 两种方式设置状态栏
1、ios9.0以前设置状态栏字体颜色 ///白色 [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent]; ///黑色 [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleDefault]; 会看到如下提示: setStatusBarSty…...
html5:webSocket 基础使用
一、理解 HTML5 WebSocket HTML5 WebSocket是一种新型的网络协议,它能够在客户端和服务器之间建立实时的双向通信通道,使得浏览器和服务器之间的数据传输更加高效、快速和可靠。相比传统的HTTP协议,WebSocket协议使用更少的网络开销…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
