一、背景

  1. 现在不方便在主工程里运用源码联调
  2. 现在每一个基础库依靠外部的东西静态库十分困难或许是引进进来工程人物越来越不明晰,架构规划未来会越来越不好区分

二、入门要求

  1. cocoapods组成以及中心模块工作原理
  2. pod update 和 pod install 原理
  3. 简略了解ruby语法

三、期望方针

  1. Pod update时对已经push到spec库房的pod库能够通过tag或许全局ruby环境变量对区分是加载framework或许是源码;

四、职业计划汇总

方法1:

pod repo push 时,咱们能够发布两套podspec,eg: ABC.podspec 和 ABC_Binary.podspec 成为双podspec计划;

方法2:

CocoaPods供给了针对podspec的预履行脚本,prepare_command(戳我进官网)指令,该指令能够指定相应的脚本在pod install时去履行,那么咱们就能够将编译打包的脚本放入spec文件中,从而完成推迟打包

A bash script that will be executed after the Pod is downloaded. This command can be used to create, delete and modify any file downloaded and will be ran before any paths for other file attributes of the specification are collected.

此指令可用于创建,删去和修改下载的任何文件,并且在收集标准的其他文件特点的任何途径之前将ran, 好像发现了新大陆。

留意:如果是:path方法引入这个脚本不起作用 (官方有详细的描绘,我的了解是本地这样操作是冗余的)

扩展prepare_command 运用方法

格局:

 s.prepare_command = '脚本类型 脚本途径'
 s.prepare_command = <<-CMD   ... 指令  CMD

例子如下:

s.prepare_command = 'ruby build_files.rb'
s.prepare_command = '/bin/bash build_files.sh'
s.prepare_command = '/bin/bash build_files.sh'
s.prepare_command = <<-CMD
                        linux unix各种履行指令,eg:操作文件
CMD

这种方法运行之前需求履行以下指令删去pod库在本地缓存以及工程缓存,我这儿比较强暴点,详细如下:

pod cache clean --all
rm -rf ~/Library/Caches/CocoaPods

方法3:

通过cocoapods插件 cocoapods-binary 完成

第一步:sudo gem install cocoapods-binary

第二步:例如如下podfile的写法:

plugin 'cocoapods-binary'
use_frameworks!
# all_binary!
target "HP" do
    pod "ExpectoPatronum", :binary => true
end

计划4:

现在还有一种方法,仅限于运用xcode打包时保留的DWARF调试信息暂时复原出源码,详细能够参阅iOS组件二进制源码调试热切换计划,但是跟咱们这次方针不符合,感兴趣也能够了解;

调研计划比照

计划 优点 缺点
双podspec计划 加速pod 导入的速度 需求占用部分服务资源
prepare_command 推迟打包 发布简略,只需依据ruby环境变量确认是否需求调用prepare_command的frmaework打包脚本即可 由于这种方法是拉取代码,推迟决议是否打framework方法导入,比较第一种时间会长
cocoapods-binary 外部运用方做的时候过多

五、demo实践

完成步骤:

计划:demo运用的prepare_command 推迟打包方法打包,这儿选用的.a静态库的方法打包

源码库房 dev分支

Spec库房

第一步

了解ABC.podspec文件,怎么别离区分源码和二进制库,以及二进化的话在什么机遇和怎么打包静态库

#
# Be sure to run `pod lib lint ABC.podspec' to ensure this is a
# valid spec before submitting.
#
# Any lines starting with a # are optional, but their use is encouraged
# To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html
#
Pod::Spec.new do |s|
 s.name       = 'ABC'
 s.version     = '0.1.0'
 s.summary     = 'A short description of ABC.'
# This description is used to generate tags and improve search results.
#  * Think: What does it do? Why did you write it? What is the focus?
#  * Try to keep it short, snappy and to the point.
#  * Write the description between the DESC delimiters below.
#  * Finally, don't worry about the indent, CocoaPods strips it!
 s.description   = <<-DESC
    TODO: Add long description of the pod here.
DESC
 s.homepage     = 'https://github.com/葛高召/ABC'
 # s.screenshots   = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
 s.license     = { :type => 'MIT', :file => 'LICENSE' }
 s.author      = { 'xxx' => 'xxx@gmailc.om' }
 s.source      = { :git => 'git@github.com:GE-GAO-ZHAO/ComommentSpecBinarySDK.git', :tag => s.version.to_s }
 # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'  
 s.ios.deployment_target = '9.0'
 if s.version.to_s.include?'Binary' or ENV['IS_BINARY']
  puts '-------------------------------------------------------------------'
  puts 'Notice:ABC is binary now'
  puts '-------------------------------------------------------------------'
  s.prepare_command = '/bin/bash build_lib.sh'
  s.ios.vendored_frameworks= 'PodProducts/*.framework'
 else
  puts '-------------------------------------------------------------------'
  puts 'Notice:ABC is source code now'
  puts '-------------------------------------------------------------------'
  s.static_framework = false
  s.source_files = 'ABC/Classes/**/*'
 end
end

第二步

详细静态库打包脚本如下(仅做参阅)

#!/bin/sh
# Script.sh
# ABC
#
# Created by 葛高召 on 2022/1/6.
# Copyright  2022 葛高召. All rights reserved.
echo ///            ///
echo /// 开端推迟编译二进制库 ///
echo ///            ///
read_dir() {
  for file in `ls $1` do
        if [ -d $1"/"$file ]
  then
        read_dir $1"/"$file
  else
        echo $1"/"$file
  fi
  done
}
echo ======目录信息=========
CURRENT_DIR1=$(cd `dirname $0`; pwd)
read_dir $CURRENT_DIR1
echo ======目录信息=========
#workspace名、scheme名字
PROJECT_NAME='ABC'
BINARY_NAME="${PROJECT_NAME}"
#进入工程根目录
cd Example
#framework途径
INSTALL_DIR=../PodProducts
if [ -d ${INSTALL_DIR} ];then
  echo "移除framework缓存 $INSTALL_DIR"
  rm -rf ${INSTALL_DIR}
