iOS项目集成flutter及注意事项

本文详细介绍了如何在现有iOS项目中集成Flutter模块,包括环境设置、项目结构调整、podfile配置及bitcode禁用等关键步骤,同时分享了跳转至Flutter页面及解决常见问题的经验。

第一步

电脑集成flutter SDK 设置环境变量等等这里不做过多介绍自行百度
我使用的 channel是stable,你可以flutter channel 命令行查看你的channel,flutter channel stable可以切换到你选的channel(这个channel不知道是不是影响后续操作,如果影响建议跟我保持一致,我同事的在create module的时候podhelper.rb文件就有问题)

第二步

新建一个新的空文件夹test,命令行cd到这个文件夹path。
运行? 名字得小写

 flutter create -t module flutter_module

将现有项目拖入文件夹test与flutter_module同级

如果你安卓的同事已经创建了module文件夹,你也只需要将这个module文件和你原项目文件放在一起就可以了

在这里插入图片描述

只需要看红框的文件层级 其他文件忽略,flutterIOS是我的现有iOS项目

第三步

打开你原iOS项目的podfile文件 顶部插入? 然后 pod install

flutter_application_path = '../flutter_module' 
eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)

flutter_application_path是你module文件的路径
下面那行是将flutter中的framework包导入到原项目pod里,这里可以看出需要读podhelper.rb文件

注意:如果flutter里加入了插件,在flutter packages get 后,原项目还是需要重新 pod install的

pod install之后可以看到pod project里多了一个文件?
在这里插入图片描述

第四步

将targets和project里的 enable bitcode 设置为no ,flutter暂时不支持bitcode
在这里插入图片描述
添加run script
在这里插入图片描述

"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed

注意,这个run script必须得加上这两行以运行dart生成的脚步,否则跳转过去会黑屏

最后build一下就可以跑了

原生项目是跳转到一个flutterViewConterller里,代码可以在Github上看到,这里就不废话了。

踩坑

1、跳转到flutter页面

//        let flutterEngine = (UIApplication.shared.delegate as? AppDelegate)?.flutterEngine;
//        let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)!;
		
        let flutterViewController = FlutterViewController(project: nil, nibName: nil, bundle: nil)!
        flutterViewController.setInitialRoute("/page1")
        self.present(flutterViewController, animated: false, completion: nil)

官方GitHub上的文档是上面注释掉的方式创建VC,但是根本不能跳转到指定路由,采用未注释的方式才能跳转到指定路由页面

2、需要修改.ios文件里,这个文件的配置信息generated.xcconfig的修改

3、同事用的channel是master ,create module 后 podhelper.rb一直有问题,如果遇到pod install 无法导入flutter的问题,可以改一下podhelper.rb的内容?,修改完了之后重新pod install。之前说了你在podfile文件里加的那两行代码就是来读这个.rb文件的。作用就是将flutter里的插件和代码导入到pod project里。注意,在pod install 之前Flutter文件里只保留这5个文件,生成的engine文件夹里的就是要导入到原项目里的
在这里插入图片描述

def parse_KV_file(file, separator='=')
    file_abs_path = File.expand_path(file)
    if !File.exists? file_abs_path
        return [];
    end
    pods_array = []
    skip_line_start_symbols = ["#", "/"]
    File.foreach(file_abs_path) { |line|
        next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
        plugin = line.split(pattern=separator)
        if plugin.length == 2
            podname = plugin[0].strip()
            path = plugin[1].strip()
            podpath = File.expand_path("#{path}", file_abs_path)
            pods_array.push({:name => podname, :path => podpath});
         else
            puts "Invalid plugin specification: #{line}"
        end
    }
    return pods_array
end

