第一步
电脑集成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文件里,这个文件的配置信息
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