안녕하세요. 후르륵짭짭입니다.
지금까지 모듈화 하는 방법에 대해 작성했었습니다.
어떻게 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 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
Pod Spec 샘플 (내부모듈 배포 방식 보려고)
https://github.com/CocoaPods/Specs/blob/master/Specs/8/b/3/Google/3.0.3/Google.podspec.json
https://github.com/CocoaPods/Specs/blob/master/Specs/e/e/3/OpenSSL/1.0.210/OpenSSL.podspec.json
Pod 배포 방법
https://ali-akhtar.medium.com/distribute-framework-with-cocoapods-locally-and-remotely-4a39f95b3077
서브 모듈을 사용해서 Pod 배포 방법
https://blog.asamaru.net/2015/10/21/xcode-create-sub-module-using-cocoapods/
https://ios-development.tistory.com/1101
서브 모듈에 파일 드래그 해서 사용하는 방법
https://www.kodeco.com/690-dependency-management-using-git-submodules
서브 모듈 사용 하기
https://zeddios.tistory.com/718
Multiple Command 오류
https://lxxyeon.tistory.com/64
서브 모듈 정리
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
'Xcode > IOS' 카테고리의 다른 글
SwiftUI) 내맘대로 정리#2 (feat : onTapGesture , MagnificationGesture , Group) (5) | 2023.04.14 |
---|---|
iOS) SwiftUI 내 맘 정리#1 (feat: Animation , Circle & Capsule , DragGesture) (0) | 2023.03.05 |
IOS) Umbrella Framework 생성 및 배포(feat : CoCoaPods) (2) | 2023.01.29 |
IOS) TestFlight로 앱 배포하기와 오류들 (feat : X86 제거) (0) | 2023.01.12 |
SwiftUI) SwiftUI 체험기#1 - 다양한 Binding (0) | 2022.08.20 |
댓글