본문 바로가기
Xcode/IOS

IOS) Framework 서브모듈 배포 (feat: Submodule + Cocoapod)

by 후르륵짭짭 2023. 2. 10.
728x90
반응형

안녕하세요. 후르륵짭짭입니다.

지금까지 모듈화 하는 방법에 대해 작성했었습니다.

어떻게 Framework를 생성하고 어떤 점에서 문제가 있는지 작성했다면,

이번에는 사내에 모듈을 배포하는 총 3가지 방법에 대해서 작성하려고 합니다.

(참고로 Pod 배포는 Submodule로 Private 하게 작업하여 작성하였습니다.)

 

** 서브 모듈 작업하기 ** 

서브모듈이란 메인 프로젝트 밑에 다른 프로젝트를 넣는  방식입니다.

즉, A와 B가 서로 연결 되어 있는 겁니다. 

https://git-scm.com/book/ko/v2/Git-%EB%8F%84%EA%B5%AC-%EC%84%9C%EB%B8%8C%EB%AA%A8%EB%93%88

 

Git - 서브모듈

gitmodules 파일에 있는 URL은 조건에 맞는 사람이면 누구든지 Clone 하고 Fetch 할 수 있도록 접근할 수 있어야 한다. 예를 들어 다른 사람이 Pull을 하는 URL과 라이브러리의 작업을 Push 하는 URL이 서로

git-scm.com

서브모듈에 대한 자세한 내용은 위에 적혀 있습니다. 

서브 모듈로 작업하면 프로젝트 관리가 좀 더 쉬우며 메인 프로젝트에서 같이 작업을 하고 

코드 커밋은 다른 프로젝트에 적용이 가능해 집니다. 

 

- 모듈 추가하기 -

git submodule add -b <브랜치> <깃주소> <저장위치 == 서브모듈 이름>

저는 위와 같은 명령을 통해 서브 모듈을 추가 했습니다.

위 명령어를 통해 서브모듈을 추가하면 .gitmodules 이라는 파일이 추가 됩니다.

[submodule "<모듈위치>"]
	path = <모듈위치>
	url = <프로젝트 깃 주소>
	branch = <브랜치>

그리고 해당 파일을 누르면 위와 같이 작성이 됩니다.

(참고로 깃주소에 "./깃주소.git"으로 작성한다면 http나 ssh로 받았을 때 자동으로 자신의 아이디로 받아오게 됩니다.)

 

- 모듈 초기화 및 업데이트 - 

git submodule update --init <서브모듈 위치>

서브 모듈을 추가 했다고 마무리가 되는 것이 아닙니다.

해당 파일로 이동하면 아무런 내용물이 없을 겁니다. 

따라서 "init" 명령어를 작성해서 서브모듈 파일들을 가져와야합니다.

git submodule update --remote <서브모듈위치>

만약 프로젝트에서 추가된 커밋이 있다면 업데이트 해줘야합니다.

따라서 원격저장소에 있는 커밋들로 변경할 때 해당 명령어를 통해 업데이트 해줍니다.

(참고로 <서브모듈위치>는 특정 모듈만 받고 싶을 때 사용합니다. 해당 부분이 없다면 .gitmodules 에 있는 모든 서브모듈을 받습니다.)

 

** Framework 프로젝트 메인 프로젝트에 배포 ** 

- 프로젝트 주입 - 

가장 간단한 방법이고 인지하기도 가장 쉬운 방법입니다.

서브 모듈에 있는 저 파랑색 프로젝트(xcodeproj) 파일을 우리 메인 프로젝트의 하얀색(xcworkspace)을 실행 후 

드래그 해서 넣어주면 됩니다.

 

- Pod Spec 작성 - 

기존에 존재하는 프로젝트에서 Pod 배포를 하기 위해서는 Pod Spec 파일을 생성해줘야합니다.

pod spec create <프로젝트이름>

프로젝트가 있는 폴더로 이동 후에 위 명령어를 작성해줍니다.

그러면 .podspec 파일이 생성 될 것 입니다.

