前言

Flutter 是一个很有潜力的框架,但是目前使用Flutter的APP并不算很多,相关资料并不丰富,介绍现有工程引入Flutter的相关文章也比较少。项目从零开始,引入Flutter操作比较简单,但是现有工程引入Flutter 需要费很多精力和时间,这里是我在完成现有iOS工程引入Flutter后写的一次总结文章。

Flutter 环境搭建

首先是要搭建Flutter环境,之前也写了一篇相关文章搭建Flutter-iOS开发环境,可以参考一下 可以去官网查看:github.com/flutter/flu… 比较简单,这里不做赘述。

现有iOS工程引入Flutter

一、建立Flutter module

首先建立flutter module,主要是用于获取改flutter app中的Generated.xcconfig和framework

cd some/path/
$ flutter create -t module my_flutter
复制代码

也可以用

flutter create app
复制代码

建立flutter app,flutter app中也有Generated.xcconfig和framework

二、新建配置文件

根据官网,需要在工程中建立三个配置文件: Flutter.xcconfigDebug.xcconfigRelease.xcconfig 在XCode工程对应目录,右击,选择新建文件(New File),选中创建xcconfig文件,如图:

Flutter.xcconfig中填写:
 //这里填写前面建立的flutter module 的Generated.xcconfig的路径
#include "../../my_flutter/.ios/Flutter/Generated.xcconfig"
ENABLE_BITCODE=NO
复制代码
Debug.xcconfig中填写:
#include "../Flutter/Flutter.xcconfig"

复制代码

Release.xcconfig中填写:

#include "../Flutter/Flutter.xcconfig"
FLUTTER_BUILD_MODE=release
复制代码

如果工程中用cocoapods管理,需要在 Debug.xcconfigRelease.xcconfig添加pod的路径:

例如 Release.xcconfig

#include "Flutter.xcconfig"
#include "工程路径/Pods/Target Support Files/******.release.xcconfig"//pod路径
FLUTTER_BUILD_MODE=release
复制代码

在准备好这些xcconfig文件后,需要到XCode工程PROJECT(注意是PROJECT,不是Target)中的Configuration选项里,将对应的target选择成前面的xcconfig文件,Debug用Debug.xcconfig, Release用 Release.xcconfig

注意:进行Archive打包的时候,无论是Debug包还是Release包,需要切换到Release.xcconfig,不然会报错。

三、为编译Dart引入相关build phase

在工程的Build Phase中新建一个Run Script,用于编译时运行脚本, 建立方法如图:

建立Run Script后,需要移动其对应的位置,需要在Target dependencies之后,如果用cocoapods管理工程需要在,Check Pods Manifest.lock之后:

在脚本框中,填入以下代码,用于引进Flutter中的xcode_backend脚本:

"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
复制代码

如图:

四、生成和添加Framework

完成前面的配置后,便可以在XCode对工程进行编译build (Command+B),在提示“ Build Success ” 后,在iOS工程文件夹中会生成一个Flutter文件夹,将其加入工程目录中,建议和刚才xcconfig所在目录并列,

右键项目目录 ,选择 Add Files to 'xxx' ,Options选Create groups,添加编译生成的Flutter文件夹。需要注意但是:Flutter目录下有个flutter_assets文件,不能使用Create groups的方式添加,只能用Creat folder references的Options, 否则Flutter页面会空白渲染不出来。可以删了flutter_assets在用Creat folder references重新添加。

在添加完Flutter 文件夹之后,去Embeded Binaries中添加App.frameworkFlutter.framework

五、AppDelegate改造

Flutter需要和APP进行交互,需要对AppDelegate 进行改造:

AppDelegate.h文件中:

#import <Flutter/Flutter.h>

@interface AppDelegate : FlutterAppDelegate <UIApplicationDelegate, FlutterAppLifeCycleProvider>

@end
复制代码