def flutter_root(f)
    generated_xcode_build_settings = parse_KV_file(File.join(f, File.join('.ios', 'Flutter', 'Generated.xcconfig')))
    if generated_xcode_build_settings.empty?
        puts "Generated.xcconfig must exist. Make sure `flutter pub get` is executed in #{f}."
        exit
    end
    generated_xcode_build_settings.map { |p|
        if p[:name] == 'FLUTTER_ROOT'
            return p[:path]
        end
    }
end

# If this wasn't specified, assume it's two levels up from the directory of this script.
flutter_application_path ||= File.join(__dir__, '..', '..')
framework_dir = File.join(flutter_application_path, '.ios', 'Flutter')

engine_dir = File.join(framework_dir, 'engine')
if !File.exist?(engine_dir)
    # Copy the debug engine to have something to link against if the xcode backend script has not run yet.
    debug_framework_dir = File.join(flutter_root(flutter_application_path), 'bin', 'cache', 'artifacts', 'engine', 'ios')
    FileUtils.mkdir_p(engine_dir)
    FileUtils.cp_r(File.join(debug_framework_dir, 'Flutter.framework'), engine_dir)
    FileUtils.cp(File.join(debug_framework_dir, 'Flutter.podspec'), engine_dir)
end

pod 'Flutter', :path => engine_dir
pod 'FlutterPluginRegistrant', :path => File.join(framework_dir, 'FlutterPluginRegistrant')

symlinks_dir = File.join(framework_dir, '.symlinks')
FileUtils.mkdir_p(symlinks_dir)
plugin_pods = parse_KV_file(File.join(flutter_application_path, '.flutter-plugins'))
plugin_pods.map { |r|
    symlink = File.join(symlinks_dir, r[:name])
    FileUtils.rm_f(symlink)
    File.symlink(r[:path], symlink)
    pod r[:name], :path => File.join(symlink, 'ios')
}

# Ensure that ENABLE_BITCODE is set to NO, add a #include to Generated.xcconfig, and
# add a run script to the Build Phases.
post_install do |installer|
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings['ENABLE_BITCODE'] = 'NO'
            next if  config.base_configuration_reference == nil
            xcconfig_path = config.base_configuration_reference.real_path
            File.open(xcconfig_path, 'a+') do |file|
                file.puts "#include \"#{File.realpath(File.join(framework_dir, 'Generated.xcconfig'))}\""
            end
        end
    end
end

