工程效率配置&Shell&打包等程序员

iOS - Run Script之修改App icon

2020-05-07  本文已影响0人  Linghit_iOS

Run Script 之 修改AppIcon

Created by Ningyuan 2020/04/26

需求背景

方便地从图标上区分应用的版本以及环境等信息。

准备

首先,需要在Mac安装Homebrew,如果还没安装,请访问https://brew.sh了解并自行安装。

本次用到的主要工具为ImageMagick,它可以提供对图像的多种处理,有兴趣的可以自行学习。链接如下:

ImageMagick官方网址:https://www.imagemagick.org/script/command-line-options.php

ImageMagick中文站:http://www.imagemagick.com.cn

打开终端并输入以下命令,安装ImageMagick、GhostScripts:

brew install imagemagick

brew install ghostscript

简单尝试

  1. 下面使用convert命令,为”icon-60@2x.png“这张图片附加字体、图片,可自行找图片测试。
convert icon-60@2x.png -fill black -font Times-Bold -pointsize 18 -gravity south -annotate 0 "Hello World" test.png
```shell
# (运行项目后)应用所在路径,待会要用来查看生成的图标
echo "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"

# 项目所在文件夹路径
echo "${SRCROOT}"
```
  1. 然后,Xcode -> Targets -> Build Phases -> 选“+” -> New Run Script phase -> 在新建的Run Script中填上下面的测试脚本代码,修改BASE_IMAGE_PATHnew.png为自己的资源即可:

    BASE_IMAGE_PATH:要转换的图片路径,- name 后的AppIcon60x60@2x.png修改为项目中的其中一张图标名称

    new.png:beta图标的图片名称,同样需要修改为自己的图标

    # Type a script or drag a script file from your workspace to insert its path.
    
    echo "hello sh"
    echo "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
    
    IFS=$'\n'
    
    PATH=${PATH}:/usr/local/bin
    
    IFS=$'\n'
    
    function generateIcon () {
    
    BASE_IMAGE_NAME=$1
    
    #获取本地的应用图标,然后分别将该路径保存到TARGET_PATH 和 BASE_IMAGE_PATH 变量中
    TARGET_PATH="${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/${BASE_IMAGE_NAME}"
    
    BASE_IMAGE_PATH=$(find ${SRCROOT} -name "AppIcon60x60@2x.png")
    
    WIDTH=$(identify -format %w ${BASE_IMAGE_PATH})
    
    FONT_SIZE=$(echo "$WIDTH * .15" | bc -l)
    
    #版本号
    versionNumber=$MARKETING_VERSION
    #构建号
    buildNumber=$CURRENT_PROJECT_VERSION
    
    #将new.png的图标的尺寸改为合适的大小
    convert new.png -resize $WIDTHx$WIDTH resizedNew.png
    
    #首先,它在原始的应用图标上添加"Hello World"文本。
    #然后该脚本执行合成的功能--将刚刚新生成的resizedNew.png放置在其上面。然后将合成的图片保存为应用的图标。
    convert ${BASE_IMAGE_PATH} -fill black -font Times-Bold -pointsize ${FONT_SIZE} -gravity south -annotate 0 "$buildNumber" - | composite resizedNew.png - ${TARGET_PATH}
    
    }
    
    generateIcon "AppIcon60x60@2x.png"
    generateIcon "AppIcon60x60@3x.png"
    
    generateIcon "AppIcon76x76~ipad.png"
    generateIcon "AppIcon76x76@2x~ipad.png"
    
    generateIcon "AppIcon83.5x83.5@2x~ipad.png"
    
  2. Command + B编译,顺利的话会生成相应的图标,进入下面显示的路径,则可看到刚刚生成的图片:AppIcon60x60@2x.png、AppIcon60x60@3x.png、AppIcon76x76ipad.png、AppIcon76x76@2xipad.png、AppIcon83.5x83.5@2x~ipad.png

    echo "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}
    

优化

  1. 实际使用中,将上面的测试脚本修改,封装为一个replaceAppIcon.sh或自己命名的一个.sh文件
  2. 经测试,上述测试脚本只能在iOS10以及之前的版本生效,iOS11以后即使能成功生成图片,但实际运行项目时还是无法替换应用icon,需要将生成的图片存放到Assets.xcassets
  3. 除了Release环境,根据当前scheme中选择的构建环境,自动生成对应.xcassets文件并存放到里面

下面是优化后的代码,复制到新建的.sh文件中,icons_pathicons_desc_path需要根据自己的项目修改成对应路径

#!/bin/sh
# 检查是否已安装所需工具
convertPath=`which convert`
echo ${convertPath}
if [[ ! -f ${convertPath} || -z ${convertPath} ]]; then
echo "监测到未安装ImageMagick、GhostScript,请在终端使用以下命令安装:
brew install imagemagick
brew install ghostscript"
exit -1;
fi

# version    app-版本号
# build_num  app-构建版本号
version=`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}"`
build_num=`/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}"`

caption="${version}\n($build_num)"
echo $caption

