上一篇:flutter_boost学习1:iOS运行flutter_boost的Sample
下一篇:flutter_boost学习3:iOSNative添加与flutter交互调用
环境:MacOS、Xcode、cocoapods、flutter、flutter_boost
练习GitHub:HybridFlutter
参考:
- 添加Flutter到现有iOS的项目
- 中文文档
前言
上一篇体验运行了flutter_boost的sample,现在在一个完整项目中集成flutter_boost,方便一些业务能运行能同时运行在多个端,顺便提供一套flutter与Native方法交互的通用功能
1、创建一个flutter项目
flutter create -t module flutter_module
2.1、flutter添加flutter_boost的依赖,可以参考flutter_boost中文文档
2.2、在pubspec.yaml
里添加flutter_boost
的依赖,
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: '0.0.410'
完整的文件内容如下
name: advance_study
description: A new Flutter application.
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
flutter_boost:
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: '0.0.410'
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.io/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.io/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.io/custom-fonts/#from-packages
2.3 命令行运行:flutter packages get
或在各个IDE里运行相关的packages get
2.4 flutter里添加代码,参考flutter_boost中文文档
3、iOS原生代码里添加对flutter_boost的支持
3.1 在Podfile
里添加引用flutter的库
flutter_application_path = "../../Flutter/flutter_module"
eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
完整配置如下:
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
use_frameworks!
target 'HybridiOS' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
# use_frameworks!
# Pods for HybridiOS
# 返回侧滑适配有导航栏和没导航栏的切换
pod 'FDFullscreenPopGesture', '~> 1.1'
pod 'ZJScrollPageView'
pod 'YYModel'
pod 'Aspects'
pod 'Masonry', '~> 1.1.0'
pod 'MJRefresh', '~> 3.1.13'
flutter_application_path = "../../Flutter/flutter_module"
eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
target 'HybridiOSTests' do
inherit! :search_paths
# Pods for testing
end
target 'HybridiOSUITests' do
inherit! :search_paths
# Pods for testing
end
end
3.2 在AppDelegate.h
里设置继承与FLBFlutterAppDelegate
完整代码如下:
//
// AppDelegate.h
// HybridiOS
//
// Created by lonelyflow on 14/05/2019.
// Copyright © 2019 Lonely traveller. All rights reserved.
//
#import
#import
@interface AppDelegate : FLBFlutterAppDelegate
@property (strong, nonatomic) UIWindow *window;
@end
创建Router,这个Router优化为在第一次调用Router时才会初始化Fluttery Engine,这样能尽量避免在还未使用到Flutter时就创建了先关的消耗
MyFlutterRouter.h
//
// MyFlutterRouter.h
// HybridiOS
//
// Created by loneylyflow on 15/05/2019.
// Copyright © 2019 Lonely traveller. All rights reserved.
//
#import
#import
@interface MyFlutterRouter : NSObject
@property(nonatomic, weak) FlutterViewController *flutterViewController;
+ (instancetype)sharedRouter;
@end
MyFlutterRouter.m
//
// MyFlutterRouter.m
// HybridiOS
//
// Created by loneylyflow on 15/05/2019.
// Copyright © 2019 Lonely traveller. All rights reserved.
//
#import "MyFlutterRouter.h"
#import "MyFlutterViewController.h"
#import
@interface MyFlutterRouter()
@property(nonatomic, copy) FlutterEventSink eventSink;
@property(nonatomic, strong) UINavigationController *navigationController;
@end
@implementation MyFlutterRouter
+ (instancetype)sharedRouter
{
static MyFlutterRouter *_instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[MyFlutterRouter alloc] init];
// 在这里初始化FlutterViewController
// 初始化Router
[FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:_instance onStart:^(FlutterViewController * fvc){
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.001 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
MyFlutterRouter.sharedRouter.flutterViewController = fvc;
});
}];
});
return _instance;
}
#pragma mark - push/pop/close
- (void)openPage:(NSString *)name params:(NSDictionary *)params animated:(BOOL)animated completion:(void (^)(BOOL))completion
{
if([params[@"present"] boolValue]){
MyFlutterViewController *vc = MyFlutterViewController.new;
[vc setName:name params:params];
vc.hidesBottomBarWhenPushed = YES;
[self.navigationController presentViewController:vc animated:animated completion:^{}];
}else{
MyFlutterViewController *vc = MyFlutterViewController.new;
vc.hidesBottomBarWhenPushed = YES;
[vc setName:name params:params];
[self.navigationController pushViewController:vc animated:animated];
}
}
- (void)closePage:(NSString *)uid animated:(BOOL)animated params:(NSDictionary *)params completion:(void (^)(BOOL))completion
{
FLBFlutterViewContainer *vc = (id)self.navigationController.presentedViewController;
if([vc isKindOfClass:FLBFlutterViewContainer.class] && [vc.uniqueIDString isEqual: uid]){
[vc dismissViewControllerAnimated:animated completion:^{}];
}else{
[self.navigationController popViewControllerAnimated:animated];
}
}
- (UINavigationController *)navigationController
{
UITabBarController *tabVC = (UITabBarController *)[UIApplication sharedApplication].delegate.window.rootViewController;
if([tabVC isKindOfClass:[UITabBarController class]]){
UINavigationController *nav = (UINavigationController *)tabVC.selectedViewController;
if([nav isKindOfClass:[UINavigationController class]]){
return nav;
}else{
return [[UINavigationController alloc] init];
}
}
return [[UINavigationController alloc] init];
}
@end
3.3 在需要用到Flutter的地方调用flutter
[MyFlutterRouter.sharedRouter openPage:@"first" params:@{} animated:YES completion:^(BOOL isFinish){}];
3.4 在Build Phases
里添加运行脚本,好让iOS原生运行时自动打包flutter项目
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed