[Swift]制作framework并发布到cocoapods私有库

此文仅做备忘,不做任何学习交流,大家可随意参考
framework中三方库依赖以及framework发布统一使用pod方式

一、制作framework

1、创建APP工程,用来开发framework和测试用的
以UIImageView的扩展framework制作为例,并在framework中依赖三方库SDWebImage


2、创建framework的Target,我命名为MyUIImageViewSDK



3、使用pod管理依赖的三方库(如SDWebImage)

使用终端cd到项目根目录,执行命令pod init,打开生成的Podfile文件,在MyUIImageViewSDK下添加pod 'SDWebImage'

终端执行pod install,然后打开MyUIImageViewLib.xcworkspace文件

4、配置framework

设置支持版本


取消只编译当前架构


移除重复的架构
真机和模拟器编译后,framework中arm64架构重复,会导致合并失败,所以移除模拟器中的arm64架构

设置编译选项优化,给framework包瘦身


设置类型为静态库


设置release



5、开发代码

如果让类和方法让外界可调用,需要用权限修饰,我用的是public
swift 不像OC可以暴露接口,在swift中 要想给别的工程调用接口,记得在类,方法或属性前加public。
swift权限控制符:
open 权限最大,可以被外界模块访问,继承重写
public 可以被外界工程访问
internal 默认文件创建时的权限,可以在本工程的访问
private 只可以在创建的文件内访问


6、添加生成最终需要发布的framework的脚本
说明:关于framework编译和合并的脚本,我还是比较喜欢以下的方式,简单粗暴。
像新建一个shell脚本的target我也试过,framework中没有依赖三方还行,像我这种依赖三方库的,shell运行不通过,三方库会报错
carthage编译framework我也试过,虽然可以解决三方库报错的问题,但是我觉得麻烦


# 真机和模拟器framework合并脚本
# 选中framework,分别在真机和模拟器编译成功即可
if [ "${ACTION}" = "build" ]
then
# 定义framework名称(替换为自己定义的名字即可)
SDK_NAME=MyUIImageViewSDK
# 输出路径
INSTALL_DIR=${SRCROOT}/Products/${SDK_NAME}.framework
# 真机路径
DEVICE_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphoneos/${SDK_NAME}.framework
# 模拟器路径
SIMULATOR_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphonesimulator/${SDK_NAME}.framework
# 如果输出路径已存在,则删除
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
# 创建输出路径
mkdir -p "${INSTALL_DIR}"
# 如果真机framework和模拟器framework都存在
if [ -d "${DEVICE_DIR}" ] && [ -d "${SIMULATOR_DIR}" ]
then
# 拷贝真机framework到输出路径
cp -r "${DEVICE_DIR}/" "${INSTALL_DIR}/"
# 拷贝模拟器framework中的modules到输出路径
cp -r "${SIMULATOR_DIR}/Modules/${SDK_NAME}.swiftmodule/" "${INSTALL_DIR}/Modules/${SDK_NAME}.swiftmodule"
# 合并真机framework和模拟器framework
lipo -create "${DEVICE_DIR}/${SDK_NAME}" "${SIMULATOR_DIR}/${SDK_NAME}" -output "${INSTALL_DIR}/${SDK_NAME}"
fi
fi

7、生成framework
选中MyUIImageViewSDK,分别在真机和模拟器编译一次即可,然后在项目的根目录中,Products文件夹里会有最终的framework



二、发布framework

cocoapods发布私有库的大致流程为:
1、GitHub上创建一个私有索引库,这个索引库存放的都是私有库的路径
2、GitHub上创建一个私有库,存放的是整个私有库的所有源码
3、把私有库的.podspec文件push到私有索引库中
4、把私有索引库更新到本地repo中

创建私有索引库,并添加到本地repo中


终端执行pod repo add MySpec [email protected]:WitXiong/MySpec.git
然后执行pod repo即可查看有没有添加成功

创建私有组件库


本地组件源码根目录下,创建.podspec文件
终端执行pod spec create MyUIImageViewSDK
生成文件后拖入Xcode工程中,取消copy勾选
podspec文件修改完后,把本地私有库代码和远端私有库关联,并把代码都push上去
这里需要注意的是,每次push后都需要打tag,且tag和.podspec文件中的版本号要一致

#
#  Be sure to run `pod spec lint MyUIImageViewSDK.podspec' to ensure this is a
#  valid spec and to remove all comments including this before submitting the spec.
#
#  To learn more about Podspec attributes see https://guides.cocoapods.org/syntax/podspec.html
#  To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
#

Pod::Spec.new do |spec|

  # ―――  Spec Metadata  ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  These will help people to find your library, and whilst it
  #  can feel like a chore to fill in it's definitely to your advantage. The
  #  summary should be tweet-length, and the description more in depth.
  #

  spec.name         = "MyUIImageViewSDK"
  spec.version      = "0.0.1"
  spec.summary      = "A short description of MyUIImageViewSDK."

  # 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!
  spec.description  = <<-DESC
  这是描述区,这里的文字一定要比 spec.summary 中的内容长,
  否则spec远端验证可能会不通过
                   DESC

  # 这里是主页地址,可以写github私有库的主页地址
  spec.homepage     = "http://EXAMPLE/MyUIImageViewSDK"
  # spec.screenshots  = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"


  # ―――  Spec License  ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Licensing your code is important. See https://choosealicense.com for more info.
  #  CocoaPods will detect a license file if there is a named LICENSE*
  #  Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
  #

  spec.license      = { :type => "MIT", :file => "FILE_LICENSE" }


  # ――― Author Metadata  ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Specify the authors of the library, with email addresses. Email addresses
  #  of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
  #  accepts just a name if you'd rather not provide an email address.
  #
  #  Specify a social_media_url where others can refer to, for example a twitter
  #  profile URL.
  #

  spec.author             = { "wit" => "[email protected]" }
  # Or just: spec.author    = "kaigao"
  # spec.authors            = { "kaigao" => "[email protected]" }
  # spec.social_media_url   = "https://twitter.com/kaigao"

  # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  If this Pod runs only on iOS or OS X, then specify the platform and
  #  the deployment target. You can optionally include the target after the platform.
  #

  spec.platform     = :iOS
  spec.platform     = :ios, "10.0"
  spec.swift_version = "5.0"

  #  When using multiple platforms
  # spec.ios.deployment_target = "5.0"
  # spec.osx.deployment_target = "10.7"
  # spec.watchos.deployment_target = "2.0"
  # spec.tvos.deployment_target = "9.0"


  # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Specify the location from where the source should be retrieved.
  #  Supports git, hg, bzr, svn and HTTP.
  #

  # 这是私有库的路径,填写私有库的git clone 的链接就行
  spec.source       = { :git => "[email protected]:WitXiong/MyUIImageViewSDK.git", :tag => "#{spec.version}" }


  # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  CocoaPods is smart about how it includes source code. For source files
  #  giving a folder will include any swift, h, m, mm, c & cpp files.
  #  For header files it will include any header in the folder.
  #  Not including the public_header_files will make all headers public.
  #

  # 如果是想暴露源码,打开这行
  # spec.source_files  = "Classes", "Classes/**/*.{h,m}"
  # spec.exclude_files = "Classes/Exclude"
  # 此处暴露的是framework
  spec.vendored_frameworks = "Products/MyUIImageViewSDK.framework"

  # spec.public_header_files = "Classes/**/*.h"


  # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  A list of resources included with the Pod. These are copied into the
  #  target bundle with a build phase script. Anything else will be cleaned.
  #  You can preserve files from being cleaned, please don't preserve
  #  non-essential files like tests, examples and documentation.
  #

  # spec.resource  = "icon.png"
  # spec.resources = "Resources/*.png"

  # spec.preserve_paths = "FilesToSave", "MoreFilesToSave"


  # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Link your library with frameworks, or libraries. Libraries do not include
  #  the lib prefix of their name.
  #

  # spec.framework  = "SomeFramework"
  # spec.frameworks = "SomeFramework", "AnotherFramework"

  # spec.library   = "iconv"
  # spec.libraries = "iconv", "xml2"


  # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  If your library depends on compiler flags you can set them in the xcconfig hash
  #  where they will only apply to your library. If you depend on other Podspecs
  #  you can include multiple dependencies to ensure it works.

  # spec.requires_arc = true

  # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
  # 这是声明framework依赖的三方库
  spec.dependency "SDWebImage", "~> 5.0"

end

把.podspec文件push到远程Spec私有索引库中
终端执行pod repo push MySpec MyUIImageViewSDK.podspec --allow-warnings --skip-import-validation

使用(和正常的pod库使用方式一样)
唯一的区别是,因为是私有库,需要在podfile文件中额外添加源地址
一个是私有的索引库地址source '[email protected]:WitXiong/MySpec.git'
一个是cocoapods的cdn地址source 'https://cdn.cocoapods.org/'

结束

你可能感兴趣的:([Swift]制作framework并发布到cocoapods私有库)