官方有三种方式:A.使用 CocoaPods 和 Flutter SDK 集成,B.在 Xcode 中集成 frameworks,C.使用 CocoaPods 在 Xcode 和 Flutter 框架中内嵌应用和插件框架 A,C这两种方式都需要用到 cocoapods 这个工具对第三方依赖包进行管理,一是网络问题需要翻墙或者设置镜像,二是每台电脑上都需要安装配置环境;相较于方式B 把flutter打包成原生iOS应用可使用的framework那就简单的多了。
在 Xcode 中集成 frameworks
可以创建必备的 frameworks,手动修改既有 Xcode 项目,将他们集成进去。当你组内其它成员们不能在本地安装 Flutter SDK 和 CocoaPods,或者你不想使用 CocoaPods 作为既有应用的依赖管理时,这种方法会比较合适。但是每当你在 Flutter module 中改变了代码,都必须运行 flutter build ios-framework。
如果你使用前面的 使用 CocoaPods 和 Flutter SDK 集成,你可以跳过本步骤。
下面的示例假设你想在 some/path/MyApp/Flutter/ 目录下创建 frameworks:
flutter build ios-framework --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
在 Xcode 中将生成的 frameworks 集成到你的既有应用中。例如,你可以在 some/path/MyApp/Flutter/Release/ 目录拖拽 frameworks 到你的应用 target 编译设置的 General > Frameworks, Libraries, and Embedded Content 下,然后在 Embed 下拉列表中选择 “Embed & Sign”。
链接到框架
例如,你可以将框架从 Finder 的 some/path/MyApp/Flutter/Release/ 拖到你的目标项目中,然后点击以下步骤 build settings > Build Phases > Link Binary With Libraries。
在 target 的编译设置中的 Framework Search Paths (FRAMEWORK_SEARCH_PATHS) 增加 $(PROJECT_DIR)/Flutter/Release/。
Embed the frameworks
内嵌框架
生成的动态框架必须嵌入你的应用并且在运行时被加载。
例如,你可以从应用框架组中拖拽框架(除了 FlutterPluginRegistrant 以及其他的静态框架)到你的目标 ‘ build settings > Build Phases > Embed Frameworks。然后从下拉菜单中选择 “Embed & Sign”。
你现在可以在 Xcode中使用 ⌘B 编译项目。
下面就是如何实现跳转 flutter 页面
目前只打通了 Object-C 的接入,Swift 还未打通(不是专业的IOS开发,看不懂😭)
在项目入口视图文件添加如下图代码
- (void)buttonClick:(UIButton *)button{
NSLog(@"点击了这个按钮");
FlutterViewController *mainVC = [[FlutterViewController alloc] init];
mainVC.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:mainVC animated:YES completion:nil];
}
Tips
出现如上图错误,说明我们重复引入了 framework,Release、Debug 保留一个,我们处于开发中就保留 Debug
然后重新运行都编译成功了
余下两种集成方式我也列举在下面了
选项 A - 使用 CocoaPods 和 Flutter SDK 集成
这个方法需要你的项目的所有开发者,都在本地安装 Flutter SDK。只需要在 Xcode 中编译应用,就可以自动运行脚本来集成 dart 代码和 plugin。这个方法允许你使用 Flutter module 中的最新代码快速迭代开发,而无需在 Xcode 以外执行额外的命令。
下面的示例假设你的既有应用和 Flutter module 在相邻目录。如果你有不同的目录结构,需要适配到对应的路径。
some/path/
├── my_flutter/
│ └── .ios/
│ └── Flutter/
│ └── podhelper.rb
└── MyApp/
└── Podfile
如果你的应用(MyApp)还没有 Podfile,根据 CocoaPods getting started guide 来在项目中添加 Podfile。
-
在
Podfile中添加下面代码:flutter_application_path = '../my_flutter' load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') -
每个需要集成 Flutter 的 Podfile target,执行
install_all_flutter_pods(flutter_application_path):target 'MyApp' do install_all_flutter_pods(flutter_application_path) end -
在
Podfile的post_install部分,调用flutter_post_install(installer)。post_install do |installer| flutter_post_install(installer) if defined?(flutter_post_install) end -
运行
pod install。
podhelper.rb 脚本会把你的 plugins, Flutter.framework,和 App.framework 集成到你的项目中。
你应用的 Debug 和 Release 编译配置,将会集成相对应的 Debug 或 Release 的 编译产物。可以增加一个 Profile 编译配置用于在 profile 模式下测试应用。
在 Xcode 中打开 MyApp.xcworkspace ,你现在可以使用 ⌘B 编译项目了。
选项 C - 使用 CocoaPods 在 Xcode 和 Flutter 框架中内嵌应用和插件框架
除了将一个很大的 Flutter.framework 分发给其他开发者、机器或者持续集成 (CI) 系统之外,你可以加入一个参数 --cocoapods 将 Flutter 框架作为一个 CocoaPods 的 podspec 文件分发。这将会生成一个 Flutter.podspec 文件而不再生成 Flutter.framework 引擎文件。如选项 B 中所说的那样,它将会生成 App.framework 和插件框架。
flutter build ios-framework --cocoapods --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.
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.
-
In Info-Debug.plist only add the key
NSBonjourServicesand set the value to an array with the string_dartobservatory._tcp. Note Xcode will display this as “Bonjour services”.Optionally, add the key
NSLocalNetworkUsageDescriptionset to your desired customized permission dialog text. -
In your target’s build settings, change the Info.plist File (
INFOPLIST_FILE) setting path frompath/to/Info.plisttopath/to/Info-$(CONFIGURATION).plist.This will resolve to the path Info-Debug.plist in Debug and Info-Release.plist in Release.
Alternatively, 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.
The 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.
Apple Silicon (arm64 Macs)
在使用 Apple Silicon 芯片的 Mac 上 (M1),宿主应用将针对 arm64 架构的模拟器编译。尽管 Flutter 支持 arm64 的 iOS 模拟器,但一些插件仍有可能未进行支持。当你在使用这些插件时,你会遇到 Undefined symbols for architecture arm64 的错误,此时你必须从模拟器支持架构中移除 arm64。
在宿主应用的 Target 中,找到名为 Excluded Architectures (EXCLUDED_ARCHS) 的构建设置。单击右侧的箭头指示器图标以展开可用的构建配置。将鼠标悬停在 Debug 处并单击加号图标。将 Any SDK 更改为 Any iOS Simulator SDK。然后向构建设置值中添加 arm64。
当全部都正确设置后,Xcode 将会向你的 project.pbxproj 文件中添加 "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;。
然后对全部 iOS 目标再次执行单元测试。