Flutter混合开发Android篇

Flutter混合开发IOS篇

在Mac上搭建Flutter开发环境

1.下载Flutter SDK ((Channel stable, v1.17.1, on Mac OS X 10.15.7 19H15, locale zh-Hans-CN),不要下载最新的SDK,兼容混合开发框架 flutter_boost: ^1.17.1。

2.下载四个插件,分别为 Flutter、Dart、FishReduxTemplate、Flutter Intl。流程图如下:
Preferences | Plugins

3.检查三个SDK的配置,分别为Androd SDK、Flutter SDK、
Dart SDK. 流程图如下:
Preferences | Appearance & Behavior | System Settings | Android SDK
Preferences | Languages & Frameworks | Flutter
Preferences | Languages & Frameworks | Dart

Mac上搭建Flutter开发环境

IOS Flutter混合开发

创建module

1.在IOS项目的同级目录新建Flutter Module

File | New | New Flutter Project… | Flutter Module

2.Flutter module项目集成FlutterBoost

在flutter_module项目的pubspec.yaml文件中添加依赖插件配置

dependencies:
  flutter_boost: ^1.17.1

配置完成后执行flutter packages get命令下载依赖插件到本地

需要了解 pub get 和 pub upgrade 命令 , 打开pubspec.yaml这两个命令就能显示出来

pub get
在项目中配置了pubspec文件后,就可以在项目根目录中执行pub get命令

pub upgrade
第一次获取依赖时,Pub 会下载依赖及其兼容的最新版本。然后通过创建lockfile 锁定依赖,以始终使用这个版本。 Pub会在pubspec旁创建并存储一个名为pubspec.lock文件。它列出了使用的每个依赖包的指定版本(当前包或传递包的版本)。

3.运行代码

1.直接点击绿色的箭头Run就能独立运行到手机里面。
2.Build | Flutter | Build AAR ,就能编译出AAR文件,并生成Android集成日志

IOS原生项目中集成FlutterBoost

1. 修改 Podfile 文件

flutter_application_path = '../flutter_module/'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
target 'YiHome2.0' do
  install_all_flutter_pods(flutter_application_path)

2.运行命令

pod install

3.添加 PlatformRouterImp.h

//
//  PlatformRouterImp.h
//  YiHome2.0
//
//  Created by liubing on 2020/11/26.
//  Copyright © 2020 xiaoyi. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <flutter_boost/FlutterBoost.h>

NS_ASSUME_NONNULL_BEGIN

@protocol FLBPlatform;

/**
 * 实现平台侧的页面打开和关闭,不建议直接使用用于页面打开,建议使用FlutterBoostPlugin中的open和close方法来打开或关闭页面;
 * FlutterBoostPlugin带有页面返回数据的能力
 */
@interface PlatformRouterImp : NSObject<FLBPlatform>
@property (nonatomic,strong) UINavigationController *navigationController;
@end

NS_ASSUME_NONNULL_END

4.添加 PlatformRouterImp.m

//
//  PlatformRouterImp.m
//  YiHome2.0
//
//  Created by liubing on 2020/11/26.
//  Copyright © 2020 xiaoyi. All rights reserved.
//

#import "PlatformRouterImp.h"
#import <flutter_boost/FlutterBoost.h>
#import "JJDeviceShareQRCodeScanSuccessViewController.h"

@interface PlatformRouterImp()
- (UINavigationController *)currentNC;
@end

@implementation PlatformRouterImp

#pragma mark - Boost 1.5
- (void)open:(NSString *)name
   urlParams:(NSDictionary *)params
        exts:(NSDictionary *)exts
  completion:(void (^)(BOOL))completion
{
    if ([name isEqualToString:@"yicamera://DeviceShareResultActivity"]) {
//        KeyConst.DEVICE_SHARE_WAY: KeyConst.DEVICE_SHARE_WAY_ACCOUNT,
//        KeyConst.DEVICE_SHARE_MESSAGE_ID: infoInvitee.id,
//        KeyConst.DEVICE_SHARE_TOKEN: infoInvitee.shareToken,
//        KeyConst.DEVICE_SHARE_OWNER_NAME: infoInvitee.nickName,
        JJDeviceShareQRCodeScanSuccessViewController * vc = DYY_Create_Alloc(JJDeviceShareQRCodeScanSuccessViewController);
        vc.stringInvitedUserId = params[@"DEVICE_SHARE_OWNER_NAME"];
        vc.stringShareToken = params[@"DEVICE_SHARE_TOKEN"];
        int type = 2;
        vc.shareType = type == 2 ? JJShareTypeAccount : JJShareTypeQRCode;
        [[self currentNC] pushViewController:vc animated:YES];
        // TODO 设备邀请
        return;
    }
    
    BOOL animated = [exts[@"animated"] boolValue];
    FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
    [vc setName:name params:params];
    [[self currentNC] pushViewController:vc animated:animated];
    if(completion) completion(YES);
}

- (void)present:(NSString *)name
   urlParams:(NSDictionary *)params
        exts:(NSDictionary *)exts
  completion:(void (^)(BOOL))completion
{
    BOOL animated = [exts[@"animated"] boolValue];
    FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
    [vc setName:name params:params];
    [[self currentNC] presentViewController:vc animated:animated completion:^{
        if(completion) completion(YES);
    }];
}

- (void)close:(NSString *)uid
       result:(NSDictionary *)result
         exts:(NSDictionary *)exts
   completion:(void (^)(BOOL))completion
{
    BOOL animated = [exts[@"animated"] boolValue];
    animated = YES;
    FLBFlutterViewContainer *vc = (id)[self currentNC].presentedViewController;
    if([vc isKindOfClass:FLBFlutterViewContainer.class] && [vc.uniqueIDString isEqual: uid]){
        [vc dismissViewControllerAnimated:animated completion:^{}];
    }else{
        [[self currentNC] popViewControllerAnimated:animated];
    }
}



- (UINavigationController *)currentNC
{
    if (![[UIApplication sharedApplication].windows.lastObject isKindOfClass:[UIWindow class]]) {
        NSAssert(0, @"未获取到导航控制器");
        return nil;
    }
    UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
    return [self getCurrentNCFrom:rootViewController];
}

//递归
- (UINavigationController *)getCurrentNCFrom:(UIViewController *)vc
{
    if ([vc isKindOfClass:[UITabBarController class]]) {
        UINavigationController *nc = ((UITabBarController *)vc).selectedViewController;
        return [self getCurrentNCFrom:nc];
    }
    else if ([vc isKindOfClass:[UINavigationController class]]) {
        if (((UINavigationController *)vc).presentedViewController) {
            return [self getCurrentNCFrom:((UINavigationController *)vc).presentedViewController];
        }
        return [self getCurrentNCFrom:((UINavigationController *)vc).topViewController];
    }
    else if ([vc isKindOfClass:[UIViewController class]]) {
        if (vc.presentedViewController) {
            return [self getCurrentNCFrom:vc.presentedViewController];
        }
        else {
            return vc.navigationController;
        }
    }
    else {
        NSAssert(0, @"未获取到导航控制器");
        return nil;
    }
}

@end

5.修改 AppDelegate.h

#import <flutter_boost/FlutterBoost.h>

6.修改 AppDelegate.m

#import "AppDelegate.h"
#import "PlatformRouterImp.h"
#import <flutter_boost/FlutterBoost.h>
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
 ...
router = [PlatformRouterImp new];
    [FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:router
    onStart:^(FlutterEngine *engine) {
        // 注册MethodChannel,监听flutter侧的getPlatformVersion调用
        FlutterMethodChannel *flutterMethodChannel = [FlutterMethodChannel methodChannelWithName:@"flutter_native_channel" binaryMessenger:engine.binaryMessenger];
                
        [flutterMethodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
                    
        NSString *method = call.method;
            if ([@"getUser" isEqualToString:call.method]) {
                dispatch_async(dispatch_get_global_queue(0, 0), ^{
                    NSError *error = nil;
                    [JJSingleAccount sharedJJSingleAccount];
                    JJSingleAccount *account = [JJSingleAccount sharedJJSingleAccount];
                    NSString *user = [account mj_JSONString];
                    NSDictionary *r = @{@"user":user};
                    NSData *data = [NSJSONSerialization dataWithJSONObject:r options:NSJSONWritingPrettyPrinted error:&error];
                    result(data);
                });
            } else if ([method isEqualToString:@"getPlatformVersion"]) {
                NSString *sysVersion = [[UIDevice currentDevice] systemVersion];
                result(sysVersion);
            } else {
                result(FlutterMethodNotImplemented);
            }
                    
        }];
    }];
    
	return YES;
}

7. 打开Flutter界面

[FlutterBoostPlugin open:@"notification" urlParams:nil exts:@{@"animated":@(YES)}onPageFinished:^(NSDictionary *result) {
                NSLog(@"call me when page finished, and your result is:%@", result);
            } completion:^(BOOL f) {
                NSLog(@"page is opened");
            }];

学习资料

Flutter官网
Dart官网
依赖包
OpenFlutter社区
flutter_boost 混合开发框架
fish_redux架构开发

上一篇:ReadLine自动补全分析


下一篇:转载:30多条mysql数据库优化方法,千万级数据库记录查询轻松解决