Flutter-現有iOS工程引入Flutter

前言

Flutter 是一個頗有潛力的框架,可是目前使用Flutter的APP並不算不少,相關資料並不豐富,介紹現有工程引入Flutter的相關文章也比較少。項目從零開始,引入Flutter操做比較簡單,可是現有工程引入Flutter 須要費不少精力和時間,這裏是我在完成現有iOS工程引入Flutter後寫的一次總結文章。ios

Flutter 環境搭建

首先是要搭建Flutter環境,以前也寫了一篇相關文章搭建Flutter-iOS開發環境,能夠參考一下 能夠去官網查看:github.com/flutter/flu… 比較簡單,這裏不作贅述。git

現有iOS工程引入Flutter

1、創建Flutter module

首先創建flutter module,主要是用於獲取改flutter app中的Generated.xcconfig和frameworkgithub

cd some/path/ $ flutter create -t module my_flutter 複製代碼

也能夠用xcode

flutter create app
複製代碼

創建flutter app,flutter app中也有Generated.xcconfig和frameworkbash

2、新建配置文件

根據官網,須要在工程中創建三個配置文件: Flutter.xcconfigDebug.xcconfigRelease.xcconfig 在XCode工程對應目錄,右擊,選擇新建文件(New File),選中建立xcconfig文件,如圖:app

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的路徑:ide

例如 Release.xcconfigpost

#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.xcconfigfetch

注意:進行Archive打包的時候,不管是Debug包仍是Release包,須要切換到Release.xcconfig,否則會報錯。

3、爲編譯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 複製代碼

如圖:

4、生成和添加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

5、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]; } 複製代碼

6、新建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的數據通訊等。

相關文章
相關標籤/搜索