美文网首页
iOS 组件二进制化方案--(二)

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

作者: JimmyL | 来源:发表于2018-08-10 14:49 被阅读129次

    之前在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 ".*"
    

    相关文章

      网友评论

          本文标题:iOS 组件二进制化方案--(二)

          本文链接:https://www.haomeiwen.com/subject/cotymftx.html