Flutter iOS 集成使用 flutter boost

    <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/kdoc_html_views-1a98987dfd.css">
    <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-25cebea3f9.css">
            <div id="content_views" class="markdown_views prism-atom-one-dark">
                <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
                    <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
                </svg>
                <p>在 <a href="https://so.youkuaiyun.com/so/search?q=Flutter&amp;spm=1001.2101.3001.7020" target="_blank" class="hl hl-1" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.7020&quot;,&quot;dest&quot;:&quot;https://so.youkuaiyun.com/so/search?q=Flutter&amp;spm=1001.2101.3001.7020&quot;,&quot;extra&quot;:&quot;{\&quot;searchword\&quot;:\&quot;Flutter\&quot;}&quot;}" data-tit="Flutter" data-pretit="flutter">Flutter</a>项目中集成完 flutter boost,并且已经使用了 flutter boost进行了路由管理,这时如果需要和iOS混合开发,这时就要到 原生端进行集成。</p> 

注意:之前建的项目必须是 Flutter module项目,并且原生项目和flutter module项目在同一个文件夹下面

下面是原生端集成 flutter boost的步骤:

  • 在原生项目的 Podfile文件中添加如下代码
# Uncomment the next line to define a global platform for your project
platform :ios, '12.0'

flutter_application_path = ‘…/my_flutter’
load File.join(flutter_application_path, ‘.ios’, ‘Flutter’, ‘podhelper.rb’)

target ‘FlutterList’ do

Comment the next line if you don’t want to use dynamic frameworks

use_frameworks!

Pods for FlutterList

install_all_flutter_pods(flutter_application_path)

pod ‘Masonry’, ‘1.0.2’

end

post_install do |installer|
flutter_post_install(installer) if defined?(flutter_post_install)
end

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

填写完后指向 pod install。此时项目的pod目录下面就会出现 flutter相关的库
在这里插入图片描述
到此就完成 flutter混合开发的集成工作,接下来就是需要 编写使用代码

  • 编写混合开发代码
    这里没有跟着flutter boost 官网进行集成 https://github.com/alibaba/flutter_boost/blob/master/docs/install.md 创建代码,稍微进行了些改进。

  • HYFlutterBoostDelegate

  • HYFlutterViewContainer

  • HYFlutterViewController
    分别创建了以上代码,并且在AppDelegate 中使用 FlutterBoost

  • HYFlutterBoostDelegate

import Foundation
import flutter_boost