# 处理icon
function processIcon() {

    base_file=$1 # icon文件
    temp_path=$2 # 生成文件的临时存放路径
    dest_path=$3 # 目标路径
    # 检查文件、路径是否存在,不存在则退出
    if [[ ! -e $base_file ]]; then
    echo "error: file does not exist: ${base_file}"
    exit -1;
    fi
    if [[ -z $temp_path ]]; then
    echo "error: temp_path does not exist: ${temp_path}"
    exit -1;
    fi
    if [[ -z $dest_path ]]; then
    echo "error: dest_path does not exist: ${dest_path}"
    exit -1;
    fi

    file_name=$(basename "$base_file")
    final_file_path="${dest_path}/${file_name}"
    base_tmp_normalizedFileName="${file_name%.*}-normalized.${file_name##*.}"
    base_tmp_normalizedFilePath="${temp_path}/${base_tmp_normalizedFileName}"
    
    # Normalize
    echo "Reverting optimized PNG to normal"
    echo "xcrun -sdk iphoneos pngcrush -revert-iphone-optimizations -q '${base_file}' '${base_tmp_normalizedFilePath}'"
    xcrun -sdk iphoneos pngcrush -revert-iphone-optimizations -q "${base_file}" "${base_tmp_normalizedFilePath}"
    width=`identify -format %w "${base_tmp_normalizedFilePath}"`
    height=`identify -format %h "${base_tmp_normalizedFilePath}"`
    band_height=$((($height * 40) / 100))
    band_position=$(($height - $band_height))
    text_position=$(($band_position - 4))
    point_size=$(((13 * $width) / 100))
    echo "Image dimensions ($width x $height) - band height $band_height @ $band_position - point size $point_size"
    
    # 添加你自己需定制的beta小标签 如new.png
    baseBetaImg="new.png"
    if [[ $baseBetaImg == "new.png" ]]; then
    echo "不添加小标签。"
    else
        convert ${baseBetaImg} -resize ${width}x${height} /tmp/resizedBetaImg.png
    fi

    # 蒙版、版本号、构建号
    convert "${base_tmp_normalizedFilePath}" -blur 10x8 /tmp/blurred.png
    convert /tmp/blurred.png -gamma 0 -fill white -draw "rectangle 0,$band_position,$width,$height" /tmp/mask.png
    convert -size ${width}x${band_height} xc:none -fill 'rgba(0,0,0,0.2)' -draw "rectangle 0,0,$width,$band_height" /tmp/labels-base.png
    convert -background none -size ${width}x${band_height} -pointsize $point_size -fill white -gravity center -gravity South caption:"$caption" /tmp/labels.png
    
    if [[ $baseBetaImg == "" ]]; then
        convert "${base_tmp_normalizedFilePath}" /tmp/blurred.png /tmp/mask.png -composite /tmp/temp.png
    else
        convert "${base_tmp_normalizedFilePath}" /tmp/blurred.png /tmp/mask.png -composite /tmp/resizedBetaImg.png -composite /tmp/temp.png
        rm /tmp/resizedBetaImg.png
    fi
    rm /tmp/blurred.png
    rm /tmp/mask.png
    
    # 合成最终icon图片
    filename=New"${base_file}"
    convert /tmp/temp.png /tmp/labels-base.png -geometry +0+$band_position -composite /tmp/labels.png -geometry +0+$text_position -geometry +${w}-${h} -composite -alpha remove "${final_file_path}"
    
    # 最后清理临时生成的图片文件
    rm /tmp/temp.png
    rm /tmp/labels-base.png
    rm /tmp/labels.png
    rm "${base_tmp_normalizedFilePath}"
    echo "Overlayed ${final_file_path}"
}

# 获取当前配置环境
config_envir=$CONFIGURATION
if [[$config_envir == "Release"]]; then
echo "Release环境不生成AppIcon"
exit -1;
else
    # 非Release环境才生成新AppIcon
    # Process all app icons and create the corresponding internal icons
    # 本项目源icon路径
    # 组成:@{PROJECT_DIR}/你的项目路径/.xcassets文件(如Assets.xcassets)/AppIcon.appiconset
    icons_path="${PROJECT_DIR}/TingZhiPsychology/Assets.xcassets/AppIcon.appiconset"

    # 生成icon图集存放路径
    icons_dest_path="${PROJECT_DIR}/TingZhiPsychology/Assets.xcassets/AppIcon-${config_envir}.appiconset"

    # 图片临时存放路径
    tmp_path="${TEMP_DIR}/IconVersioning"
    echo "icons_path: ${icons_path}"
    echo "icons_dest_path: ${icons_dest_path}"
    mkdir -p "${tmp_path}"
    if [[ $icons_dest_path == "\\" ]]; then
    echo "error: destination file path can't be the root directory"
    exit -1;
    fi
    rm -rf "${icons_dest_path}"
    cp -rf "${icons_path}" "${icons_dest_path}"

    find "${icons_path}" -type f -name "*.png" -print0 |
    while IFS= read -r -d '' file; do
    echo "$file"
    processIcon "${file}" "${tmp_path}" "${icons_dest_path}"
    done
fi

使用

  1. 新建.sh文件,复制(并修改上述代码AppIcon存放路径)到项目中
  2. 将自己使用的beta图标移动到与.xcodeproj文件同级路径中,同时需要将图标的文件名.后缀填入代码中的baseBetaImg,没有则忽略此步骤
  3. Xcode -> Targets -> Build Phases -> 选“+” -> New Run Script phase -> 在新建的Run Script中填上.sh文件相应的路径,如下图所示:
5ea594264fe6b.png
  1. 先编译一次command + B,然后在Build Setting中搜索AppIcon,填入对应环境生成的AppIcon,如下图所示:
5ea59434adc6f.png
  1. 最后,若已删除新生成的AppIcon,或不需要使用,则需要步骤3中,将不同环境下的AppIcon还原

参考文章

上一篇 下一篇

猜你喜欢

热点阅读