背景
我們公司一直用 Objective-C
語言來開發iOS
的專案,最近提出要用跨平臺混合語言flutter
來研發新的功能,並計劃逐步過渡到flutter
專案。花了一整天的時間來研究flutter
在Objective-C
中的整合,現將探索過程分享如下:
參考Flutter
官方文件
一、安裝Flutter SDK
1、下載最新版的Flutter SDK
flutter_macos_2.2.3-stable.zip
2、將下載好的sdk解壓到合適的目錄
cd /Users/jim
unzip ~/Downloads/flutter_macos_2.2.3-stable.zip
複製程式碼
3、新增flutter環境變數
3.1 在.zshrc
中新增下面一行程式碼(我用的zsh
)
export PATH="$PATH:[PATH_OF_FLUTTER_GIT_DIRECTORY]/bin"
3.2 驗證是否新增成功
echo $PATH
3.3 檢視 flutter
和 dart
$ which flutter dart
# 列印:
/path-to-flutter-sdk/bin/flutter
/path-to-flutter-sdk/bin/dart
複製程式碼
如果你操作的結果如上所示,說明安裝成功了!
二、iOS配置
1、到AppStore
下載並安裝最新版本的Xcode;
2、配置Xcode command-line tools
,在終端執行如下命令:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -runFirstLaunch
複製程式碼
二、安裝並配置開發工具Visual Studio Code
VS Code
是一個輕量級的編輯器,支援Flutter app
的執行和除錯。
1、安裝
下載最新版本: Visual Studio Code 下載完成後,雙擊安裝即可!
2、安裝Flutter 和 Dart
外掛
- Start VS Code.
- Invoke View > Command Palette….
- Type “install”, and select Extensions: Install Extensions.
- Type “flutter” in the extensions search field, select Flutter in the list, and click Install. This also installs the required Dart plugin.
3、使用Flutter doctor
驗證配置是否成功
- Invoke View > Command Palette….
- Type “doctor”, and select the Flutter: Run Flutter Doctor.
- Review the output in the OUTPUT pane for any issues. Make sure to select Flutter from the dropdown in the different Output Options.
4、測試驅動
4.1 建立App
- Invoke View > Command Palette.
- Type “flutter”, and select the Flutter: New Application Project.
- Create or select the parent directory for the new project folder.
- Enter a project name, such as
myapp
, and press Enter.- Wait for project creation to complete and the
main.dart
file to appear.·
4.2 執行App
4.2.1 檢視VS Code底部的狀態列:
4.2.2 選擇裝置
從Device Selector
區域,選擇一個裝置,如果裝置不存在,就點選No Devices
來建立一個模擬器。
4.2.3 執行
Invoke Run > Start Debugging or press
F5
.
三、原生Objective-C
專案整合Flutter
Flutter可以作為嵌入式框架增量地新增到現有的iOS應用程式中。
1、將開發好的 Flutter
專案放到與原生工程同級目錄下;
some/path/
├── my_flutter/
│ └── .ios/
│ └── Flutter/
│ └── podhelper.rb
└── MyApp/
└── Podfile
複製程式碼
2、Use the CocoaPods
dependency manager
and installed Flutter SDK
2.1、 在 Podfile
中新增下面的程式碼:
flutter_application_path = '../my_flutter'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
複製程式碼
2.2、 For each Podfile target that needs to embed Flutter, call install_all_flutter_pods(flutter_application_path)
.
target 'MyApp' do
install_all_flutter_pods(flutter_application_path)
end
複製程式碼
2.3、 Run pod install
.
3、新增Flutter screen
到iOS app
3.1 、建立一個FlutterEngine
In AppDelegate.h
:
@import UIKit;
@import Flutter;
@interface AppDelegate : FlutterAppDelegate // More on the FlutterAppDelegate below.
@property (nonatomic,strong) FlutterEngine *flutterEngine;
@end
複製程式碼
In AppDelegate.m
:
// Used to connect plugins (only if you have plugins with iOS platform code).
#import <FlutterPluginRegistrant/GeneratedPluginRegistrant.h>
#import "AppDelegate.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions {
self.flutterEngine = [[FlutterEngine alloc] initWithName:@"my flutter engine"];
// Runs the default Dart entrypoint with a default Flutter route.
[self.flutterEngine run];
// Used to connect plugins (only if you have plugins with iOS platform code).
[GeneratedPluginRegistrant registerWithRegistry:self.flutterEngine];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
複製程式碼
3.2 、使用FlutterEngine
來展示一個FlutterViewController
@import Flutter;
#import "AppDelegate.h"
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Make a button to call the showFlutter function when pressed.
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self
action:@selector(showFlutter)
forControlEvents:UIControlEventTouchUpInside];
[button setTitle:@"Show Flutter!" forState:UIControlStateNormal];
button.backgroundColor = UIColor.blueColor;
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[self.view addSubview:button];
}
- (void)showFlutter {
FlutterEngine *flutterEngine =
((AppDelegate *)UIApplication.sharedApplication.delegate).flutterEngine;
FlutterViewController *flutterViewController =
[[FlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];
[self presentViewController:flutterViewController animated:YES completion:nil];
}
@end
複製程式碼
四、後續開發工作
當修改my_flutter/pubspec.yaml
外掛依賴的時候,需要在
Flutter module 目錄下執行flutter pub get
命令,用被podhelper.rb
指令碼來重新整理外掛列表,最後在原生專案目錄下some/path/MyApp
,執行pod install
即可。
四、常見報錯及解決辦法
1、 如果發現專案報target of uri doesn't exist
此時直接在Android studio軟體底部的terminal裡執行flutter upgrade
2、flutter
基於oc
的flutter
專案使用基於swift
的plugin
導致報錯問題?
3、flutter
中引用的 plugins
可能跟原工程定義的類有重複的
解決辦法:刪除原生工程裡面的第三方類;
4、iOS14 系統一啟動 App 就閃退
Due to low-level changes in iOS’s debugger mechanisms, developers using versions of Flutter earlier than 1.20.4 stable won’t be able to launch apps (by using
flutter run
or a Flutter-enabled IDE) on physical iOS devices running iOS 14. This affects debug, profile, and release builds. Simulator builds, add-to-app modules, and running directly from Xcode are unaffected.Upgrading to Flutter 1.22 beta allows you to build, test, and deploy to iOS without issue. Upgrading to 1.20.4 stable allows you to build and deploy to iOS 14, but not debug.
翻譯:
由於iOS偵錯程式機制的低階變化,使用
1.20.4 stable
之前版本的開發者將無法在執行iOS 14
的物理iOS裝置上啟動應用(通過使用flutter run
執行或Flutter-enabled IDE
)。這將影響除錯、profile
和釋出構建。模擬器構建、新增到應用程式的模組,以及直接從Xcode執行都不受影響。升級到
Flutter 1.22 beta
版可以讓你毫無問題地構建、測試和部署到iOS上。升級到1.20.4 stable
允許你構建和部署到iOS 14
,但不能除錯。
解決: 將 scheme
改成 release
即可
參考資料: