이 세상에 하나는 남기고 가자

세상에 필요한 소스코드 한줄 남기고 가자

CocoaPods Subspecs를 이용한 선택적 의존성 설정

아사마루

Xcode에서 CocoaPods를 이용해 sub module 만들기에서 모듈을 생성하는 것을 간단히 설명한 적이 있다. 모듈을 만들면서 여러 가지 기능을 하나의 모듈에 추가하다 보면 다른 프로젝트에서는 불필요한 코드들이 추가되는 상황이 발생한다. 이런 경우 Subspecs를 활용하면 선택적 의존성을 설정할 수 있다.

우선 Optional CocoaPod dependencies using Subspecs에 소개된 예시를 보자.

# Kite-Print-SDK.podspec
Pod::Spec.new do |spec|
  spec.name     = 'Kite-Print-SDK'
  spec.version  = '1.0.2'
  spec.license  =  'MIT'
  spec.homepage = 'https://github.com/OceanLabs/iOS-Print-SDK'
  spec.authors  = {'Deon Botha' => 'deon@oceanlabs.co'}
  spec.summary  = '...'
  spec.source   = {
    :git => 'https://github.com/OceanLabs/iOS-Print-SDK.git',
    :tag => '1.0.2'}
  spec.source_files =
    ['PSPrintSDK/OL*.{h,m}', 'PSPrintSDK/CardIO*.h']
  spec.resources =
    ['PSPrintSDK/KitePrintSDK.xcassets', '*.lproj']
  spec.dependency   'SDWebImage'
  spec.dependency   'SVProgressHUD'
  spec.dependency   'AFNetworking', '2.5.0'
  spec.dependency   'UICKeyChainStore', '~> 1.0.4'
  spec.requires_arc = true
  spec.platform     = :ios, '7.0'
  spec.social_media_url = 'https://twitter.com/dbotha'
  spec.default_subspec = 'Lite'

  spec.subspec 'Lite' do |lite|
  # subspec for users who don't want the third party PayPal
  # & Stripe bloat
  end

  spec.subspec 'PayPal' do |paypal|
    paypal.xcconfig =
        { 'OTHER_CFLAGS' => '$(inherited) -DKITE_OFFER_PAYPAL' }
    paypal.dependency   'PayPal-iOS-SDK', '~> 2.4.2'
  end

  spec.subspec 'ApplePay' do |apple|
    apple.xcconfig =
        { 'OTHER_CFLAGS' => '$(inherited) -DKITE_OFFER_APPLE_PAY' }
    apple.dependency      'Stripe', '2.2.0'
    apple.dependency      'Stripe/ApplePay'
  end
end

이 예시에서 자세히 살펴봐야 할 부분은 subspecdefault_subspecs 이다.

이 pod의 의존성을 부모 프로젝트에서 다음과 같이 지정 했다고 가정하자.

pod "Kite-Print-SDK", "~> 1.0"

부모 프로젝트에는 'PayPal'과 'ApplePay' 부분을 제외한 의존성이 설정되었다. 단, default_subspecs에 의해 'Lite' 모듈은 포함된다(예시에서는 추가적인 의존성이 없으므로 차이는 없지만).

'PayPal'과 'ApplePay'에 관련된 의존성 추가는 필요에 따라 아래와 같이 지정할 수 있다.

pod "Kite-Print-SDK", "~> 1.0"
pod "Kite-Print-SDK/PayPal", "~> 1.0"
pod "Kite-Print-SDK/ApplePay", "~> 1.0"

위 예시만으로 선택적 의존성을 설정하는 것에 대한 모든 부분을 설명한 것과 마찬가지다.


추가적으로 알아두어야 할 내용을 소개한다.

  • 모든 subspec은 암시적으로 이를 둘러싸는 Root Spec을 상속 한다.
  • default_subspecs는 다음과 같이 여러 개를 동시에 지정할 수 있다.
    • spec.default_subspec = ['Lite', 'PayPal']
  • default_subspecs를 지정하지 않으면 모든 subspec이 포함된다.
  • 'OTHER_CFLAGS'를 이용해서 소스 레벨에서 의존성 지정 여부를 확인 할 수 있다.
#if KITE_OFFER_PAYPAL
  print("use PayPal")
#else
  print("not use PayPal")
#endif

마지막으로 default_subspecs에는 아래와 같이 설명되어 있다.

A Pod should make available the full library by default. Users can fine tune their dependencies, and exclude unneeded subspecs, once their requirements are known. Therefore, this attribute is rarely needed. It is intended to be used to select a default if there are ‘sub-specifications’ which provide alternative incompatible implementations, or to exclude modules rarely needed (especially if they trigger dependencies on other libraries).

요약하자면 Pod는 기본적으로 전체 라이브러리를 제공해야 하므로 특별한 경우가 아니라면 사용하지 않는 것이 좋다.

하지만 이 글에서는 소개하고 있는 선택적 의존성을 지정하기 위해서는 사용하는 것이 좋다고 생각한다.

Comment