Mac配置Jenkins三,使用Xcodepro和PlistBu

2023-05-24  本文已影响0人  独孤流

参考:
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"
上一篇 下一篇

猜你喜欢

热点阅读