#
#  Be sure to run `pod spec lint LgIotService.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         = "<프로젝트명>"
  spec.version      = "<버전>"
  spec.summary      = "<짧은 설명>"

  # 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  = "<프로젝트의 긴 설명>"

  spec.homepage     = "http://EXAMPLE/LgIotService"
  # 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      = "MIT"
  # 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             = { <작성자> }

  # ――― 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, "13.0" <지원하는 플랫폼과 지원 버전>
  # spec.platform     = :ios, "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.
  #

  spec.source       = { :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  = ["<프로젝트이름>/**/*.{h,m,swift}"]
  spec.exclude_files = "Classes/Exclude"

  # 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.vendored_frameworks  = "<Local 프레임워킄>"
   spec.dependency '<Pod 프레임워크>'
   
  # 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 = { "FRAMEWORK_SEARCH_PATHS" => "Frameworks" }
  # spec.dependency "JSONKit", "~> 1.4"

end

위와 같이 다양하게 작성되는데, 저는 여기서 핵심적인 것만 다루겠습니다.

  spec.source       = { :git => "<깃주소>", :tag => "#{spec.version}" }

이 부분은 우리 프로젝트가 저장되어 있는 깃 주소를 작성해줘야합니다. 

spec.source_files  = ["<프로젝트명>/**/*.{h,m,swift}"]

이것은 외부인에게 코드를 보여줄 것들 입니다. h와 m 그리고 swift 파일 * 모두 보여준다고 작성했습니다.

spec.vendored_frameworks  = "Frameworks/<LocalFramework>.framework"

위 것은 만약 프로젝트가 LocalFramework 의존성을 가지고 있다면 Pod에 Framework파일 밑에

<LocalFramework>.framework 를 두겠다는 것을 의미합니다.

spec.dependency 'RxSwift'

이것은 만약 프로젝트가 Pod 라이브러리의 의존성을 가지고 있다면 위와 같이 가져올 수 있습니다.

 

- Pod 주입 - 

이제 Pod Spec을 작성했으니 Pod install이 가능해졌습니다.

메인 프로젝트의 Podfile에 가서 pod을 작성해 줍니다.

  pod '<PodSpec의 이름>', :path => '<Pod Spec이 존재하는 위치>'

이렇게 작성 후에 "Pod install"을 해줍니다!

만약에 에러가 없다면 잘 통과 할 것이고 에러가 있다면 그 에러에 맞게 수정 해주십셔.

위와 같이 path 설정을 한다면 Podfile이 Development Pods 파일에 존재하게 됩니다.

이 파일구조가 우리가 설정한 Pod Spec에 맞게 작업이 완료 되었습니다.

(참고로 Local 프레임워크를 넣고 빌드 했을 때 "Multiple commands"가 발생했다면

Main 프로젝트에서 Local 프레임워크를 제거해주세요.)

 

** 참고 사이트 **

Cocoapod 문서 

https://guides.cocoapods.org/making/development-cocoapods.html

 

CocoaPods Guides

CocoaPods is fully open-sourced, so it depends on community contributions to get better. If you're looking to start working on CocoaPods, this is the place to start.

guides.cocoapods.org

Pod Spec 샘플 (내부모듈 배포 방식 보려고)

https://github.com/CocoaPods/Specs/blob/master/Specs/8/b/3/Google/3.0.3/Google.podspec.json

 

GitHub - CocoaPods/Specs: The CocoaPods Master Repo

The CocoaPods Master Repo. Contribute to CocoaPods/Specs development by creating an account on GitHub.

github.com

https://github.com/CocoaPods/Specs/blob/master/Specs/e/e/3/OpenSSL/1.0.210/OpenSSL.podspec.json

 

GitHub - CocoaPods/Specs: The CocoaPods Master Repo

The CocoaPods Master Repo. Contribute to CocoaPods/Specs development by creating an account on GitHub.

github.com

 

Pod 배포 방법 

https://ali-akhtar.medium.com/distribute-framework-with-cocoapods-locally-and-remotely-4a39f95b3077

 

Distribute Framework With CocoaPods Locally and Remotely

In this tutorial our focus is to create a framework and then use in our application locally and remotely.

ali-akhtar.medium.com

 

서브 모듈을 사용해서 Pod 배포 방법 

https://blog.asamaru.net/2015/10/21/xcode-create-sub-module-using-cocoapods/

 

Xcode에서 CocoaPods를 이용해 sub module 만들기

이번엔 Xcode로 앱 제작시 Sub Module을 만드는 방법을 설명하고자 한다. 그전에 우선 어떤 경우에 Sub Module을 사용하려고 하는지 부터 이야기를 해야 할 듯하다. 나의 경우는 여러 프로젝트에서 공통

blog.asamaru.net

 

https://ios-development.tistory.com/1101

 

[iOS - swift] Cocoapods을 submodule로 추가해서 사용하는 방법 (:Path => '')

Cocoapods을 submodule로 추가하기 cocoapods을 private repo로 설정하여 관리하는 경우(사내 배포), 각각 인증에 사용할때 어려움이 있지만, submodule로 사용하면 인증 문제를 쉽게 해결이 가능 submodule로 추

ios-development.tistory.com

 

서브 모듈에 파일 드래그 해서 사용하는 방법 

https://www.kodeco.com/690-dependency-management-using-git-submodules

 

Dependency Management Using Git Submodules

In this Dependency Management tutorial you’ll learn how to use Git Submodules to manage both internal and external dependencies for your project.

www.kodeco.com

 

서브 모듈 사용 하기 

https://zeddios.tistory.com/718

 

git submodule 다른 브랜치 추적하도록 하기

안녕하세요 :) Zedd입니다.저번에 git submodule 써보기 + 삭제하는법글을 썼었는데, 이 submodule이 참.........나를 힘들게한다...build configuration문제를 해결못해서 좀 당황해하는 중이긴 합니다. 아무튼

zeddios.tistory.com

 

Multiple Command 오류

https://lxxyeon.tistory.com/64

 

[Xcode] Multiple commands produce Error 해결하기

Multiple commands produce Error 해결해 보자 위 그림과 같이 Multiple commands produce Error 가 발생하는 경우 해결방법을 소개합니다.😊 저의 경우 보통 외부 라이브러리를 포함한 프로젝트를 다운로드 받았

lxxyeon.tistory.com

 

서브 모듈 정리 

https://ohgyun.com/711

 

Git: 서브모듈 이해하기 (git submodule)

발생일: 2016.06.23 키워드: git submodule, 깃 서브모듈 문제: Git 에서 서브모듈을 사용하려고 한다. 해결책: 서브모듈에 대한 자세한 옵션은 Pro Git 책의 설명을 보는 게 더 나을 것 같아, 여기선 아래와

ohgyun.com

https://git-scm.com/book/ko/v2/Git-%EB%8F%84%EA%B5%AC-%EC%84%9C%EB%B8%8C%EB%AA%A8%EB%93%88

 

Git - 서브모듈

gitmodules 파일에 있는 URL은 조건에 맞는 사람이면 누구든지 Clone 하고 Fetch 할 수 있도록 접근할 수 있어야 한다. 예를 들어 다른 사람이 Pull을 하는 URL과 라이브러리의 작업을 Push 하는 URL이 서로

git-scm.com

 

728x90
반응형

댓글