参考:
PlistBuddy基本使用方法
https://github.com/CocoaPods/Xcodeproj
本文完整代码:https://github.com/h42330789/testplist/tree/main/ReadWriteXcodeproj
前言,打包过程中,需要读取或修改版本号、bundleId等信息,之前可以使用PlistBuddy读取,现在配置在xcodeproj文件里后,就难以读取和修改,但是使用Xcodeproj可以很方便的读取和修改
一、使用PlistBuddy读取Info.plist里的配置信息,在之前的项目里可能有,现在的新项目一般都放到了project.pbxproj里
#### 使用PlistBuddy从Info.plist里读取
infoPlistPath="/Users/macbookpro/Documents/study/HelloPod/HelloPod/Info.plist"
bundleDisplayName=`/usr/libexec/PlistBuddy -c "Print CFBundleDisplayName" $infoPlistPath`
# APP版本号,如1.0.1, 在新版xcode生成的项目里可能是MARKETING_VERSION,或者根本不存在,则需要去project.pbxproj里去读取
bundleVersion=`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" $infoPlistPath`
# APP的build版本,一般使用数字,如1,在新版xcode生成的项目里可能是CURRENT_PROJECT_VERSION,或者不存在,则需要去project.pbxproj里去读取
bundleBuildVersion=`/usr/libexec/PlistBuddy -c "Print CFBundleVersion" $infoPlistPath`
# APP的bundleId,如com.ab.xyz 在新版xcode生成的项目里可能是PRODUCT_BUNDLE_IDENTIFIER,或者不存在,则需要去project.pbxproj里去读取
bundleId=`/usr/libexec/PlistBuddy -c "Print CFBundleIdentifier" $infoPlistPath`
echo "bundleDisplayName: $bundleDisplayName"
echo "bundleVersion: $bundleVersion"
echo "bundleBuildVersion: $bundleBuildVersion"
echo "bundleId: $bundleId"
二、使用Xcodeproj从project.pbxproj里读取
2.1 安装xcodeproj
sudo gem install xcodeproj
2.2 使用xcodeproj
读取xcode配置文件
创建一个以.rb为结尾的文件, 遍历循环target和config,然后从buildSetting里读取
# 读取里buildSetting里的数据
def readBuildSetting(xcodeprojPath, findTargetName, findConfigName, findKey)
# 读取xcode的配置信息, xxx/xxx/xx.xcodeproj
project = Xcodeproj::Project.open(xcodeprojPath)
# 遍历target、config是否一直
project.targets.each do |target|
targetName = target.name
target.build_configurations.each do |config|
configName = config.name
build_settings = config.build_settings
if (targetName == findTargetName) && (configName == findConfigName)
# 查找到对应的build_settings后,读取对应的key
findValue = config.build_settings[findKey]
# 将查找的内容,存放到plist里
puts "#{findKey}: #{findValue}"
return
end
end
end
end
2.3 使用xcodeproj
修改xcode配置文件
创建一个以.rb为结尾的文件, 遍历循环target和config,然后从buildSetting里读取
# 修改里buildSetting里的数据
def updateBuildSetting(xcodeprojPath, findTargetName, findConfigName, updateKey, updateValue)
# 读取xcode的配置信息, xxx/xxx/xx.xcodeproj
project = Xcodeproj::Project.open(xcodeprojPath)
# 遍历target、config是否一直
project.targets.each do |target|
targetName = target.name
target.build_configurations.each do |config|
configName = config.name
build_settings = config.build_settings
if (targetName == findTargetName) && (configName == findConfigName)
# 修改内容
config.build_settings[updateKey] = updateValue
end
end
end
# 保存修改
project.save()
end
完整的实现:
#!/usr/bin/ruby
# https://github.com/CocoaPods/Xcodeproj
require 'xcodeproj'
# ruby 非空判断 https://blog.csdn.net/leinminna/article/details/110422744
# 在 Ruby 中执行 Shell 命令的 6 种方法 https://segmentfault.com/a/1190000000368191
# 增加或修改key对应的value,如果不存在就增加,如果存在不一致就修改
def changeDict(dict, key, value)
if (dict.has_key?(key))
oldValue = dict[key]
if (oldValue != value)
dict[key] = value
return true
end
else
dict[key] = value
return true
end
return false
end
# 删除key,如果存在才删除
def deleteDict(dict, key)
if (dict.has_key?(key))
dict.delete(key)
return true
end
return false
end
# bool值取或运输
def boolOr(a, b)
if (a == false and b == false)
return false
end
return true
end
# bool值取与运输
def boolAnd(a, b)
if (a == true and b == true)
return true
end
return false
end
def updateParamPlist(paramPlistPath, key, value)
oldVale = `/usr/libexec/PlistBuddy -c "Print #{key}" #{paramPlistPath}`
if oldVale.nil? || oldVale.empty?
# 之前不存在,则添加
`/usr/libexec/PlistBuddy -c 'Add :#{key} string #{value}' #{paramPlistPath}`
else
# 之前存在,则修改
`/usr/libexec/PlistBuddy -c 'Set :#{key} #{value}' #{paramPlistPath}`
end
puts "read key: #{key} oldVale: #{oldVale} newValue: #{value}"
end
# 读取xcoceproj里buildSetting里的数据
def readBuildSetting(xcodeprojPath, findTargetName, findConfigName, findKey, paramPlistPath)
# puts "xcodeprojPath: #{xcodeprojPath}"
# puts "findTargetName: #{findTargetName}"
# puts "findConfigName: #{findConfigName}"
project = Xcodeproj::Project.open(xcodeprojPath)
project.targets.each do |target|
targetName = target.name
target.build_configurations.each do |config|
configName = config.name
build_settings = config.build_settings
if (targetName == findTargetName) && ((findConfigName == "All") || (configName == findConfigName))
findValue = config.build_settings[findKey]
# 将查找的内容,存放到plist里
updateParamPlist(paramPlistPath, findKey, findValue)
puts "----------readBuildSetting---success--end---------------"
return
end
end
end
puts "----------readBuildSetting--error--end-------------"
end
# 读取xcoceproj里buildSetting里的数据
def updateBuildSetting(xcodeprojPath, findTargetName, findConfigName, updateKey, updateValue)
isNeedChange = false
project = Xcodeproj::Project.open(xcodeprojPath)
project.targets.each do |target|
targetName = target.name
target.build_configurations.each do |config|
configName = config.name
build_settings = config.build_settings
if (targetName == findTargetName) && ((findConfigName == "All") || (configName == findConfigName))
isNeedChange = boolOr(isNeedChange, changeDict(build_settings, updateKey, updateValue))
# 将查找的内容,存放到plist里
puts "----------updateBuildSetting---success--end---------------"
end
end
end
# 保存配置
if (isNeedChange == true)
project.save()
end
end
# 对项目设置成自动管理
def updateAutoProfile(xcodeprojPath, findTargetName, findConfigName, newTeamId, newBundleId)
isNeedChange = false
project = Xcodeproj::Project.open(xcodeprojPath)
project.targets.each do |target|
targetName = target.name
target.build_configurations.each do |config|
configName = config.name
build_settings = config.build_settings
if (targetName == findTargetName) && ((findConfigName == "All") || (configName == findConfigName))
# 删除手动管理相关的配置
isNeedChange = boolOr(isNeedChange, deleteDict(build_settings, "CODE_SIGN_IDENTITY[sdk=iphoneos*]"))
isNeedChange = boolOr(isNeedChange, deleteDict(build_settings, "CODE_SIGN_STYLE"))
isNeedChange = boolOr(isNeedChange, deleteDict(build_settings, "DEVELOPMENT_TEAM"))
isNeedChange = boolOr(isNeedChange, deleteDict(build_settings, "DEVELOPMENT_TEAM[sdk=iphoneos*]"))
isNeedChange = boolOr(isNeedChange, deleteDict(build_settings, "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]"))
isNeedChange = boolOr(isNeedChange, deleteDict(build_settings, "PROVISIONING_PROFILE_SPECIFIER"))
# 修改
isNeedChange = boolOr(isNeedChange, changeDict(build_settings, "CODE_SIGN_STYLE", "Automatic"))
isNeedChange = boolOr(isNeedChange, changeDict(build_settings, "DEVELOPMENT_TEAM", newTeamId))
isNeedChange = boolOr(isNeedChange, changeDict(build_settings, "PRODUCT_BUNDLE_IDENTIFIER", newBundleId))
isNeedChange = boolOr(isNeedChange, changeDict(build_settings, "CODE_SIGN_IDENTITY", "Apple Development"))
end
end
end
puts "isNeedChange #{isNeedChange}"
# 保存配置
if (isNeedChange == true)
project.save()
end
end
# 对项目设置成手动管理
def updateManualProfile(xcodeprojPath, findTargetName, findConfigName, newTeamId, newBundleId, newProfileName)
isNeedChange = false
project = Xcodeproj::Project.open(xcodeprojPath)
project.targets.each do |target|
targetName = target.name
target.build_configurations.each do |config|
configName = config.name
build_settings = config.build_settings
if (targetName == findTargetName) && ((findConfigName == "All") || (configName == findConfigName))
# 去掉自动管理证书,证书方
isNeedChange = boolOr(isNeedChange, deleteDict(build_settings, "CODE_SIGN_IDENTITY"))
isNeedChange = boolOr(isNeedChange, deleteDict(build_settings, "CODE_SIGN_STYLE"))
# 增加手动管理证书
isNeedChange = boolOr(isNeedChange, changeDict(build_settings, "CODE_SIGN_IDENTITY[sdk=iphoneos*]", "iPhone Distribution"))
isNeedChange = boolOr(isNeedChange, changeDict(build_settings, "CODE_SIGN_STYLE", "Manual"))
isNeedChange = boolOr(isNeedChange, changeDict(build_settings, "DEVELOPMENT_TEAM[sdk=iphoneos*]", newTeamId))
isNeedChange = boolOr(isNeedChange, changeDict(build_settings, "DEVELOPMENT_TEAM", newTeamId))
isNeedChange = boolOr(isNeedChange, changeDict(build_settings, "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]", newProfileName))
isNeedChange = boolOr(isNeedChange, changeDict(build_settings, "PRODUCT_BUNDLE_IDENTIFIER", newBundleId))
isNeedChange = boolOr(isNeedChange, changeDict(build_settings, "CODE_SIGN_IDENTITY", "Apple Distribution"))
end
end
end
puts "isNeedChange #{isNeedChange}"
# 保存配置
if (isNeedChange == true)
project.save()
end
end
type=ARGV[0]
if type == "write"
# 给buildSetting里设置信息
xcodeprojPath = ARGV[1]
findTargeName = ARGV[2]
findConfigName = ARGV[3]
updateKey = ARGV[4]
updateValue = ARGV[5]
updateBuildSetting(xcodeprojPath, findTargeName, findConfigName, updateKey, updateValue)
elsif type == "read"
# 读取buildSetting里的信息
xcodeprojPath = ARGV[1]
findTargeName = ARGV[2]
findConfigName = ARGV[3]
findKey = ARGV[4]
paramPlistPath = ARGV[5]
readBuildSetting(xcodeprojPath, findTargeName, findConfigName, findKey, paramPlistPath)
elsif type == "autoProfile"
# 设置自动管理证书
xcodeprojPath = ARGV[1]
findTargeName = ARGV[2]
findConfigName = ARGV[3]
newTeamId = ARGV[4]
newBundleId = ARGV[5]
updateAutoProfile(xcodeprojPath, findTargetName, findConfigName, newTeamId, newBundleId)
elsif type == "manualProfile"
# 设置手动管理证书
xcodeprojPath = ARGV[1]
findTargeName = ARGV[2]
findConfigName = ARGV[3]
newTeamId = ARGV[4]
newBundleId = ARGV[5]
newProfileName = ARGV[6]
updateManualProfile(xcodeprojPath, findTargetName, findConfigName, newTeamId, newBundleId, newProfileName)
end
完整的调用示例
#!/bin/sh
export LC_ALL=en_US.UTF-8
#### 使用PlistBuddy从Info.plist里读取
infoPlistPath="/Users/macbookpro/Documents/study/HelloPod/HelloPod/Info.plist"
bundleDisplayName=`/usr/libexec/PlistBuddy -c "Print CFBundleDisplayName" $infoPlistPath`
# APP版本号,如1.0.1, 在新版xcode生成的项目里可能是MARKETING_VERSION,或者根本不存在,则需要去project.pbxproj里去读取
bundleVersion=`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" $infoPlistPath`
# APP的build版本,一般使用数字,如1,在新版xcode生成的项目里可能是CURRENT_PROJECT_VERSION,或者不存在,则需要去project.pbxproj里去读取
bundleBuildVersion=`/usr/libexec/PlistBuddy -c "Print CFBundleVersion" $infoPlistPath`
# APP的bundleId,如com.ab.xyz 在新版xcode生成的项目里可能是PRODUCT_BUNDLE_IDENTIFIER,或者不存在,则需要去project.pbxproj里去读取
bundleId=`/usr/libexec/PlistBuddy -c "Print CFBundleIdentifier" $infoPlistPath`
echo "bundleDisplayName: $bundleDisplayName"
echo "bundleVersion: $bundleVersion"
echo "bundleBuildVersion: $bundleBuildVersion"
echo "bundleId: $bundleId"
#### 使用xcodeProj从project.pbxproj里读取
rubyPath=`which ruby`
rubyScriptPath="/Users/macbookpro/Desktop/test/xcodeprojTool.rb"
xcodeprojPath="/Users/macbookpro/Documents/study/HelloPod/HelloPod.xcodeproj"
infoPlistPath="/Users/macbookpro/Documents/study/HelloPod/HelloPod/Info.plist"
paramPlistPath="./param.plist"
findTargetName="HelloPod"
readConfig="Release" # Release Debug All
writeConfig="All"
# 读取版本号
$rubyPath $rubyScriptPath "read" $xcodeprojPath $findTargetName $readConfig "MARKETING_VERSION" $paramPlistPath
# 读取编译版本号
$rubyPath $rubyScriptPath "read" $xcodeprojPath $findTargetName $readConfig "CURRENT_PROJECT_VERSION" $paramPlistPath
# 读取bundleId
$rubyPath $rubyScriptPath "read" $xcodeprojPath $findTargetName $readConfig "PRODUCT_BUNDLE_IDENTIFIER" $paramPlistPath
# 读取App名称
$rubyPath $rubyScriptPath "read" $xcodeprojPath $findTargetName $readConfig "INFOPLIST_KEY_CFBundleDisplayName" $paramPlistPath
# 修改内容
# 修改版本号
$rubyPath $rubyScriptPath "write" $xcodeprojPath $findTargetName $writeConfig "MARKETING_VERSION" "1.12.002"
# 修改编译版本号
$rubyPath $rubyScriptPath "write" $xcodeprojPath $findTargetName $writeConfig "CURRENT_PROJECT_VERSION" "88"
# 修改bundleId
$rubyPath $rubyScriptPath "write" $xcodeprojPath $findTargetName $writeConfig "PRODUCT_BUNDLE_IDENTIFIER" "www.ab.com"
# 修改App名称
$rubyPath $rubyScriptPath "write" $xcodeprojPath $findTargetName $writeConfig "INFOPLIST_KEY_CFBundleDisplayName" "bestAp"
网友评论