Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说ios定制化的自动打包脚本是什么_苹果手机脚本制作软件,希望能够帮助你!!!。
本文主要是基于用同一套代码生成不用包名、不同开发者证书、不同功能、不同组件依赖、不同Extension、多target等各种需求定制。
project_path = 'xxx.xcodeproj'
project = Xcodeproj::Project.open(project_path)
project.targets.each do |target|
#your target name
if target.name == 'Scene'
target.build_configurations.each do |config|
# Debug / Release
if config.name == 'Release'
#获得build settings
build_settings = config.build_settings
#build_settings是一个哈希,里面是一个个配置
build_settings.each do |key,value|
print key, " == ", value, "\n"
# 可在这里进行设置证书等操作,常用的如下:
# 比如修改bundle id ,测试
# build_settings[key] = "com.test.demo"
# 设置授权文件
# build_settings["CODE_SIGN_ENTITLEMENTS"] = "xxx.entitlements"
# 设置签名 iPhone Distribution / iPhone Developer
build_settings["PROVISIONING_PROFILE_SPECIFIER"] = "PROFILENAME"
build_settings["PRODUCT_BUNDLE_IDENTIFIER"] = "your BUNDLEID"
build_settings["DEVELOPMENT_TEAM"] = "your TEAMID"
# ..... 其他的视情况(需求)去查找API
end
end
end
end
def updateDependecies(mode, project, app_target_name, ext)
require 'xcodeproj'
# Find project and app target
puts mode
xc = project
app_target = xc.targets.find { |t| t.name == app_target_name }
# Find app extensions' target objects
target = xc.targets.find { |t| t.name == ext }
return "Couldn't find a '#{ext}' target in '#{app_target_name}'" if target.nil?
return "'#{ext}' doesn't seem to be an application extension target" unless target.product_type.include? 'app-extension'
target
# Find .appex product files
appex = target.product_reference
# Add or remove dependency on extension targets
dependency = app_target.dependency_for_target(target)
puts app_target.dependencies
if mode == 'add'
if dependency
puts "[WARN] App already has dependency on #{target.name}"
else
app_target.add_dependency(target)
end
else
if dependency
app_target.dependencies.delete(dependency)
else
puts "[WARN] Couldn't find dependency on #{target.name}"
end
end
# Add or remove .appex copy jobs
embed_extensions_phase = app_target.copy_files_build_phases.find do |copy_phase|
copy_phase.symbol_dst_subfolder_spec == :plug_ins
end
return "Couldn't find 'Embed App Extensions' phase" if embed_extensions_phase.nil?
appex_included = embed_extensions_phase.files_references.include? appex
if mode == 'add'
if appex_included
puts "[WARN] App already embeds #{appex.display_name}"
else
build_file = embed_extensions_phase.add_file_reference(appex)
build_file.settings = { "ATTRIBUTES" => ['RemoveHeadersOnCopy'] }
end
else
if appex_included
embed_extensions_phase.remove_file_reference(appex)
else
puts "[WARN] App doesn't seem to embed #{appex.display_name}"
end
end
return "更新依赖完成,update dependency '#{ext}' target in '#{app_target_name}'"
end
Link binary with libraries system libraries, link them.
Embed Frameworks 3rd party libraries, embed them.
def exsit_framework?(build_phase,name)
# next !if build_phase.nil?
build_phase.files_references.each do |ref|
if ref.name == "#{name}"
puts "已经存在 #{name}"
return true
end
end
puts "不存在 #{name}"
return false
end
def updateSystemFramework(project,target,name, command)
require 'xcodeproj'
puts "#{command} #{name} to #{target}"
build_phase = target.frameworks_build_phase
framework_group = project.frameworks_group
if command == :add
if self.exsit_framework?(build_phase,name)
return
end
systempath = "System/Library/Frameworks/"
path = "#{systempath}#{name}"
file_ref = framework_group.new_reference(path)
file_ref.name = "#{name}"
file_ref.source_tree = 'SDKROOT'
build_file = build_phase.add_file_reference(file_ref)
else
build_phase.files_references.each do |ref|
if ref.name == "#{name}"
puts "删除 #{name}"
build_phase.remove_file_reference(ref)
framework_group.children.delete(ref)
break
end
end
end
end
def updateCustomFramework(project,target, path,name,command)
# Get useful variables
frameworks_group = project.groups.find { |group| group.display_name == 'Frameworks' }
frameworks_build_phase = target.build_phases.find { |build_phase| build_phase.to_s == 'FrameworksBuildPhase' }
embed_frameworks_build_phase = nil
target.build_phases.each do |phase|
if phase.display_name == 'Embed Frameworks'
embed_frameworks_build_phase = phase
end
# puts phase
end
if command == :add
# Add new "Embed Frameworks" build phase to target
if embed_frameworks_build_phase.nil?
embed_frameworks_build_phase = project.new(Xcodeproj::Project::Object::PBXCopyFilesBuildPhase)
embed_frameworks_build_phase.name = 'Embed Frameworks'
embed_frameworks_build_phase.symbol_dst_subfolder_spec = :frameworks
target.build_phases << embed_frameworks_build_phase
end
# Add framework search path to target
['Debug', 'Release'].each do |config|
paths = ['$(inherited)', path]
orgpath = target.build_settings(config)['FRAMEWORK_SEARCH_PATHS']
if orgpath.nil?
puts "路径为空----------"
target.build_settings(config)['FRAMEWORK_SEARCH_PATHS'] = paths
else
puts "路径非空----------"
paths.each do |p|
if !orgpath.include?(p)
orgpath << p
end
end
end
end
# Add framework to target as "Embedded Frameworks"
framework_ref = frameworks_group.new_file("#{path}#{name}")
exsit = false
embed_frameworks_build_phase.files_references.each do |ref|
if ref.name = name
exsit = true
end
end
if !exsit
build_file = embed_frameworks_build_phase.add_file_reference(framework_ref)
frameworks_build_phase.add_file_reference(framework_ref)
build_file.settings = { 'ATTRIBUTES' => ['CodeSignOnCopy'] }
end
else
frameworks_build_phase.files_references.each do |ref|
if ref.name == "#{name}"
puts "删除 #{name}"
frameworks_build_phase.remove_file_reference(ref)
embed_frameworks_build_phase.remove_file_reference(ref)
break
end
end
end
end
例如:AccessWiFi
#从外面传入的参数
wifiFlag = ARGV[0]
project.objects.each do |obj|
if obj.isa == "PBXProject"
systemCapabilities = obj.attributes["TargetAttributes"][ta.uuid]["SystemCapabilities"]
puts systemCapabilities
systemCapabilities["com.apple.AccessWiFi"] = {"enabled":"#{wifiFlag}"}
end
end
target 'Scene' do
pod 'iOSExtension/Widgets',:path => '../'
pod 'XXX'
pod 'YYY'
pod 'AAA'
pod 'BBB'
end
使用sed 命令删除包名XXX的指定行
$sed -i '' "/XXX.*/d" filePath
$sed -i '' "/XXX.*/d" filePath
$sed -i '' "/YYY.*/d" filePath
$sed -i '' "/AAA.*/d" filePath
$sed -i '' "/BBB.*/d" filePath
其实,Podfile 本身也是一个ruby文件,所以在其中可以定义函数。这时候,解决上面移除多个pod库的,可以定义一个函数
def myPodModule(flag)
if flag == 0
puts "不--安装myPodModule"
return
end
pod 'XXX'
pod 'YYY'
pod 'AAA'
pod 'BBB'
puts "安装myPodModule"
end
target 'Scene' do
pod 'iOSExtension/Widgets',:path => '../'
#调用
myPodModule(1)
end
脚本如下:
#依赖的脚本
$sed -i "" 's/myPodModule(0)/myPodModule(1)/g' xxx/Podfile
#不依赖的脚本
$sed -i "" 's/myPodModule(1)/myPodModule(0)/g' xxx/Podfile
原始的Podfile 的结构如下:
target 'Scene' do
pod 'iOSExtension/Widgets',:path => '../'
end
target 'Widgets' do
pod 'my/Wiget',:path => '../'
end
这时候的脚本让我很难受。其实同样可以采用上面的思路去封装
def widgets(flag)
if flag == 0
puts "不--给widgets target安装依赖"
return
end
target 'Widgets' do
pod 'my/Wiget',:path => '../'
end
end
target 'Scene' do
pod 'iOSExtension/Widgets',:path => '../'
end
#调用
widgets(1)
脚本如下:
#依赖的脚本
$sed -i "" 's/widgets(0)/widgets(1)/g' xxx/Podfile
#不依赖的脚本
$sed -i "" 's/widgets(1)/widgets(0)/g' xxx/Podfile
post_install do |installer|
project = installer.aggregate_targets.first.user_project
project.targets.each do |target|
puts target.name,'名称:'
end
end
Xcodeproj GitHub地址
Xcodeproj API文档
fuck996