iOS 多个pod库快速合并和组件化共存

3,451 阅读2分钟

应用场景

  • 需要将多个pod库合并到一个pod
  • 被合并的pod 依旧可以在自己的仓库维护

方案

我们将一个MergePodsSDK当成一个全新的组件来看待,接下来我们要把需要引用的代码放到对应的pod的代码拉取到src文件下。然后每个组件当成MergePodsSDK子组件。

文件结构

具体实现

现有组件配置抽离

在组件里面创建一个以组件名称为文件名的LdsHttp.rb文件

LdsHttp.rb内容如下:

module LdsHttp
    def LdsHttp.localDependency(s,superDependency)
        if superDependency.nil?
            s.dependency 'LdsLogger'
            # s.dependency 'LdsCore'
        else 
            s.dependency "#{superDependency}/LdsLogger"
            # s.dependency "#{superDependency}/LdsCore"
        end
    end
    def LdsHttp.netDependency(s)
        s.dependency 'AFNetworking'
    end
    def LdsHttp.config(spec,sourcePath,superDependency)
        spec.ios.deployment_target = '9.0'
        spec.source_files = "#{sourcePath}Classes/**/*"
        # spec.public_header_files = "#{sourcePath}Classes/*.h"
        puts "#{sourcePath}Classes/**/*-----"
        self.localDependency(spec,superDependency)
        self.netDependency(spec)
    end
end

看代码是不是有点眼熟?其实就是把podspec文件里面的私有部分内容抽了粗来。看看podspec原来的样子:

Pod::Spec.new do |s|
  s.name             = 'LdsHttp'
  s.version          = '1.1.2'
  s.summary          = 'A short description of LdsHttp.'
  s.description      = <<-DESC
TODO: Add long description of the pod here.
                       DESC
  s.homepage         = 'https://github.com/asomeLiao'
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  s.author           = { 'asml' => 'asomeliao@foxmail.com' }
  s.source           = { :git => 'https://github.com/asomeLiao', :tag => s.version.to_s }

  s.ios.deployment_target = '9.0'
  s.source_files = "#{sourcePath}Classes/**/*"
  s.dependency 'AFNetworking'
end

在看看我们抽离出来的样子:

require_relative './LdsHttp.rb'
Pod::Spec.new do |s|
  s.name             = 'LdsHttp'
  s.version          = '1.1.2'
  s.summary          = 'A short description of LdsHttp.'
  s.description      = <<-DESC
TODO: Add long description of the pod here.
                       DESC
  s.homepage         = 'https://github.com/asomeLiao'
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  s.author           = { 'asml' => 'asomeliao@foxmail.com' }
  s.source           = { :git => 'https://github.com/asomeLiao', :tag => s.version.to_s }
  
  LdsHttp.config(s,"",nil)
end

为什么要抽离?

抽离后podspec看起来更加简洁,抽离出来的rb文件关键是可以在其他地方调用,外面只要认准LdsHttp.rb暴露的接口,不需要管其内部的配置。

多组件合并

我们在建一个MergePodsSDK.podspec文件来引用其他原有组件:

relativeSrcPath='.'
modules=[
    # "LdsCore",
    "LdsDebug",
    "LdsHttp",
    "LdsLogger", 
]

modules.each do |name|
    require_relative "#{relativeSrcPath}/#{name}/#{name}.rb"
end

module SDK
    def SDK.configForModuleName(name,spec)
        obj = Object::const_get("#{name}")
        spec.subspec "#{name}" do |ss|
            obj.config(ss,"#{name}/",spec.name)
        end
    end
end

Pod::Spec.new do |s|
    s.name='MergePodsSDK'
    s.version          = '0.0.1'
    s.summary          = 'A short description of MergePodsSDK.'
    s.description      = <<-DESC
  TODO: Add long description of the pod here.
                         DESC
    s.homepage         = 'https://github.com/asomeLiao'
    s.license          = { :type => 'MIT', :file => './MergePodsSDK/LICENSE' }
    s.author           = { 'asml' => 'asml' }
    s.source = { :git => 'xxx', :tag => s.version.to_s }
    s.ios.deployment_target = '9.0'
    s.watchos.deployment_target = '6.0'

    modules.each do |name|
        SDK.configForModuleName(name,s)
    end
    s.source_files = "MergePodsSDK/Classes/*.{h,m}"
end

注意事项

  • 合并后的子模块的内部可能还有自己的子模块,所以内部引用的时候最好是用#import "LdsLogger.h", 如果有用#import <LdsLogger/LdsLogger.h>的地方需要用脚本去遍历把LdsLogger/ 替换为MergePodsSDK/

  • xxx.podspec 里面的source_files路径要在自己的同级目录下或子目录下,在上级路径设置不生效。

demo