iOS項(xiàng)目中集成flutter

創(chuàng)建iOS項(xiàng)目

這里我們先創(chuàng)建一個(gè)空的iOS項(xiàng)目來(lái)模擬已有的項(xiàng)目柠逞,取名叫iOS_demo

創(chuàng)建flutter模塊

進(jìn)入你的項(xiàng)目同一層目錄,創(chuàng)建flutter模塊

flutter create -t module flutter_lab
文件目錄.png

關(guān)閉Bitcode

Flutter混合開(kāi)發(fā)還不支持Bitcode,所以在iOS工程檢查項(xiàng)目并關(guān)閉Bitcode

Bitcode.png

iOS項(xiàng)目相關(guān)配置

image.png

Flutter.xcconfig 內(nèi)容

#include "../flutter_lab/.ios/Flutter/Generated.xcconfig"
ENABLE_BITCODE=NO

Debug.xcconfig 內(nèi)容 (對(duì)應(yīng)的名字換成自己)

#include "Flutter.xcconfig"

// 如果使用了Cocoapods聂受,那么需要引入 cocoapods 的config文件饥悴,因?yàn)槿绻远x了config坦喘,那么cocoapods 的 config 就不會(huì)自動(dòng)指定了盲再。
#include "Pods/Target Support Files/Pods-iOS_demo/Pods-iOS_demo.debug.xcconfig"

Release.xcconfig

#include "Flutter.xcconfig"
FLUTTER_BUILD_MODE=release

// 如果使用了Cocoapods,那么需要引入 cocoapods 的config文件瓣铣,因?yàn)槿绻远x了config答朋,那么cocoapods 的 config 就不會(huì)自動(dòng)指定了。
#include "Pods/Target Support Files/Pods-iOS_demo/Pods-iOS_demo.release.xcconfig"

指定 config 文件棠笑,Debug 對(duì)應(yīng) Debug梦碗,Release 對(duì)應(yīng) Release

image.png

增加 Flutter 的腳本

image.png
image.png
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build

修改Flutter腳本

在下載的flutter SDK中找到xcode_backend文件

image.png

注釋這段腳本

image.png

編譯iOS項(xiàng)目,在項(xiàng)目目錄下會(huì)生成一個(gè)flutter文件夾


image.png

右鍵項(xiàng)目 - Add Files to 'xxx' 【Options先選Create groups】蓖救,選擇Flutter目錄

image.png

但是flutter_assets 并不能使用Create groups 的方式添加洪规,只能使用Creat folder references 的方式添加進(jìn)Xcode項(xiàng)目?jī)?nèi),否則跳轉(zhuǎn)flutter會(huì)頁(yè)面渲染失斞唷(頁(yè)面空白)斩例。


image.png

文件夾再Add Files to 'xxx',選擇Creat folder references 巨柒;最終如下圖


image.png
image.png

iOS項(xiàng)目改造

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

@interface AppDelegate : FlutterAppDelegate <UIApplicationDelegate, FlutterAppLifeCycleProvider>

@property (strong, nonatomic) UIWindow *window;

@end

#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];
}

#pragma mark - Flutter
// Returns the key window's rootViewController, if it's a FlutterViewController.
// Otherwise, returns nil.
- (FlutterViewController*)rootFlutterViewController {
    UIViewController* viewController = [UIApplication sharedApplication].keyWindow.rootViewController;
    if ([viewController isKindOfClass:[FlutterViewController class]]) {
        return (FlutterViewController*)viewController;
    }
    return nil;
}

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
    [super touchesBegan:touches withEvent:event];
    
    // Pass status bar taps to key window Flutter rootViewController.
    if (self.rootFlutterViewController != nil) {
        [self.rootFlutterViewController handleStatusBarTouche

測(cè)試

    #import "ViewController.h"
    #import <Flutter/FlutterViewController.h>
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        FlutterViewController* flutterViewController = [[FlutterViewController alloc] initWithProject:nil nibName:nil bundle:nil];
        flutterViewController.navigationItem.title = @"Flutter";
        [self presentViewController:flutterViewController animated:YES completion:nil];
    }
    
    @end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末樱拴,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子洋满,更是在濱河造成了極大的恐慌晶乔,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牺勾,死亡現(xiàn)場(chǎng)離奇詭異正罢,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)驻民,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門翻具,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人回还,你說(shuō)我怎么就攤上這事裆泳。” “怎么了柠硕?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵工禾,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蝗柔,道長(zhǎng)闻葵,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任癣丧,我火速辦了婚禮槽畔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胁编。我一直安慰自己厢钧,他們只是感情好鳞尔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著坏快,像睡著了一般铅檩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上莽鸿,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天昧旨,我揣著相機(jī)與錄音,去河邊找鬼祥得。 笑死兔沃,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的级及。 我是一名探鬼主播乒疏,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼饮焦!你這毒婦竟也來(lái)了怕吴?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤县踢,失蹤者是張志新(化名)和其女友劉穎转绷,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體硼啤,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡议经,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谴返。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片煞肾。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖嗓袱,靈堂內(nèi)的尸體忽然破棺而出籍救,到底是詐尸還是另有隱情,我是刑警寧澤渠抹,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布蝙昙,位于F島的核電站,受9級(jí)特大地震影響逼肯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜桃煎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一篮幢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧为迈,春花似錦三椿、人聲如沸缺菌。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)伴郁。三九已至,卻和暖如春蛋叼,著一層夾襖步出監(jiān)牢的瞬間焊傅,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工狈涮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留狐胎,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓歌馍,卻偏偏與公主長(zhǎng)得像握巢,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子松却,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容