iOS 组件二进制化方案--(二)

2018-08-10  本文已影响129人  JimmyL

之前在iOS 组件二进制化方案--(一)中说明了进行组件二进制化的背景和目标,但方案实施后发现了诸多不足之处。

方案一不足之处

  1. .a 文件存放在 git 仓库会占用仓库容量,影响代码拉取和提交速度;
  2. 每个人操作打包过程繁琐;

基于最终目的是想加快Jenkins构建、出包速度,解决从代码提交到测试装包时间冗长的问题,结合之前方案的不足,制定新的方案,实现组件二进制化过程自动化;

采用ftp存储

http_source.png
基于 cocoapods 支持通过http下载一个压缩包的形式拉取第三方库(详细介绍见:cocoapods_podspec_source),最终采用将组件的LICENSE、资源文件、需要暴露的 .h 以及 .a 文件压缩为 zip 格式,上传至 ftp 服务器存储,在 ftp 上的存储路径如下:
ftp_path.png
为统一 pod 拉取组件库后对资源文件和 .h 文件的读取,压缩包解压路径设置如下所示:
zip_path.png
初步应用可采用iOS 组件二进制化方案--(一)中说的方式生成.a文件,然后手动配置路径、压缩、上传至ftp(可采用界面化工具 FileZilla )

调整 podspec 文件

生成zip文件之后,就要在工程中拉取组件库,为保证组件库被拉取时可在源码与二进制包之间切换 ,需要对 podspec 进行调整,举例如下:

Pod::Spec.new do |s|
  s.name             = 'JLTestKit'
  s.version          = '1.2.0'
  s.summary          = '组件库'

  s.description      = <<-DESC
TODO: Add long description of the pod here.
                       DESC

  s.homepage         = 'http://https://github.com/JLTest/JLTestKit'
  # s.screenshots     = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  s.author           = { 'name' => 'email' }
  # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
  s.ios.deployment_target = '9.0'

#控制安装 Pod 的时候判断使用源码还是二进制库
$lib = ENV['use_lib']
$lib_name = ENV["#{s.name}_use_lib"]

if $lib || $lib_name
  #此处的source为 zip 文件在ftp服务器上的存储路径;
    s.source = { :http => 'http://example.zip' } 
    s.ios.vendored_libraries = "Library/*.a"
    s.source_files = 'Library/*.h'
    s.resources = 'Resource/JLTest.xcassets'
else
    #源码
    s.source = { :git => 'http://example.git', :tag => s.version.to_s }
    s.source_files = 'CMInvoicesCommon/Classes/**/*.{h,m}'
    s.resources = 'JLTest/Assets/JLTest.xcassets'
end
    s.dependency 'YYModel'
    s.requires_arc = true
end

source及source_files、resources的设置:

流程自动化

由于生成.a文件、生成zip、配置ftp存储路径、上传至ftp服务器过程繁琐,且重复操作耗费时间较多,因此很有必要将此流程实现自动化。

因为组件库较多,服务器资源有限的原因,最终采用每个人本机配置Jenkins构建环境去完成流程,Jenkins安装过程见持续集成环境搭建(二)--iOS Jenkins搭建持续集成环境,这里就直接说跟自动化生成并上传二进制文件相关的配置;

全局环境配置

访问权限配置

创建任务

万事俱备,只差一试!建个任务试一下。。。。。

#!/bin/bash