else
  echo "创建framework途径 $INSTALL_DIR"
  mkdir -p $INSTALL_DIR
fi
#编译场所
BUILD_PATH="${CURRENT_DIR1}/build"
RE_OS="Release-iphoneos"
RE_SIMULATOR="Release-iphonesimulator"
DEVICE_DIR_FOLDER="${BUILD_PATH}/${RE_OS}"
SIMULATOR_DIR_FOLDER="${BUILD_PATH}/${RE_SIMULATOR}"
DEVICE_DIR="${DEVICE_DIR_FOLDER}/${BINARY_NAME}.framework"
SIMULATOR_DIR="${SIMULATOR_DIR_FOLDER}/${BINARY_NAME}.framework"
echo ======编译场所信息=========
CURRENT_DIR2=$(cd `dirname $0`; pwd)
echo "CURRENT_DIR: ${CURRENT_DIR2}"
echo "BUILD_PATH: ${BUILD_PATH}"
echo "DEVICE_DIR_FOLDER: ${DEVICE_DIR_FOLDER}"
echo "SIMULATOR_DIR_FOLDER: ${SIMULATOR_DIR_FOLDER}"
echo "DEVICE_DIR: ${DEVICE_DIR}"
echo "SIMULATOR_DIR: ${SIMULATOR_DIR}"
echo ======编译场所信息========
#别离编译模拟器和真机的Framework
xcodebuild -configuration "Release" -workspace "${PROJECT_NAME}.xcworkspace" -scheme "${BINARY_NAME}" ONLY_ACTIVE_ARCH=**NO** MACH_O_TYPE="staticlib" -sdk iphoneos CONFIGURATION_BUILD_DIR="${DEVICE_DIR_FOLDER}" clean build
xcodebuild -configuration "Release" -workspace "${PROJECT_NAME}.xcworkspace" -scheme "${BINARY_NAME}" ONLY_ACTIVE_ARCH=**NO** MACH_O_TYPE="staticlib" ARCHS='i386 x86_64' VALID_ARCHS='i386 x86_64' -sdk iphonesimulator CONFIGURATION_BUILD_DIR="${SIMULATOR_DIR_FOLDER}" clean build
echo ======目录信息=========
read_dir ../
echo ======目录信息=========
if [ -d "${DEVICE_DIR}/" ];then
  echo "exist ${DEVICE_DIR}"
else
  echo "termination | reason: not exist ${DEVICE_DIR}"
  exit
fi
if [ -d "${SIMULATOR_DIR}/" ];then
  echo "exist ${SIMULATOR_DIR}"
else
  echo "termination | reason: not exist ${SIMULATOR_DIR}"
  exit
fi
#合成fat库
INSTALL_LIB_DIR=${INSTALL_DIR}/${BINARY_NAME}.framework
if [ -d "${INSTALL_LIB_DIR}" ]
then
    rm -rf "${INSTALL_LIB_DIR}"
fi
mkdir -p "${INSTALL_LIB_DIR}"
cp -a "${DEVICE_DIR}/" "${INSTALL_LIB_DIR}/"
lipo -create "${DEVICE_DIR}/${BINARY_NAME}" "${SIMULATOR_DIR}/${BINARY_NAME}" -output "${INSTALL_LIB_DIR}/${BINARY_NAME}"
#删去编译产物
rm -rf $BUILD_PATH
echo ///            ///
echo /// 完成推迟编译二进制库 ///
echo ///            ///

第三步

整体进口脚本,在podfile同级目录放入下面的脚本直接运行即可

#!/bin/sh
# Script.sh
# ABC
#
# Created by 葛高召 on 2022/1/6.
# Copyright  2022 葛高召. All rights reserved.
#提示导入的pod库方法
read -p "请输入装置的方法? 是:1(二进制) , 否:0(源码) " binary
#清除pod缓存
pod cache clean --all
rm -rf ~/Library/Caches/CocoaPods
#移除Podfile.lock 和 Pods/ABC文件夹
work_path=$(pwd)
echo 当前目录:$work_path
PodfileLockDir=${work_path}/Podfile.lock
PodsDir=${work_path}/Pods
if [[ ! -f "$PodfileLockDir" ]]; then
   echo "PodfileLockDir文件夹不存在"
else
  rm -f $PodfileLockDir
fi
if [[ ! -d "$PodsDir" ]]; then
   echo "PodsDir文件夹不存在"
else
   rm -rf $PodsDir
fi
##装置
case $binary in
0)
    echo "装置源码库"
    pod update --verbose
;;
1)
    echo "装置二进制库"
    IS_BINARY=1 pod update --verbose
;;
*)
echo '输入错误,反常退出'
;;
esac

运行依据提示输入不同的装备,完成导入二进制库或许源码库

六、参阅文献

Podspec****

pod install vs. pod update

script_phases****

How to use CocoaPods plugins****

cocoapods-imy-bin无侵入式

cocopods源码分析

七、后语

这儿介绍iOS组件二进化常见的方法,以及运用ruby环境变量和prepare_command在pod install之前通过脚本提交打好静态库方法完成。缺陷是发布后开发者能够看到podspec文件完成,其实还是不太好,能够参阅我的另一篇文章 /post/715949… 来避免这个问题