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

之前在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的设置:

  • 拉取二进制时设置为组件库对应的zip文件在ftp服务器的存储路径;
  • 拉取源码时则为git仓库地址;
  • 资源文件及.h、.m文件的暴露要根据在拉取的库中的实际路径配置;
  • 拉取二进制只需要暴露外需要引用的.h,即在生成zip文件时只需将需要暴露的.a与其他需要压缩的文件一起生成zip文件;

流程自动化

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

  • 生成.a文件:脚本在iOS 组件二进制化方案--(一)已贴出来;
  • 生成zip文件:脚本名称salib_zip(贴在文章最后),包含配置指定路径,以便修改podspec文件;将资源文件、LICENSE、需要暴露的.h文件、.a文件移至指定路径下;生成zip文件;
  • 将zip上传至ftp:脚本名称salib_sshpass,采用sshpass完成文件上传ftp服务器;关于sshpass,找了篇文章贴在这儿,sshpass专题---免交互式ssh&MAC下使用SSHPASS,便不再赘述;

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

全局环境配置

  • 将完成 .a文件生成(salib)、zip文件生成(salib_zip)、将zip上传至ftp(salib_sshpass) 这三个过程的脚本放在本地全局环境路径 /usr/local/bin 下;
  • 配置Jenkins访问本机全局命令
    Jenkins首页,系统管理--->系统设置:
    系统设置.png

    全局属性,勾选环境变量,点击新增,键为PATH,值为本机命令行执行 echo $PATH 命令后所打印的内容:
    global_path.png

访问权限配置

  • 为了让Jenkins用户有权限访问你的私有git库,需要为Jenkins用户配置ssh key,并将公钥配置给git仓库,为方便可以直接将常用用户下的 /Users/your_user_name/.ssh 路径下的直接复制到Jenkins用户下的对应路径下;
  • 为Jenkins添加公钥:用户--->设置--->SSH Public Keys


    SSH_Public_Keys.png
  • 新建任务时需要创建凭据用户(后面会讲到),类型选择 SSH Username with private key,将私钥添加至 private key
    SSH_Private_Keys.png

创建任务

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

  • 新建任务


    new_task.png
  • 配置任务版本


    task_version.png
  • 配置任务对应git库
    填写git地址及要构建的分支;Credentials即选择凭据,无可选项可点击右侧 add 按钮添加凭据;
    task_git.png
  • 添加shell执行
    构建--->增加构建步骤--->执行shell


    run_shell.png
#!/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 ".*"
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,087评论 18 139
  • iOS CocoaPods组件平滑二进制化方案及详细教程 感谢"fly2never_宝贝别哭"。可以使用cocoa...
    曹俊_413f阅读 12,384评论 6 82
  • 点击上方关注“花镇情感”,做个懂爱的姑娘 每一个单身中的女人,潜意识都是想找一个优秀男人。什么样的男人能够称得上优...
    花镇阅读 1,533评论 0 1
  • 感情注定越深爱就受伤越深,没有为什么,只有经历着的人能懂,顺其自然吧,就算遍体鳞伤也是要走过去的,若走不过也只能归...
    不知何为一笑倾城阅读 348评论 1 1
  • 剖开我的心,捧给你看,如果不满意,我再放回去,然后缝起来
    走_过阅读 56评论 0 0