flutter在iOS項目中的集成

背景介紹:OC的iOS項目浮创,集成flutter模塊
注意忧吟,下文中"iOS項目"指將要集成flutter的原生項目,“.ios項目”指由flutter工程生成的被集成項目

準(zhǔn)備工作:

1斩披,flutter工程(第三方的溜族,或者其他同事開發(fā)的,需要集成到iOS項目的flutter工程)
2垦沉,本地flutter環(huán)境煌抒,建議與flutter工程的版本保持一致,不然后續(xù)會有兼容問題
3厕倍,iOS工程寡壮。
4,cocoapods環(huán)境

集成項目:

1,flutter項目編譯:

注意編譯出來的文件夾是隱藏的况既,可以用shift+command+.來顯示隱藏文件夾
終端cd到flutter路徑內(nèi)这溅,執(zhí)行命令:flutter run 。
無報錯:則生成了可用于集成的.iOS項目.ios文件夾默認(rèn)為隱藏狀態(tài)棒仍。生成后的flutter工程如下所示:

image.png

若有報錯:根據(jù)錯誤類型做對應(yīng)處理悲靴,一般分為以下幾種錯誤類型
1.1.0, 環(huán)境問題: 可以借助IDE比如Xcode降狠,vscode中打開对竣,會幫你配置好剩余環(huán)境。(比如No supported devices connected.我隨便打開個Xcode項目選中連接的真機后就)
1.1.1榜配, flutter項目代碼問題:使用相關(guān)開發(fā)工具檢查flutter代碼(比如:vscode否纬,添加flutter和dark插 件后。進行debug)蛋褥,flutter項目與本地flutter版本不一致時临燃,有時也會導(dǎo)致此問題。
1.1.2烙心,.ios項目內(nèi)問題:檢查.ios項目build有什么問題膜廊,(可以使用xcode打開.ios項目)檢查開發(fā)賬戶和證書配置是否正確,檢查cocoapods是否正常集成淫茵,檢查第三方庫是否需要項目添加swift依賴爪瓜,cd進入.iOS路徑下,cocoapod重新install匙瘪。
添加swift依賴.png

2铆铆,集成到iOS項目中:

2.1 修改iOS項目中的Podfile文件:(若iOS項目未使用cocoapods,需要新建Podfile文件丹喻,)
增加以下選中內(nèi)容:主要目的是按照所編輯路徑將上一步中的.ios項目集成到iOS項目中

截屏2022-06-27 上午10.08.47.png

2.2 將iOS項目和flutter項目按照以下位置關(guān)系置于同一文件夾下薄货。(符合上一步中的路徑關(guān)系)
image.png

2.3,pod刷新 終端cd到iOS項目路徑下碍论,執(zhí)行pod install(若有swift依賴問題見1.1.2配圖)谅猾。
完成項目集成后,可能后續(xù)打包會出現(xiàn)Bitcode設(shè)置問題鳍悠,將pod中TARGETS相關(guān)庫的Enable Bitcode設(shè)置為NO即可税娜。

3,代碼調(diào)用:

代碼部分主要分為兩部分:
1藏研,配置啟動器敬矩。
目前項目使用FlutterEngineGroup用以實現(xiàn)復(fù)合的flutter頁面集成。單一flutter項目也可以使用
FlutterEngine
在Appdelegate.h中添加:

#import <Flutter/Flutter.h>

//@property (nonatomic,strong) FlutterEngine *flutterEngine;
@property (nonatomic,strong) FlutterEngineGroup *flutterEngineGroup;

在Appdelegate.m中添加:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    .....
  
    self.flutterEngineGroup = [[FlutterEngineGroup alloc] initWithName:@"flutterGroupName" project:NULL];
    //若只有單一flutter頁面遥倦,也可以用以下代碼
    //FlutterEngine:
//    self.flutterEngine = [[FlutterEngine alloc] initWithName:@"my flutter engine"];
//    [self.flutterEngine run];
//    [GeneratedPluginRegistrant registerWithRegistry:self.flutterEngine];
    return YES;
}

2谤绳,生成頁面及通道占锯。
以flutter里面提供了頁面page_one,通道名稱page_One_channal為例子缩筛。
flutter頁面為繼承FlutterViewController的類消略。
自定義類:XYFlutterViewController:
XYFlutterViewController.h代碼:

#import <Flutter/Flutter.h>

NS_ASSUME_NONNULL_BEGIN
    
    @interface XYFlutterViewController : FlutterViewController
    
    //返回flutter頁面
    +(XYFlutterViewController *)flutterPageWithName:(NSString *)name;
@end

NS_ASSUME_NONNULL_END

FlutterMethodChannel:通道,flutter與原生交互依賴通道瞎抛,一般每個flutter頁面維護一個通道
setMethodCallHandler:給通道注冊方法艺演,調(diào)用原生內(nèi)容
invokeMethod:原生使用通道調(diào)用flutter內(nèi)的方法。
XYFlutterViewController.m代碼:

