已有项目配置flutter(iOS篇进阶)

前篇:已有项目配置flutter(iOS篇)

该文档已过时,可点击查看下面的最新官方文档链接

官方参考文档

官方给出了flutter在iOS上的简单导入,但是当出现post_install仅能有一个的问题该怎么解决了?
解决思路:既然不能出现多次post_install, 那么只好将需要post_install的地方合并了

  • 看官方配置pod
# “path/to” 是自己项目的路径
flutter_application_path = 'path/to/my_flutter/'
  load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
  • 根据flutter_application_path,找到自己项目下的podhelper.rb,将其复制到ios项目根目录下。
  • 修改podhelper.rb中涉及到的路径。
  • 重新配置Podfile中的podhelper.rb路径flutter_application_path
flutter_application_path ||= File.join(__dir__, '..', 'flutter_demo')
framework_dir = File.join(flutter_application_path, '.ios', 'Flutter')
  • 对比Podfilepodhelper.rbpost_install代码块的不同,然后合并到Podfile,并将podhelper.rb中的post_install代码块注释掉。
  • 这是本人在flutter 1.0时的做法,现在flutter升级到了1.7.8, 还能正常运行。
  • 下面贴出Podfile的部分代码与podhelper.rb的全部代码,包括本人的注释。注意看注释哦
    我的flutter项目名称是flutter_demo,ios项目名称TestFlutter。两个项目在同一个文件夹下,这样方便使用相对路径。

Podfile 部分代码

# 配置flutter:
# - swift与oc的桥接配置‘use_frameworks!’上边已经配置,这里就不配置了
# - bitcode 需要设置为NO, 工程中也已经设置,这里也不设置了。pod里的设置方法可参考:https://www.jianshu.com/p/bf3002de6a5e。个人不建议在pod中设置
# - 如果podfile中没使用post_install, 则可以直接使用下面两句代码就行了。但是已经使用了,所以需要从新配置。
# flutter_application_path = '../flutter_demo/'
# eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
# - 将需要使用的podhelper.rb复制到ios项目中,然后按照iOS项目下podhelper.rb中写的步骤继续配置
# - 以下代码是导入flutter
#eval(File.read(File.join(__dir__, 'podhelper.rb')), binding)
# - framework_dir路径配置
flutter_application_path ||= File.join(__dir__, '..', 'flutter_demo')
framework_dir = File.join(flutter_application_path, '.ios', 'Flutter')

post_install do |installer|
    installer.pods_project.targets.each do |target|
        # 强制设置SWIFT_VERSION为'5'
        target.build_configurations.each do |config|
            config.build_settings['SWIFT_VERSION'] = '5.0'
        end
        
        if [].include? target.name
            target.build_configurations.each do |config|
                config.build_settings['SWIFT_VERSION'] = '4.2'
            end
        end

        if target.name == 'Params' then
            target.build_configurations.each do |config|
                config.build_settings['GCC_OPTIMIZATION_LEVEL'] = '0'
            end
        elsif target.name == 'SVProgressHUD'
            target.build_configurations.each do |config|
                config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)']
                config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'SV_APP_EXTENSIONS'
            end
        elsif target.name == 'SSMessage'
            target.build_configurations.each do |config|
                config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)']
                config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'SSMESSAGE_NEWALERT=1'
            end
            # flutter
          # elsif target.name == 'Flutter' || target.name == 'TestFlutter'
          #   target.build_configurations.each do |config|
          #       config.build_settings['ENABLE_BITCODE'] = 'NO'
          #       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

                target.build_configurations.each do |config|
                    config.build_settings['ENABLE_BITCODE'] = 'NO'
                    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

podhelper.rb全部代码

# 文件改动解析:
# - 该文件从目标项目flutter_demo中复制过来
# - 方法parse_KV_file(), flutter_root() 不做修改
# - 由于该文件的路径改变了,所以需要修改flutter_application_path的值。__dir__ 应该表示当前路径
# - podfile不能使用多个post_install,所以post_install中的操作,移动到podfile中操作,并且将该文件中的操作注释掉。需要注意的是,修改其中的路径值。
# -
# -
# -

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 packages 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__, '..', 'flutter_demo')
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.
# TODO(dnfield): Figure out a way to deliver the Build Phase scripts without manual user intervention.
# post_install do |installer|
#     installer.pods_project.targets.each do |target|
#         target.build_configurations.each do |config|
#             config.build_settings['ENABLE_BITCODE'] = 'NO'
#             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

  • 为什么复制podhelper.rb,而不是直接修改了??
    因为Flutter Module经常重构.android,不知道什么时候podhelper.rb就被还原了。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容