<think>根据用户的问题和提供的引用内容,用户希望了解如何将Flutter SDK接入现有的iOS项目。结合引用中的信息,以下是详细的步骤指南: ### 1. **安装Flutter SDK** 首先确保开发环境中已安装Flutter SDK。从Flutter官网下载适合的版本并安装。安装完成后,在终端运行以下命令验证安装: ```bash flutter doctor ``` 确保所有依赖项都正确配置,特别是iOS开发环境(如Xcode)[^1]。 ### 2. **创建Flutter模块** 在现有iOS项目的**同级目录**下,创建Flutter模块(而非独立Flutter应用): ```bash flutter create --template module my_flutter_module ``` 其中`my_flutter_module`为模块名称。此命令会生成一个包含iOS和Android子目录的Flutter模块[^1]。 ### 3. **通过CocoaPods集成Flutter模块** 在现有iOS项目的`Podfile`中添加以下代码,将Flutter模块作为依赖: ```ruby flutter_application_path = '../my_flutter_module' load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') target 'Your_iOS_App_Target' do install_all_flutter_pods(flutter_application_path) end ``` 运行`pod install`完成集成[^1][^4]。 ### 4. **配置iOS工程** - **关闭Bitcode**:在Xcode的`Build Settings`中,将`Enable Bitcode`设置为`NO`(Flutter暂不支持Bitcode)[^4]。 - **添加构建脚本**: 1. 在Xcode中选中iOS项目Target,进入`Build Phases`。 2. 点击左上角`+`,选择`New Run Script Phase`。 3. 将以下脚本粘贴到输入框中: ```bash "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed ``` 此脚本确保Flutter代码在编译时被正确构建和嵌入[^4]。 ### 5. **在iOS代码中调用Flutter** 在需要跳转至Flutter页面的地方,初始化`FlutterEngine`并加载视图: ```swift import Flutter import FlutterPluginRegistrant class FlutterManager { lazy var flutterEngine = FlutterEngine(name: "my_flutter_engine") func startFlutter() { flutterEngine.run() GeneratedPluginRegistrant.register(with: self.flutterEngine) } } // 在ViewController中使用 let flutterEngine = FlutterManager().flutterEngine let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil) present(flutterViewController, animated: true) ``` 此代码启动Flutter引擎并展示Flutter界面[^3][^4]。 ### 6. **处理第三方SDK(可选)** 若Flutter模块需使用第三方SDK(如支付、地图等),在Flutter模块的`pubspec.yaml`中添加依赖: ```yaml dependencies: flutter: sdk: flutter firebase_core: ^2.0.0 # 示例:Firebase SDK ``` 然后在iOS端的`Podfile`中同步更新原生SDK依赖[^2]。 ### 注意事项 - **混合开发调试**:使用`flutter attach`命令连接到运行中的iOS应用调试Flutter模块: ```bash flutter attach -d 'iPhone 14' ``` - **性能优化**:避免频繁启动`FlutterEngine`,建议全局共享引擎实例以减少开销[^4]。 通过以上步骤,可将Flutter SDK无缝集成到现有iOS项目中,实现原生与Flutter的混合开发。 §§相关问题§§ 1. 如何处理FlutteriOS原生之间的数据通信? 2. 集成Flutter后如何优化混合应用的启动性能? 3. 在混合开发中如何管理iOSFlutter的依赖冲突? </think>### 如何将Flutter SDK接入现有iOS项目(基于引用内容整理) #### 📦 核心步骤: 1. **环境准备** - 安装最新版Flutter SDK(通过官网下载并配置环境变量) - 验证安装:终端执行 `flutter doctor` 确保iOS工具链正常[^1] 2. **创建Flutter模块** ```bash # 在iOS项目同级目录执行 flutter create --template module my_flutter_module ``` - 注意:**不要使用独立Flutter工程**(引用[4]指出默认方案不适合现有工程)[^4] 3. **CocoaPods集成(推荐方案)** - 修改iOS项目的Podfile: ```ruby # 添加Flutter模块路径 flutter_application_path = '../my_flutter_module' load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') target 'Your_iOS_App' do install_all_flutter_pods(flutter_application_path) # 引用[1][4]关键方法[^1][^4] end ``` - 执行 `pod install` 4. **Xcode配置** - **关闭Bitcode**(Build Settings → Enable Bitcode → NO) - 添加构建脚本(Build Phases → New Run Script Phase): ```bash "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed ``` - 删除默认的`App.framework`引用(避免冲突)[^4] 5. **调用Flutter页面(Swift示例)** ```swift import Flutter func showFlutterScreen() { let flutterEngine = FlutterEngine(name: "io.flutter") flutterEngine.run() let controller = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil) present(controller, animated: true) } ``` #### ⚠️ 关键注意事项: 1. **架构兼容性**:确保Flutter模块与iOS项目的架构版本一致(如iOS 11+) 2. **插件管理**: - 第三方SDK需同时配置iOS原生依赖和Flutter插件(引用[2])[^2] - 在Flutter模块的`pubspec.yaml`添加插件后,需在iOS端重新执行 `pod install` 3. **混合路由**:引用[3]建议使用`ios_sdk_flutter_plugin`等方案管理原生页面跳转[^3] #### 🔧 调试技巧: ```bash # 附加调试器到运行中的iOS应用 flutter attach -d 'iPhone' ``` > 通过CocoaPods集成的方案比直接嵌入框架更易维护,可避免引用[4]提到的默认方案问题[^4]。若遇到构建失败,检查`flutter doctor`输出的iOS工具链警告。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值