AppDelegate.m 文件中:

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate
{
FlutterPluginAppLifeCycleDelegate *_lifeCycleDelegate;
} - (instancetype)init {
if (self = [super init]) {
_lifeCycleDelegate = [[FlutterPluginAppLifeCycleDelegate alloc] init];
}
return self;
} - (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
return [_lifeCycleDelegate application:application didFinishLaunchingWithOptions:launchOptions];
} - (void)applicationDidEnterBackground:(UIApplication*)application {
[_lifeCycleDelegate applicationDidEnterBackground:application];
} - (void)applicationWillEnterForeground:(UIApplication*)application {
[_lifeCycleDelegate applicationWillEnterForeground:application];
} - (void)applicationWillResignActive:(UIApplication*)application {
[_lifeCycleDelegate applicationWillResignActive:application];
} - (void)applicationDidBecomeActive:(UIApplication*)application {
[_lifeCycleDelegate applicationDidBecomeActive:application];
} - (void)applicationWillTerminate:(UIApplication*)application {
[_lifeCycleDelegate applicationWillTerminate:application];
} - (void)application:(UIApplication*)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings {
[_lifeCycleDelegate application:application
didRegisterUserNotificationSettings:notificationSettings];
} - (void)application:(UIApplication*)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
[_lifeCycleDelegate application:application
didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
} - (void)application:(UIApplication*)application
didReceiveRemoteNotification:(NSDictionary*)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
[_lifeCycleDelegate application:application
didReceiveRemoteNotification:userInfo
fetchCompletionHandler:completionHandler];
} - (BOOL)application:(UIApplication*)application
openURL:(NSURL*)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options {
return [_lifeCycleDelegate application:application openURL:url options:options];
} - (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url {
return [_lifeCycleDelegate application:application handleOpenURL:url];
} - (BOOL)application:(UIApplication*)application
openURL:(NSURL*)url
sourceApplication:(NSString*)sourceApplication
annotation:(id)annotation {
return [_lifeCycleDelegate application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
} - (void)application:(UIApplication*)application
performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
completionHandler:(void (^)(BOOL succeeded))completionHandler NS_AVAILABLE_IOS(9_0) {
[_lifeCycleDelegate application:application
performActionForShortcutItem:shortcutItem
completionHandler:completionHandler];
} - (void)application:(UIApplication*)application
handleEventsForBackgroundURLSession:(nonnull NSString*)identifier
completionHandler:(nonnull void (^)(void))completionHandler {
[_lifeCycleDelegate application:application
handleEventsForBackgroundURLSession:identifier
completionHandler:completionHandler];
} - (void)application:(UIApplication*)application
performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
[_lifeCycleDelegate application:application performFetchWithCompletionHandler:completionHandler];
} - (void)addApplicationLifeCycleDelegate:(NSObject<FlutterPlugin>*)delegate {
[_lifeCycleDelegate addDelegate:delegate];
} 复制代码

六、新建FlutterViewController

主要配置基本上已经完成,只要在main.dart实现Flutter的业务代码即可

在原有工程中 ,建立FlutterViewController来承载main.dart实现的Flutter页面,如:

    self.flutterViewController = [[FlutterViewController alloc] initWithProject:nil nibName:nil bundle:nil];
[self.navigationController pushViewController:self.flutterViewController animated:YES];
复制代码

后语

到这里现有iOS工程引入Flutter的工作就完成了,一些细节上的修改需要根据场景进行修改,例如Flutter和Native的数据通信等。

Flutter-现有iOS工程引入Flutter的更多相关文章

  1. Flutter 集成到现有iOS工程

    前沿 由于我司已经有自己的App,flutter属于技术引进的一部分,也不太可能重新启动一个项目,因此目前我们是将flutter模块形式注入我们的App之中.即:将flutter模块集成到现在有iOS ...

  2. Cordova-在现有iOS工程自动化接入Cordova插件

    模拟Cordova插件命令 自己编写脚本,了解cordova添加插件做了哪些事情. 上一篇文章了解到,web与native的交互主要是cordova.js中的exec方法调用,触发交互事件.UIWeb ...

  3. iOS工程引入ios-charts-master

    前一段时间看到一个非常好的例子ios-charts-master,想在自己的工程中引用,但是一直没有成功,即使把整个工程原封不动的搬过来仍然,无济于事. 经过一次意外研究,终于成功了. 特记下集成过程 ...

  4. 【Flutter 混合开发】添加 Flutter 到 iOS

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  5. Flutter踩坑日记:接入现有iOS项目

    之前搞的Flutter版工具链已经弄完了,感兴趣的朋友可以围观下,Android版本dio库(v2.0.14)发送网络请求老是报错,去官方提了issue还没回,于是今天搞一下把Flutter模块接入到 ...

  6. iOS 工程实现native 跳转指定的Flutter 页面

    概要 在前一篇文章中我们提到,iOS跳转到Flutter工程指定页面时(多个),Flutter只有单例,设置setInitialRouter 无效,如下 let flutterViewControll ...

  7. 升级添加到现有iOS Xcode项目的Flutter

    如果你在2019年8月之前将Flutter添加到现有iOS项目,本文值得你一看. 在2019年7月30日,合并合并请求flutter / flutter#36793之前Flutter 1.8.4-pr ...

  8. iOS开发者学习Flutter

    Flutter for iOS 开发者 本文档适用那些希望将现有 iOS 经验应用于 Flutter 的开发者.如果你拥有 iOS 开发基础,那么你可以使用这篇文档开始学习 Flutter 的开发. ...

  9. 现有项目中集成Flutter

    本文列举了项目开发使用Flutter会遇到的问题,以及如何使用Flutter module在现有项目中集成Flutter,并对其原理进行了分析. 最近在做的一个商业项目,完全的使用Flutter编写的 ...

随机推荐

  1. jvm 指令重排

    引言:在Java中看似顺序的代码在JVM中,可能会出现编译器或者CPU对这些操作指令进行了重新排序:在特定情况下,指令重排将会给我们的程序带来不确定的结果..... 1.  什么是指令重排? 在计算机 ...

  2. 阶段5 3.微服务项目【学成在线】_day07 课程管理实战_05-课程修改实战分析

    3 课程信息修改 3.1 需求分析 课程添加成功进入课程管理页面,通过课程管理页面修改课程的基本信息.编辑课程图片.编辑课程营销信息等. 本小节实现修改课程. 3.2 课程管理页面说明 3.2.1 页 ...

  3. 123457123456#0#-----com.threeapp.SuanShuXiaoTianCai01----数学算术小天才

    com.threeapp.SuanShuXiaoTianCai01----数学算术小天才

  4. LODOP打印超文本字符串拼接1 固定表格填充数值

    前面的博文:Lodop打印控件传入css样式.看是否传入正确样式.Lodop打印如何隐藏table某一列,Lodop传入的样式可以不是页面本身的css样式,传入什么打印什么,此外,数据也是,超文本打印 ...

  5. python面向对象之类属性,实例属性

    python中的属性分为类属性和实例属性,之前已经说过一些,这里主要是对类属性与实例属性的增删改查 首先是对类属性的增删改查,下面这个是对类属性的修改,在书写类时,已经对类属性occupation进行 ...

  6. linux下的进程通信之信号量semaphore

    概念: IPC 信号量和内核信号量非常相似,是内核信号量的用户态版本. 优点:每个IPC信号量可以保护一个或者多个信号量值的集合,而不像内核信号量一样只有一个值,这意味着同一个IPC资源可以保护多个独 ...

  7. 【POJ - 2010】Moo University - Financial Aid(优先队列)

    Moo University - Financial Aid Descriptions 奶牛大学:奶大招生,从C头奶牛中招收N(N为奇数)头.它们分别得分score_i,需要资助学费aid_i.希望新 ...

  8. 【转帖】CRI-O 1.0 正式发布

    CRI-O 1.0 正式发布 http://www.sohu.com/a/200141920_465914 CRI-O 出来之后 docker 也就可有可无了 docker创造性的提出了 将依赖关系封 ...

  9. (七)Session 对象知识点总结(来自那些年的笔记)

    如果你想要转载话,可不可以不要删掉下面的 作者信息 呀!: 作者:淮左白衣 写于 来源笔者自己之前学javaWeb的时候,写的笔记 : 目录 Session对象 Session和cookie的主要区别 ...

  10. RecursiveSequence(HDU-5950)【矩阵快速幂】

    题目链接: 题意:Si=S(i-1)+2*S(i-2)+i^4,求Sn. 思路:想到了矩阵快速幂,实在没想出来怎么构造矩阵.... 首先构造一个向量vec={a,b,16,8,4,2,1}. 在构造求 ...