#import "AppDelegate.h"http://主要用來獲取全局flutterEngineGroup
#import <FlutterPluginRegistrant/FlutterPluginRegistrant-umbrella.h>
#import "XYFlutterViewController.h"

@interface XYFlutterViewController ()
@property (strong,nonatomic)FlutterMethodChannel *Channel;
@property (strong,nonatomic)NSMutableDictionary *flutterMCDic;//FlutterMethodChannel集合
@end

@implementation XYFlutterViewController

//懶加載flutter的MethodChannel桐臊,有則取胎撤,無則創(chuàng)建
/*
name為flutter約定的的通道名稱
*/
-(FlutterMethodChannel *)flutterMethodChannelWithName:(NSString *)name
{
    if (self.flutterMCDic[name]) {
        return self.flutterMCDic[name];
    }
    FlutterMethodChannel *notifationChannel = [FlutterMethodChannel methodChannelWithName:name binaryMessenger:self];
    [self.flutterMCDic setObject:notifationChannel forKey:name];
    return notifationChannel;
}
-(NSMutableDictionary *)flutterMCDic
{
    if (!_flutterMCDic) {
        _flutterMCDic = [NSMutableDictionary new];
    }
    return _flutterMCDic;
}

-(void)dealloc
{
    [self.flutterMCDic removeAllObjects];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}


/*
name為flutter提供的頁面名稱,以page_one頁面為例子,通道名稱為page_One_channal
*/
+(XYFlutterViewController *)flutterPageWithName:(NSString *)name
{
    FlutterEngine *flutterEngine = [((AppDelegate *)UIApplication.sharedApplication.delegate).flutterEngineGroup makeEngineWithEntrypoint:name libraryURI:nil];
    [GeneratedPluginRegistrant registerWithRegistry:flutterEngine];
    XYFlutterViewController *flutterViewController = [[XYFlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];

    //頁面添加通道,page_One參數(shù)為futter中設(shè)置的
    if ([name isEqualToString:@"page_One"]) {
        [flutterViewController addActionWithName:@"page_One_channal"];
    }
}

/*
name為flutter約定的的通道名稱
*/
-(void)addActionWithName:(NSString *)name
{
    //call.method   flutter方法名
    //call.arguments  flutter給到的參數(shù)
    FlutterMethodChannel *notifationChannel = [self flutterMethodChannelWithName:name];
    //設(shè)置回調(diào):以方法1:userChannel 方法2:jumpChannel為例
    [notifationChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
        //userChannel方法:需要數(shù)據(jù)回調(diào):
        if ([@"userChannel" isEqualToString:call.method]) {
            NSDictionary *dic =  @{
                 @"userId":@"****",
            };
            result(dic);
        }else if ([@"jumpChannel" isEqualToString:call.method]) {
        //jumpChannel方法:從flutter頁面調(diào)用原生頁面
            UIViewController *vc = [UIViewController new];
            vc.hidesBottomBarWhenPushed = YES;
            [self.navigationController pushViewController:vc animated:YES];
   
        }
     }];
}

//主動調(diào)用flutter方法:
-(void)flutter_actionWithChannleName:(NSString *)channel Name:(NSString *)name
{
    FlutterMethodChannel *notifationChannel = [self flutterMethodChannelWithName:channel];  
    if([name isEqualToString:@"refrish"]){
        NSDictionary *dic =  @{
            @"userId":@"****",
        };
        //通道去調(diào)用flutter方法
        [notifationChannel invokeMethod:name arguments:dic];
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末断凶,一起剝皮案震驚了整個濱河市伤提,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌认烁,老刑警劉巖肿男,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異却嗡,居然都是意外死亡舶沛,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門窗价,熙熙樓的掌柜王于貴愁眉苦臉地迎上來如庭,“玉大人,你說我怎么就攤上這事撼港∑核” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵餐胀,是天一觀的道長哟楷。 經(jīng)常有香客問我瘤载,道長否灾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任鸣奔,我火速辦了婚禮墨技,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘挎狸。我一直安慰自己扣汪,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布锨匆。 她就那樣靜靜地躺著崭别,像睡著了一般冬筒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茅主,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天舞痰,我揣著相機與錄音,去河邊找鬼诀姚。 笑死响牛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的赫段。 我是一名探鬼主播呀打,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼糯笙!你這毒婦竟也來了贬丛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤给涕,失蹤者是張志新(化名)和其女友劉穎瘫寝,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體稠炬,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡焕阿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了首启。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片暮屡。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖毅桃,靈堂內(nèi)的尸體忽然破棺而出褒纲,到底是詐尸還是另有隱情,我是刑警寧澤钥飞,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布莺掠,位于F島的核電站,受9級特大地震影響读宙,放射性物質(zhì)發(fā)生泄漏彻秆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一结闸、第九天 我趴在偏房一處隱蔽的房頂上張望唇兑。 院中可真熱鬧,春花似錦桦锄、人聲如沸扎附。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽留夜。三九已至匙铡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碍粥,已是汗流浹背慰枕。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留即纲,地道東北人具帮。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像低斋,于是被迫代替她去往敵國和親蜂厅。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

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