前言

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. 009-多线程-JUC集合-Queue-LinkedBlockingDeque

    一.概述 LinkedBlockingDeque是双向链表实现的双向并发阻塞队列.该阻塞队列同时支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时操作(插入/删除):并且,该阻塞队列是支持线 ...

  2. osg 三维模型加载与解析(fbx、3ds、ive、obj、osg)

    void TeslaManage::OnlineTreeViewDoubleClick(const QModelIndex & index) { int row = index.row(); ...

  3. JS微信网页使用图片预览(放大缩小)

    前言 需求在微信网页中客户点击图片可进行预览放大缩小功能,网上找了各种js方式实现, 唯一的麻烦就是不兼容或者和项目框架不兼容 次函数只只用于部分客户端,否则会出现 WeixinJSBridge is ...

  4. (九)会话跟踪技术之Cookie

    --部分摘自孤傲苍狼博客~ 一.会话的概念 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 有状态会话:一个同学来过教室,下次再 ...

  5. 【C# 开发技巧】 Application.DoEvents( ) 使用笔记

    该方法可以处理当前队列的消息,比如一个for循环 5000次 向TextBox中追加文本,那肯定会假死一会儿的. 此时便可使用Application.DoEvents()来处理队列的信息. 简单说下使 ...

  6. selenium3 web自动化测试框架 四:Unittest介绍及项目实战中的运用

    unittest介绍及运用,可以参考之前写的文章,除了未结合web自动化演示,基础知识都有了 https://www.cnblogs.com/wuzhiming/p/8858305.html unit ...

  7. U盘防病毒

    1.待查 http://jingyan.baidu.com/article/a3f121e4ced14ffc9052bbca.html

  8. Beginning Linux Programming 学习-chapter2-Shell programming-Pipes and Redirection

    "为了从事创造性工作,人类需要孤独,可是在孤独中,广义的人类仍存在于内心."--(德国)奥铿                                             ...

  9. zabbix 批量添加web场景监控

    公司有大量测试环境的url需要监控是否能够访问,即url状态不为200即报警.状态为200即正常.因url比较多,且经常发生改变,如通过web场景配置(我没配过)会比较繁琐,工作量比较大.通过网上查找 ...

  10. PS复制图层快捷键

    选中图层,按“Ctrl + J”即可快速复制图层.