class HYFlutterBoostDelegate: NSObject, FlutterBoostDelegate {

///您用来push的导航栏
var navigationController:UINavigationController? <span class="token punctuation">{<!-- --></span>
    <span class="token builtin class-name">return</span> UINavigationController.topNavigationController<span class="token punctuation">(</span><span class="token punctuation">)</span>?.navigationController
<span class="token punctuation">}</span>

///用来存返回flutter侧返回结果的表
var resultTable:Dictionary<span class="token operator">&lt;</span>String,<span class="token punctuation">(</span><span class="token punctuation">[</span>AnyHashable:Any<span class="token punctuation">]</span>?<span class="token punctuation">)</span>-<span class="token operator">&gt;</span>Void<span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">[</span>:<span class="token punctuation">]</span><span class="token punctuation">;</span>

func pushNativeRoute<span class="token punctuation">(</span>_ pageName: String<span class="token operator">!</span>, arguments: <span class="token punctuation">[</span>AnyHashable <span class="token builtin class-name">:</span> Any<span class="token punctuation">]</span><span class="token operator">!</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>

    //可以用参数来控制是push还是pop
    <span class="token builtin class-name">let</span> isPresent <span class="token operator">=</span> arguments<span class="token punctuation">[</span><span class="token string">"isPresent"</span><span class="token punctuation">]</span> as? Bool ?? <span class="token boolean">false</span>
    <span class="token builtin class-name">let</span> isAnimated <span class="token operator">=</span> arguments<span class="token punctuation">[</span><span class="token string">"isAnimated"</span><span class="token punctuation">]</span> as? Bool ?? <span class="token boolean">true</span>
    //这里根据pageName来判断生成哪个vc,这里给个默认的了
    <span class="token builtin class-name">let</span> targetViewController <span class="token operator">=</span> UIViewController<span class="token punctuation">(</span><span class="token punctuation">)</span>
    
    // 这里也可以使用路由进行跳转
    
    if<span class="token punctuation">(</span>isPresent<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
        self.navigationController?.present<span class="token punctuation">(</span>targetViewController, animated: isAnimated, completion: nil<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>else<span class="token punctuation">{<!-- --></span>
        self.navigationController?.pushViewController<span class="token punctuation">(</span>targetViewController, animated: isAnimated<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

func pushFlutterRoute<span class="token punctuation">(</span>_ options: FlutterBoostRouteOptions<span class="token operator">!</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token builtin class-name">let</span> vc:HYFlutterViewController <span class="token operator">=</span> HYFlutterViewController<span class="token punctuation">(</span><span class="token punctuation">)</span>
    vc.setName<span class="token punctuation">(</span>options.pageName, uniqueId: options.uniqueId, params: options.arguments,opaque: options.opaque<span class="token punctuation">)</span>
    vc.hidesBottomBarWhenPushed <span class="token operator">=</span> <span class="token boolean">true</span>
    //对这个页面设置结果
    resultTable<span class="token punctuation">[</span>options.pageName<span class="token punctuation">]</span> <span class="token operator">=</span> options.onPageFinished<span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token builtin class-name">let</span> nav <span class="token operator">=</span> navigationController  <span class="token punctuation">{<!-- --></span>
        nav.pushViewController<span class="token punctuation">(</span>vc, animated: <span class="token boolean">true</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
    
<span class="token punctuation">}</span>


func popRoute<span class="token punctuation">(</span>_ options: FlutterBoostRouteOptions<span class="token operator">!</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    //如果当前被present的vc是container,那么就执行dismiss逻辑
    <span class="token keyword">if</span> <span class="token builtin class-name">let</span> vc <span class="token operator">=</span> self.navigationController?.presentedViewController as? HYFlutterViewController, vc.uniqueIDString<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> options.uniqueId<span class="token punctuation">{<!-- --></span>
        
        //这里分为两种情况,由于UIModalPresentationOverFullScreen下,生命周期显示会有问题
        //所以需要手动调用的场景,从而使下面底部的vc调用viewAppear相关逻辑
        <span class="token keyword">if</span> vc.modalPresentationStyle <span class="token operator">==</span> .overFullScreen <span class="token punctuation">{<!-- --></span>
            
            //这里手动beginAppearanceTransition触发页面生命周期
            self.navigationController?.topViewController?.beginAppearanceTransition<span class="token punctuation">(</span>true, animated: <span class="token boolean">false</span><span class="token punctuation">)</span>
            
            vc.dismiss<span class="token punctuation">(</span>animated: <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                self.navigationController?.topViewController?.endAppearanceTransition<span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>else<span class="token punctuation">{<!-- --></span>
            //正常场景,直接dismiss
            vc.dismiss<span class="token punctuation">(</span>animated: true, completion: nil<span class="token punctuation">)</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>else<span class="token punctuation">{<!-- --></span>
        self.navigationController?.popViewController<span class="token punctuation">(</span>animated: <span class="token boolean">true</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
    //否则直接执行pop逻辑
    //这里在pop的时候将参数带出,并且从结果表中移除
    <span class="token keyword">if</span> <span class="token builtin class-name">let</span> onPageFinshed <span class="token operator">=</span> resultTable<span class="token punctuation">[</span>options.pageName<span class="token punctuation">]</span> <span class="token punctuation">{<!-- --></span>
        onPageFinshed<span class="token punctuation">(</span>options.arguments<span class="token punctuation">)</span>
        resultTable.removeValue<span class="token punctuation">(</span>forKey: options.pageName<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • HYFlutterViewContainer
#import <flutter_boost/FlutterBoost.h>

NS_ASSUME_NONNULL_BEGIN

@interface HYFlutterViewContainer : FBFlutterViewContainer

@end

NS_ASSUME_NONNULL_END

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
#import "HYFlutterViewContainer.h"

@interface HYFlutterViewContainer (){
UINavigationBar *_bar;
}

@property (nonatomic)BOOL navigationBarHidden;
@property (nonatomic, strong) FBVoidCallback removeEventCallback;

@end

@implementation HYFlutterViewContainer

  • (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    }

  • (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.navigationController setNavigationBarHidden:YES animated:animated];
    }

/// 设置这个container对应的从flutter过来的事件监听
-(void)setupEventListeningFromFlutter{
__weak typeof(self) weakSelf = self;
// 为这个容器注册监听,监听内部的flutterPage往这个容器发的事件
self.removeEventCallback = [FlutterBoost.instance addEventListener:^(NSString *name, NSDictionary *arguments) {
__strong typeof(self) strongSelf = weakSelf;
//事件名
NSString *event = arguments[@“event”];
//事件参数
NSDictionary *args = arguments[@“args”];

    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">[</span>event isEqualToString:@<span class="token string">"enablePopGesture"</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
        // 多page情况下的侧滑动态禁用和启用事件
        NSNumber *enableNum <span class="token operator">=</span> args<span class="token punctuation">[</span>@<span class="token string">"enable"</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
        BOOL <span class="token builtin class-name">enable</span> <span class="token operator">=</span> <span class="token punctuation">[</span>enableNum boolValue<span class="token punctuation">]</span><span class="token punctuation">;</span>
        //右滑控制

// strongSelf.fd_interactivePopDisabled = !enable;
}
} forName:self.uniqueId];
}

  • (BOOL)navigationBarHidden {
    return YES;
    }

  • (UINavigationBar *)navBar
    {
    if (!_bar) {
    _bar = [UINavigationBar new];
    }
    return _bar;
    }

  • (BOOL)shouldAutorotate
    {
    return NO;
    }

  • (UIInterfaceOrientationMask)supportedInterfaceOrientations
    {
    return UIInterfaceOrientationMaskPortrait;
    }

@end

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • HYFlutterViewController
#import <UIKit/UIKit.h>
#import "HYFlutterViewContainer.h"

@interface HYFlutterViewController : UIViewController

@property (nonatomic, strong) HYFlutterViewContainer *container;

  • (NSString *)uniqueIDString;

  • (void)setName:(NSString *)name uniqueId:(NSString *)uniqueId params:(NSDictionary *)params opaque:(BOOL) opaque;

@end

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
#import "HYFlutterViewController.h"
#import <Masonry/Masonry.h>
#import "UINavigationController+HY.h"

@interface HYFlutterViewController ()

@end

@implementation HYFlutterViewController

  • (void)setName:(NSString *)name uniqueId:(NSString *)uniqueId params:(NSDictionary *)params opaque:(BOOL) opaque {
    _container = [HYFlutterViewContainer new];
    [_container setName:name uniqueId:uniqueId params:params opaque:opaque];
    }

  • (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    // 隐藏导航栏
    [self.container.navigationController setNavigationBarHidden:YES animated:YES];

    [self addChildViewController:_container];
    [_container didMoveToParentViewController:self];

    [self.view addSubview:_container.view];
    [_container.view mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.mas_equalTo(UIEdgeInsetsZero);
    }];
    }

  • (NSString *)uniqueIDString {
    return self.container.uniqueIDString;
    }

  • (void)dealloc {
    [_container removeFromParentViewController];
    [_container didMoveToParentViewController:nil];
    }

@end

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    HYFlutterBoostDelegate* delegate = [[HYFlutterBoostDelegate alloc]init];
<span class="token punctuation">[</span>FlutterBoost.instance setup:application delegate:delegate callback:^<span class="token punctuation">(</span>FlutterEngine *engine<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    NSLog<span class="token punctuation">(</span>@<span class="token string">"FlutterBoost 开始操作"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    
<span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">;</span>

self.window <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">[</span>UIWindow alloc<span class="token punctuation">]</span>initWithFrame:<span class="token punctuation">[</span>UIScreen mainScreen<span class="token punctuation">]</span>.bounds<span class="token punctuation">]</span><span class="token punctuation">;</span>
self.window.backgroundColor <span class="token operator">=</span> <span class="token punctuation">[</span>UIColor whiteColor<span class="token punctuation">]</span><span class="token punctuation">;</span>

ViewController* VC <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">[</span>ViewController alloc<span class="token punctuation">]</span>init<span class="token punctuation">]</span><span class="token punctuation">;</span>
UINavigationController *nav <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">[</span>UINavigationController alloc<span class="token punctuation">]</span> initWithRootViewController:VC<span class="token punctuation">]</span><span class="token punctuation">;</span>

self.window.rootViewController <span class="token operator">=</span> nav<span class="token punctuation">;</span>
<span class="token punctuation">[</span>self.window makeKeyAndVisible<span class="token punctuation">]</span><span class="token punctuation">;</span>

<span class="token builtin class-name">return</span> YES<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

使用 Flutter boost进行调转

- (void)btnClick:(UIButton *)btn {
    FlutterBoostRouteOptions* option = [[FlutterBoostRouteOptions alloc]init];
    option.pageName = @"/";
    [[[FlutterBoost instance] plugin].delegate pushFlutterRoute:option];
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

到此flutter boost原生交互使用结束,此时进到flutter界面导航是没有左侧的返回按钮的,这需要自己处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值