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
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架構開發