在iOS中,我肯定不会写这篇博客。如果我写了,读者会说:你这不是骗流量的么?我又不是小白。哼,取关!😂
打扰了,这里虽然是flutter工程,不过最终体现还是以pod的形式存在于Xcode原生工程中,博主看过一些类似的博文,有博主就是直接在pod中建文件夹把framework拖进去的。不过我们今天肯定不会讲这种方式,第一:太打脸,第二:太没水平,都做flutter了,还按照原生的方式来做,不太好。况且这么做是不安全的,你总不能删了pod之后,每次都要重新做一遍导入的过程吧?
这里博主给大家提供一种便捷的方式,为了方便大家理解,博主这里将新建一个工程来给大家演示:
1.新建工程+plugin(不用演示了吧,小伙伴们)
这是建好的工程目录:
2.在plugin下引入framework
1)打开flugin吓的iOS目录
2)在这个目录下建一个新的文件,名为framework
3)把你的framework拖进来
博主这里叫demo.framework
3.修改podspec文件
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint flutter_plugin.podspec' to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'flutter_plugin'
s.version = '0.0.1'
s.summary = 'A new Flutter plugin.'
s.description = <<-DESC
A new Flutter plugin.
DESC
s.homepage = 'http://example.com'
s.license = { :file => '../LICENSE' }
s.author = { 'Your Company' => 'email@example.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.dependency 'Flutter'
s.platform = :ios, '8.0'
s.vendored_frameworks = 'framework/*.framework'
s.resource = 'framework/*.*'
s.libraries = 'stdc++'
s.resources = 'Assets/*.*'
s.pod_target_xcconfig = {
'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64',
'CLANG_CXX_LANGUAGE_STANDARD' => 'compiler-default',
'CLANG_CXX_LIBRARY' => 'libc++',
'OTHER_LDFLAGS' => '$(inherited) -ObjC'
}
end
4.要在yaml引入这个plugin,否则pod install是拉不到这个plugin的
注意路径不要写错了
5.podfile需要自己创建下,给大家提供一个模版
source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'
# Uncomment this line to define a global platform for your project
platform :ios, '9.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def parse_KV_file(file, separator='=')
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
end
generated_key_values = {}
skip_line_start_symbols = ["#", "/"]
File.foreach(file_abs_path) do |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)
generated_key_values[podname] = podpath
else
puts "Invalid plugin specification: #{line}"
end
end
generated_key_values
end
target 'Runner' do
# Flutter Pod
use_frameworks!
copied_flutter_dir = File.join(__dir__, 'Flutter')
copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
# Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
# That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
# CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
unless File.exist?(generated_xcode_build_settings_path)
raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
unless File.exist?(copied_framework_path)
FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
end
unless File.exist?(copied_podspec_path)
FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
end
end
# Keep pod path relative so it can be checked into Podfile.lock.
pod 'Flutter', :path => 'Flutter'
# Plugin Pods
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
system('rm -rf .symlinks')
system('mkdir -p .symlinks/plugins')
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.each do |name, path|
symlink = File.join('.symlinks', 'plugins', name)
File.symlink(path, symlink)
pod name, :path => File.join(symlink, 'ios')
end
end
# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
install! 'cocoapods', :disable_input_output_paths => true
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
if config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'].to_f < 9.0
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
end
end
end
end
这个模版比较全面,博主项目中的模版和这个就基本差不多,关键是可以区分环境,debug,release这些。
6.这些都做完了,那么就运行下pod install吧
可以看到我们自己的plugin已经被pod装载了
7.打开Xcode看下,你会发现pod中已经存在framework了
8.framework引入完了,这时候我们可能会在plugin中创建一些新的iOS的类,这个时候为了方便调试,我们可以直接在Xcode里面操作了
建的文件或者文件夹要放在Classes文件目录下,这样你会发现你建的文件都会出现在flutter中的Classes下
9.建个新的文件夹和文件看下
接下来看下flutter工程中的Classes下
神奇的发现竟然是同步的,开不开心。
10.到这里,你就学会了如何去自建一个新的plugin,同时你也学会了如何建一个需要依赖第三方framework的plugin,写作不易,给个👍吧!