if [ -e Example/*.xcworkspace ];then
    rm -rf Example/Podfile.lock Example/Pods Example/*.xcworkspace
fi

cd Example

# 更新私有repo库
if [ -e ~/.cocoapods/repos/SASpecs ];then
    pod repo update SASpecs
else
    pod repo add PrivateRepo ssh://git@192.168.6.111:8080/test.git 
fi

pod install

cd ../

# 压缩为zip
# 此处 1 为需要暴露.h文件,因为工程采用组件化,使用中间件沟通的业务库是不需要暴露.h文件给外部的,这种情况下此处的1就不写;
salib_zip ${version} 1  

# 上传至ftp
salib_sshpass JLTestKit ${version}

总结,压缩成zip文件存储于ftp服务器可解决掉上面说的方案一中的不足 1;流程自动化则解决了操作流程繁琐的问题;

应用中遇到的问题

在工程中拉取组件库在源码和二进制之间切换时,由于两种形式的source不同,不会同时缓存在本地cocoapods cache中。受此影响,在切换时需要将工程的pods文件夹、.xcworkspace、podfile.lock及要切换的组件库在本机的cocoapods cache删掉,重新执行pod install;首次拉取新版本时不需做此操作,因为本地还没有针对新版本的缓存;


脚本

salib:iOS 组件二进制化方案--(一)

salib_zip:

#!/bin/bash
#
#------------iOS 组件二进制化:将资源文件、需要暴露的.h文件、.a文件压缩为zip--------------

if [ -e *.podspec ];then  
    
    #存在 podspec 文件
    #采用 podspec 的名字指定 workspace 与需要编译的 scheme
    project_name=$(basename *.podspec .podspec)  
else
    echo "ERROR: not find podspec file, please run shell in project root path"
    exit 1
fi

if [ -n "$1" ];then 
    version=${1%.*}
else
    echo "ERROR: Please input the version which you want to build"
    exit 1
fi

salib $1

if [ $?  -eq 0 ]; then
        
    echo
    echo "--- Setup $project_name.zip ---"

    upload_path=$project_name/$project_name
    
    if [ -e $upload_path/$version ]; then
        # 删除之前生成的
        rm -r $upload_path/$version
    fi
    
    mkdir -p $upload_path/$version

    # mkdir -p $upload_path/$version/Library
#
#   if [ -e $project_name/**/*.xcassets ] || [ -e $project_name/**/*.bundle ]; then
#       mkdir -p $upload_path/$version/Resource
#   fi
    
    # 复制LICENSE
    cp -rf LICENSE $upload_path/$version/LICENSE

    if [ $2 ];then
        # 复制.h
        cp -rf $project_name/Classes/**/*.h $upload_path/$version
    fi

    # 复制 .a 文件
    cp -rf $project_name/Library/$version/lib$project_name.a $upload_path/$version

    # 复制资源文件 Assets bundle
    if [ -e $project_name/**/*.xcassets ];then
        cp -rf $project_name/**/*.xcassets $upload_path/$version
    fi
    
    if [ -e $project_name/**/*.bundle ];then
        cp -rf $project_name/**/*.bundle $upload_path/$version
    fi
    
    if [ -e $project_name/**/*.mp4 ];then
        cp -rf $project_name/**/*.mp4 $upload_path/$version
    fi

    # 删除 Library
    rm -r $project_name/Library
    
    count=`ls $upload_path/$version|wc -l`
    if [ ${count} -gt 0 ]; then
        cd $upload_path/$version
        pwd
        echo "开始压缩"
        # 压缩生成zip文件
        zip -r $project_name.zip * */
        
        rm -rf *.a *.h *.xcassets *.bundle *.mp4 LICENSE
        
    else
        echo "The directory is null, no file to create zip"
    fi
fi

salib_sshpass:

#!/bin/bash
#
#------------iOS 组件二进制化:采用sshpass将压缩文件上传至ftp--------------

repo=$1 
version=$2

if [ $? -eq 0 ];then
        # 192.168.6.49 为ftp地址
    sshpass -p 'lQ@8VhN@6o' ssh -o StrictHostKeyChecking=no root@192.168.6.49 "mkdir -p /home/ftpios/ios/${repo}/${version%.*}"

    sshpass -p 'lQ@8VhN@6o' scp -o StrictHostKeyChecking=no ${repo}/${repo}/${version%.*}/${repo}.zip root@192.168.6.49:/home/ftpios/ios/${repo}/${version%.*}
    
    echo "============================================================"
        # 打印zip在ftp的存储路径
    echo "url:  http://192.168.6.49/ios/${repo}/${version%.*}/${repo}.zip"
fi

# 任务执行完,删除 Jenkins workspace下的相关文件
rm -rf * && rm -rf ".*"
上一篇下一篇

猜你喜欢

热点阅读