草庐IT

iOS开发之Build版本号自增

BrianWang 2023-10-15 原文

1. 背景

在iOS项目打包时,有两个版本号,一个是Version,即显示在AppStore中的版本号,其key为CFBundleShortVersionString,另一个是Build,即编译版本号,其key为CFBundleVersion

2. 问题发现

当App准备上架时,需要打包提交至AppStore审核,在这个过程中我们可能会多次上传ipa包。在Version相同的情况下,若Build还相同,则上传到App Store Connect时会提示已有该版本,不能再次上传。

3. 问题解决

为了避免这种情况,我们可以在每次打包前去手动修改Build,以保证不会重复。或者我们可以通过脚本让Build在每次打包时自动加一,省去每次手动修改的麻烦。

添加脚本的流程:
  1. Xcode切换到 Build Phases 选项卡;
  2. 点击左上角"+"号来增加一项"New Run Script Phase";
  3. 添加如下脚本代码:
Shell #!/bin/sh

代码:

# ******************************************************
#
# Copyright 2015-2022 BTStudio. All rights reserved.
#
# Author        : Wangzhi
# Last modified : 2022-09-21
# Email         : wzqsyk@126.com
# Description   : 每次Build或Archive后,编译版本号自动+1
#
# 注意: 编译版本号设置为整数时,该脚本才能实现其功能
#
# ******************************************************


# 每次编译后编译版本号是否+1: 1-每次Build后+1  0-每次Archive后+1  
INCREASE_WHEN_BUILD=0

# Build或Archive的标志,默认为Build
BuildConfigurationFlag="Debug"

BuildNumber=1 # 编译版本号


if [ $INCREASE_WHEN_BUILD -eq 0 ]; then
    BuildConfigurationFlag="Release"
fi

echo "当前Xcode的Build Configuration: $CONFIGURATION"
if [ $BuildConfigurationFlag == "${CONFIGURATION}" ]; then
    # Info.plist中的编译版本号(BundleVersion)
    BuildVersionOfInfo="1" 
    # 项目配置文件(xxx.xcodeproj/project.pbxproj)中的编译版本号(CURRENT_PROJECT_VERSION)
    BuildVersionOfConfig="1"

    # 1. 读取版本号
    BuildVersionOfInfo=$(/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "${INFOPLIST_FILE}")
    BuildVersionOfConfig=${CURRENT_PROJECT_VERSION}
    # 判断读取出来的BuildVersionOfInfo变量是否为字符串: $(CURRENT_PROJECT_VERSION)
    # - 若是,则需从CURRENT_PROJECT_VERSION读取版本号;
    # - 若不是,则读取出来的BuildVersionOfInfo即是版本号,需再判断与BuildVersionOfConfig的大小,取较大值;
    if [ $BuildVersionOfInfo == '$(CURRENT_PROJECT_VERSION)' ]; then
        BuildNumber=${CURRENT_PROJECT_VERSION}
    else
        # 取较大值
        if [ $BuildVersionOfInfo -ge $BuildVersionOfConfig ]; then
            BuildNumber=$BuildVersionOfInfo
        else
            BuildNumber=$BuildVersionOfConfig
        fi
    fi
    
    # 2. 版本号+1
    BuildNumber=$(($BuildNumber + 1))
    
    # 3. 新的版本号写入Info.plist
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BuildNumber" "${INFOPLIST_FILE}"
    
    echo "Build version need increase"
else
    echo "Build version don't need increase"
fi
  1. 效果如下:


    添加Build自动+1的脚本代码
  2. 之后每次进行打包时,Build会自动+1,避免了Build重复的问题。

提示:

  1. 可以双击 Build Auto Increase 进行名称的修改,增加一项 New Run Script Phase 后,Xcode默认名称为:Run Script
  2. 每次编译或打包后,可以查看脚本的执行结果,如下图所示:


    脚本的执行结果

小知识

PlistBuddy是Mac自带的专门解析plist的小工具,由于PlistBuddy并不在Mac默认的Path里,所以我们得通过绝对路径(/usr/libexec/PlistBuddy)来引用这个工具。

Shell基本语法:

  1. 定义变量时,变量名不加美元符号$ (PHP语言中变量需要)。如:
    your_name="runoob.com" (注意:变量名和等号之间不能有空格)
  2. 使用一个定义过的变量,只要在变量名前面加美元符号即可。如:
    echo $your_name
  3. 读取plist中某个字段的值,并赋给变量var:
    var=$(/usr/libexec/PlistBuddy -c "Print :字段名" plist文件路径)
  4. 修改plist中某个字段相应的值:
    /usr/libexec/PlistBuddy -c "Set :字段名 值" plist文件路径
  5. Shell的echo指令与PHP的echo指令类似,都是用于字符串的输出。
    命令格式:echo string
  6. Shell脚本没有{}括号,所以用fi表示if语句块的结束。
  7. #! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell。

有关iOS开发之Build版本号自增的更多相关文章

  1. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  2. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  3. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  4. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  5. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  6. ruby-on-rails - 错误 : Error installing pg: ERROR: Failed to build gem native extension - 2

    我克隆了一个rails仓库,我现在正尝试捆绑安装背景:OSXElCapitanruby2.2.3p173(2015-08-18修订版51636)[x86_64-darwin15]rails-v在您的Gemfile中列出的或native可用的任何gem源中找不到gem'pg(>=0)ruby​​'。运行bundleinstall以安装缺少的gem。bundleinstallFetchinggemmetadatafromhttps://rubygems.org/............Fetchingversionmetadatafromhttps://rubygems.org/...Fe

  7. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  8. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  9. ruby-on-rails - 如果我将 ruby​​ 版本 2.5.1 与 rails 版本 2.3.18 一起使用会怎样? - 2

    如果我使用ruby​​版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby​​1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更

  10. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

随机推荐