附帶參考網(wǎng)址:
官方將 Flutter module 集成到 iOS 項(xiàng)目
官方Flutter: iOS Android 原生項(xiàng)目集成 Flutter
看視頻更直接在 iOS 應(yīng)用中添加 Flutter 頁面
Flutter 可以以 framework 框架的形式添加到你的既有 iOS 應(yīng)用中讥脐。
請參閱 add_to_app代碼示例 的 iOS 目錄径缅。
系統(tǒng)要求
你的開發(fā)環(huán)境必須滿足 Flutter 對 macOS 系統(tǒng)的版本要求 并 已經(jīng)安裝 Xcode,F(xiàn)lutter 支持 iOS 8.0 及以上嗤锉。此外喻鳄,你還需要 1.10 或以上版本的 CocoaPods
創(chuàng)建 Flutter module
為了將 Flutter 集成到你的既有應(yīng)用里,第一步要?jiǎng)?chuàng)建一個(gè) Flutter module。
在命令行中執(zhí)行:
cd some/path/
flutter create --template module my_flutter
Flutter module 會(huì)創(chuàng)建在 some/path/my_flutter/
目錄晤锥。在這個(gè)目錄中,你可以像在其它 Flutter 項(xiàng)目中一樣廊宪,執(zhí)行 flutter
命令矾瘾。比如 flutter run --debug
或者 flutter build ios
。同樣箭启,你也可以通過 Android Studio/IntelliJ 或者 VS Code 中的 Flutter 和 Dart 插件運(yùn)行這個(gè)模塊壕翩,在集成到現(xiàn)有應(yīng)用前,這個(gè)項(xiàng)目在 Flutter module 中包含了一個(gè)單視圖的示例代碼傅寡,對 Flutter 側(cè)代碼的測試會(huì)有幫助放妈。
模塊組織
在 my_flutter
模塊北救,目錄結(jié)構(gòu)和普通 Flutter 應(yīng)用類似:
my_flutter/
├── .ios/
│ ├── Runner.xcworkspace
│ └── Flutter/podhelper.rb
├── lib/
│ └── main.dart
├── test/
└── pubspec.yaml
添加你的 Dart 代碼到 lib/
目錄。
添加 Flutter 依賴到 my_flutter/pubspec.yaml
芜抒,包括 Flutter packages 和 plugins珍策。
.ios/
隱藏文件夾包含了一個(gè) Xcode workspace,用于單獨(dú)運(yùn)行你的 Flutter module宅倒。它是一個(gè)獨(dú)立啟動(dòng) Flutter 代碼的殼工程攘宙,并且包含了一個(gè)幫助腳本,用于編譯 framewroks 或者使用 CocoaPods 將 Flutter module 集成到你的既有應(yīng)用拐迁。
提示
iOS 代碼要添加到你的既有應(yīng)用或者 Flutter plugin中蹭劈,而不是 Flutter module 的 .ios/
目錄下。 .ios/
下的改變不會(huì)集成到你的既有應(yīng)用线召,并且這有可能被 Flutter 重寫铺韧。
由于 .ios/
目錄是自動(dòng)生成的,因此請勿對其進(jìn)行版本控制灶搜。在新機(jī)器上構(gòu)建 module 時(shí)祟蚀,請?jiān)谑褂?Flutter module 構(gòu)建 iOS 項(xiàng)目之前,先于 my_flutter
目錄運(yùn)行 flutter pub get
以生成 .ios/
目錄割卖。
在你的既有應(yīng)用中集成 Flutter module
這里有兩種方式可以將 Flutter 集成到你的既有應(yīng)用中前酿。
使用 CocoaPods 依賴管理和已安裝的 Flutter SDK 。(推薦)
把 Flutter engine 鹏溯、你的 dart 代碼和所有 Flutter plugin 編譯成 framework 罢维。用 Xcode 手動(dòng)集成到你的應(yīng)用中,并更新編譯設(shè)置丙挽。
提示 Your app does not run on a simulator in Release mode because Flutter does not yet support outputting x86/x86_64 ahead-of-time (AOT) binaries for your Dart code. You can run in Debug mode on a simulator or a real device, and Release on a real device.
你的應(yīng)用將不能在模擬器上運(yùn)行 Release 模式肺孵,因?yàn)?Flutter 還不支持將 Dart 代碼編譯成 x86/x86_64 ahead-of-time (AOT) 模式的二進(jìn)制文件。你可以在模擬機(jī)和真機(jī)上運(yùn)行 Debug 模式颜阐,在真機(jī)上運(yùn)行 Release 模式平窘。
要在模擬器上運(yùn)行您的應(yīng)用,請按照本節(jié)底部的 嵌入框架說明進(jìn)行操作凳怨。
使用 Flutter 會(huì) 增加應(yīng)用體積 瑰艘。
選項(xiàng) A - 使用 CocoaPods 和 Flutter SDK 集成
這個(gè)方法需要你的項(xiàng)目的所有開發(fā)者,都在本地安裝 Flutter SDK肤舞。只需要在 Xcode 中編譯應(yīng)用紫新,就可以自動(dòng)運(yùn)行腳本來集成 dart 代碼和 plugin。這個(gè)方法允許你使用 Flutter module 中的最新代碼快速迭代開發(fā)李剖,而無需在 Xcode 以外執(zhí)行額外的命令芒率。
下面的示例假設(shè)你的既有應(yīng)用和 Flutter module 在相鄰目錄。如果你有不同的目錄結(jié)構(gòu)篙顺,需要適配到對應(yīng)的路徑偶芍。
some/path/
├── my_flutter/
│ └── .ios/
│ └── Flutter/
│ └── podhelper.rb
└── MyApp/
└── Podfile
如果你的應(yīng)用(MyApp
)還沒有 Podfile充择,根據(jù) CocoaPods getting started guide 來在項(xiàng)目中添加 Podfile
。
-
<t translation-result="on" style="box-sizing: border-box; margin-bottom: 0.6rem;">在
Podfile
中添加下面代碼:</t>Add the following lines to your
Podfile
:content_copy
flutter_application_path = '../my_flutter' load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
<t translation-result="on" style="box-sizing: border-box; margin-bottom: 0.6rem;">每個(gè)需要集成 Flutter 的 [Podfile target][]腋寨,執(zhí)行
install_all_flutter_pods(flutter_application_path)
:</t>
```
target 'MyApp' do
install_all_flutter_pods(flutter_application_path)
end
```
-
運(yùn)行
pod install
聪铺。提示
當(dāng)你在
my_flutter/pubspec.yaml
改變了 Flutter plugin 依賴,需要在 Flutter module 目錄運(yùn)行flutter pub get
萄窜,來更新會(huì)被podhelper.rb
腳本用到的 plugin 列表铃剔,然后再次在你的應(yīng)用目錄some/path/MyApp
運(yùn)行pod install
.
podhelper.rb
腳本會(huì)把你的 plugins, Flutter.framework
查刻,和 App.framework
集成到你的項(xiàng)目中键兜。
你應(yīng)用的 Debug 和 Release 編譯配置,將會(huì)集成相對應(yīng)的 Debug 或 Release 的 編譯產(chǎn)物穗泵∑掌可以增加一個(gè) Profile 編譯配置用于在 profile 模式下測試應(yīng)用。
小提示
Flutter.framework
是 Flutter engine 的框架佃延, App.framework
是你的 Dart 代碼的編譯產(chǎn)物现诀。
在 Xcode 中打開 MyApp.xcworkspace
,你現(xiàn)在可以使用 ?B
編譯項(xiàng)目了履肃。
選項(xiàng) B - 在 Xcode 中集成 frameworks
除了上面的方法仔沿,你也可以創(chuàng)建必備的 frameworks,手動(dòng)修改既有 Xcode 項(xiàng)目尺棋,將他們集成進(jìn)去封锉。當(dāng)你組內(nèi)其它成員們不能在本地安裝 Flutter SDK 和 CocoaPods,或者你不想使用 CocoaPods 作為既有應(yīng)用的依賴管理時(shí)膘螟,這種方法會(huì)比較合適成福。但是每當(dāng)你在 Flutter module 中改變了代碼,都必須運(yùn)行 flutter build ios-framework
荆残。
如果你使用前面的 使用 CocoaPods 和 Flutter SDK 集成奴艾,你可以跳過本步驟。
下面的示例假設(shè)你想在 some/path/MyApp/Flutter/
目錄下創(chuàng)建 frameworks:
flutter build ios-framework --xcframework --no-universal --output=some/path/MyApp/Flutter/
some/path/MyApp/
└── Flutter/
├── Debug/
│ ├── Flutter.xcframework
│ ├── App.xcframework
│ ├── FlutterPluginRegistrant.xcframework (only if you have plugins with iOS platform code)
│ └── example_plugin.xcframework (each plugin is a separate framework)
├── Profile/
│ ├── Flutter.xcframework
│ ├── App.xcframework
│ ├── FlutterPluginRegistrant.xcframework
│ └── example_plugin.xcframework
└── Release/
├── Flutter.xcframework
├── App.xcframework
├── FlutterPluginRegistrant.xcframework
└── example_plugin.xcframework
請注意
始終使用相同目錄下的 Flutter.framework
和 App.framework
内斯∥詹啵混合使用不同目錄(例如 Profile/Flutter.framework
以及 Debug/App.framework
)將會(huì)導(dǎo)致運(yùn)行失敗。
小提示
在 Xcode 11 中嘿期,你可以添加 --xcframework --no-universal
參數(shù)來生成 XCFrameworks,而不是使用通用的 framework埋合。
在 Xcode 中將生成的 frameworks 集成到你的既有應(yīng)用中备徐。例如,你可以在 some/path/MyApp/Flutter/Release/
目錄拖拽 frameworks 到你的應(yīng)用 target 編譯設(shè)置的 General > Frameworks, Libraries, and Embedded Content 下甚颂,然后在 Embed 下拉列表中選擇 “Embed & Sign”蜜猾。
鏈接到框架
例如秀菱,你可以將框架從 Finder 的 some/path/MyApp/Flutter/Release/
拖到你的目標(biāo)項(xiàng)目中,然后點(diǎn)擊以下步驟 build settings > Build Phases > Link Binary With Libraries蹭睡。
在 target 的編譯設(shè)置中的 Framework Search Paths (FRAMEWORK_SEARCH_PATHS
) 增加 $(PROJECT_DIR)/Flutter/Release/
衍菱。
Embed the frameworks
內(nèi)嵌框架
生成的動(dòng)態(tài)框架必須嵌入你的應(yīng)用并且在運(yùn)行時(shí)被加載。
重點(diǎn)提醒
插件會(huì)幫助你生成 靜態(tài)或動(dòng)態(tài)框架肩豁。靜態(tài)框架應(yīng)該直接鏈接而不是嵌入脊串。如果你在應(yīng)用中嵌入了靜態(tài)框架,你的應(yīng)用將不能發(fā)布到 App Store 并且會(huì)得到一個(gè) Found an unexpected Mach-O header code 的 archive error清钥。
例如琼锋,你可以從應(yīng)用框架組中拖拽框架(除了 FlutterPluginRegistrant 以及其他的靜態(tài)框架)到你的目標(biāo) ‘ build settings > Build Phases > Embed Frameworks。然后從下拉菜單中選擇 “Embed & Sign”祟昭。
你現(xiàn)在可以在 Xcode中使用 ?B
編譯項(xiàng)目缕坎。
小提示
如果你想在 Debug 編譯配置下使用 Debug 版本的 Flutter frameworks,在 Release 編譯配置下使用 Release 版本的 Flutter frameworks篡悟,在 MyApp.xcodeproj/project.pbxproj
文件中谜叹,嘗試在所有 Flutter 相關(guān) frameworks 上使用 path = "Flutter/$(CONFIGURATION)/example.framework";
替換 path = Flutter/Release/example.framework;
(注意添加引號 "
)。
你也必須在 Framework Search Paths (FRAMEWORK_SEARCH_PATHS
) 編譯設(shè)置中使用 $(PROJECT_DIR)/Flutter/$(CONFIGURATION)
搬葬。
選項(xiàng) C - 使用 CocoaPods 在 Xcode 和 Flutter 框架中內(nèi)嵌應(yīng)用和插件框架
除了將一個(gè)很大的 Flutter.framework 分發(fā)給其他開發(fā)者荷腊、機(jī)器或者持續(xù)集成 (CI) 系統(tǒng)之外,你可以加入一個(gè)參數(shù) --cocoapods
將 Flutter 框架作為一個(gè) CocoaPods 的 podspec 文件分發(fā)踩萎。這將會(huì)生成一個(gè) Flutter.podspec
文件而不再生成 Flutter.framework 引擎文件停局。如選項(xiàng) B 中所說的那樣,它將會(huì)生成 App.framework 和插件框架香府。
flutter build ios-framework --cocoapods --xcframework --no-universal --output=some/path/MyApp/Flutter/
some/path/MyApp/
└── Flutter/
├── Debug/
│ ├── Flutter.podspec
│ ├── App.xcframework
│ ├── FlutterPluginRegistrant.xcframework
│ └── example_plugin.xcframework (each plugin with iOS platform code is a separate framework)
├── Profile/
│ ├── Flutter.podspec
│ ├── App.xcframework
│ ├── FlutterPluginRegistrant.xcframework
│ └── example_plugin.xcframework
└── Release/
├── Flutter.podspec
├── App.xcframework
├── FlutterPluginRegistrant.xcframework
└── example_plugin.xcframework
Host apps using CocoaPods can add Flutter to their Podfile:
pod 'Flutter', :podspec => 'some/path/MyApp/Flutter/[build mode]/Flutter.podspec'
Embed and link the generated App.xcframework, FlutterPluginRegistrant.xcframework, and any plugin frameworks into your existing application as described in Option B.
Local Network Privacy Permissions
On iOS 14 and higher, enable the Dart multicast DNS service in the Debug version of your app to add debugging functionalities such as hot-reload and DevTools via flutter attach
.
請注意 This service must not be enabled in the Release version of your app, or you may experience App Store rejections.
One way to do this is to maintain a separate copy of your app’s Info.plist per build configuration. The following instructions assume the default Debug and Release. Adjust the names as needed depending on your app’s build configurations.
-
Rename your app’s Info.plist to Info-Debug.plist. Make a copy of it called Info-Release.plist and add it to your Xcode project.
Info-Debug.plist and Info-Release.plist in Xcode -
In Info-Debug.plist only add the key
NSBonjourServices
and set the value to an array with the string_dartobservatory._tcp
. Note Xcode will display this as “Bonjour services”.Optionally, add the key
NSLocalNetworkUsageDescription
set to your desired customized permission dialog text.Info-Debug.plist with additional keys -
In your target’s build settings, change the Info.plist File (
INFOPLIST_FILE
) setting path frompath/to/Info.plist
topath/to/Info-$(CONFIGURATION).plist
.Set INFOPLIST_FILE build settingThis will resolve to the path Info-Debug.plist in Debug and Info-Release.plist in Release.
Resolved INFOPLIST_FILE build settingAlternatively, you can explicitly set the Debug path to Info-Debug.plist and the Release path to Info-Release.plist.
-
If the Info-Release.plist copy is in your target’s Build Settings > Build Phases > Copy Bundle Resources build phase, remove it.
Copy Bundle build phaseThe first Flutter screen loaded by your Debug app will now prompt for local network permission. The permission can also be allowed by enabling Settings > Privacy > Local Network > Your App.
Local network permission dialog
Apple Silicon (arm64
Macs)
Flutter 目前暫未支持 arm64
的 iOS 模擬器董栽。要在 Apple Silicon Mac 設(shè)備上運(yùn)行你的宿主應(yīng)用,請從模擬器支持架構(gòu)中移除 arm64
企孩。
在宿主應(yīng)用的 Target 中锭碳,找到名為 Excluded Architectures (EXCLUDED_ARCHS
) 的構(gòu)建設(shè)置。單擊右側(cè)的箭頭指示器圖標(biāo)以展開可用的構(gòu)建配置勿璃。將鼠標(biāo)懸停在 Debug 處并單擊加號圖標(biāo)擒抛。將 Any SDK 更改為 Any iOS Simulator SDK。然后向構(gòu)建設(shè)置值中添加 arm64
补疑。
當(dāng)全部都正確設(shè)置后歧沪,Xcode 將會(huì)向你的 project.pbxproj 文件中添加 "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
。
然后對全部 iOS 目標(biāo)再次執(zhí)行單元測試莲组。
開發(fā)
你現(xiàn)在可以 添加一個(gè) Flutter 頁面 到你的既有應(yīng)用中诊胞。