Lined Notebook

private Repository로 Cocoapods Library 만들기(1)

by 사슴비행기

ios

글을 다듬는 중이어서 추후에 조금씩 수정될 수 있습니다. :-)

혹시 틀린 부분이 있다면가차없이 철퇴를 날려주세요

그 철퇴 글에 다시 녹여보겠습니다 ㅠ

 

 

1년 정도 일했을 때는

부랴부랴 기능만 구현하느라

리팩토링이라느니 객체화라느니

신경 쓸 겨를이 없었는데,

 

개발만 하는게 아니라

유지 보수를 하게 되면서

재사용, 객체화, 리팩토링, 메모리 누수 등등

얼마나 중요한지, 점차 알게되었다.

 

 

그래서 프레임워크로

로직을 따로 떼어내는 작업도 연습해봤었는데

고수분들이 Cocoapods로 배포도 해보고

SPM...주입?(아직 이게 뭔지 잘 모르겠다)

으로도 해보라고 해서,

시행착오를 글로 쓰게되었다.

 

본 글은 Zedd님의 가이드에 따르면서

(해당 글 하단에 링크 추가해두었습니다.

원본으로 보실 분들은 출처로 이동해주세요.)

이해가 안가서 따로 찾아본 부분 추가 및

제 상황에서 발생하던 오류와 해결방법을

추가한 글이니 참고하시길 바랍니다.


 

일단 여러 사람들이 쓸 수 있게

public하게 만드는 방법과

회사 내부에서만 쓰는 로직 등을 만드는

private하게 만드는 방법이 있다.

 

오늘 내가 기록할 부분은 private하게

cocoapods를 만드는 것이다.

 

이전에 대충 따라하다가

여러 오류를 만나고 포기했던 기억이 있는데

오늘은 끈기를 가지고 하나하나 해결해보려 한다.

 

 

0. 먼저 이해하고 헷갈리지 말아야 할 것

 

코코아팟 라이브러리를 만들 때

Repo(= 레포지토리 = 저장소 =  Repository)

라고 불리는 것이 2개가 있다.

 

 

1. 우리가 구현하고자하는 소스코드를 가진 Repo.

- 아래 pod lib create로 만드는 것이다.

- Pod Repo라고 한다.

 

2. private한 Pod Repo를 관리하기 위한 Spec repo.

- pod spec들을 모아둔 repo다.

 

자세한 내용은 spec repo가 나오는 구간에

추가해 두었다.

 

 

1. 라이브러리 만들기

터미널에 '라이브러리를 만들 위치'로 가준다.

cd 명령어를 이용해서 이동할 수 있다.

 

그 다음 아래 코드를 터미널에 쳐준다.

 

 

pod lib create 라이브러리이름

 

 

그러면 이런 질문들을 물어본다.

 

 

1. What platform do you want to use??
-> 너가 사용하려는 플랫폼이 뭐야?
 
2. What language do you want to use??
-> 원하는 언어는 뭔대?
 
3. Would you like to include a demo application with your library?
-> 너 라이브러리에 데모앱을 포함시킬꺼야?
 
4. Which testing frameworks will you use?
-> 너 testing 프레임워크를 사용할거야? (None으로 하면 Apple의 Test 프레임워크를 사용한다고 함)
 
5. Would you like to do view based testing?
-> 너 view 테스트를 할꺼야?

 

 

나는 순서대로

iOS, Swift, Yes, None, Yes라고 했다.

testing 프레임워크의 선택지에 Quick이 있는데

이것도 추후에 해보고 싶은데,

일단은 오류를 막기위해

기본부터 해보고 해보려고 한다.

 

아무튼, 마지막질문까지 대답하고

엔터를 치면 

 

 

Running pod install on your new library.

Analyzing dependencies
Downloading dependencies
Installing CustomPopupView (0.1.0)
Installing FBSnapshotTestCase (2.1.4)
Generating Pods project
Integrating client project

[!] Please close any current Xcode sessions and use `CustomPopupView.xcworkspace` for this project from now on.
Pod installation complete! There are 2 dependencies from the Podfile and 2 total pods installed.

 Ace! you're ready to go!
 We will start you off by opening your project in Xcode
  open 'CustomPopupView/Example/CustomPopupView.xcworkspace'

To learn more about the template see `https://github.com/CocoaPods/pod-template.git`.
To learn more about creating a new pod, see `https://guides.cocoapods.org/making/making-a-cocoapod`.

 

 

뭐, 이런 문구같은게 뜨면서

생성이 완료된다.

자, 40%는 했다.

 

그럼 만든 라이브러리 폴더로 이동해서 보면

_Pods.xcodeproj 이런게 보이는데

이건 Pod 프로젝트 파일이라고 한다.

 

예제 앱을 Yes라고 했다면,

Example에 ...xcworkspace가 만들어져 있을 거다.

 

아무튼 이정도만 대충 훑어보고,

 

 

2. 라이브러리 설정 파일 수정하기

 

다시 _Pods.xcodeproj 파일이 있는 곳으로 되돌아가면

라이브러리이름.podspec 파일이 있을거다.

거기서 이 라이브러리의 설명을 변경해주면 된다.

 

이미 적혀져 있는 것들을

수정하거나 주석을 제거하면 된다.

여기서는 #이 주석이다.

 

 

s.name -> 라이브러리 이름 
s.version -> 라이브러리 버전 
s.summary -> 요약 설명
s.description -> 상세 설명 
s.homepage -> 홈페이지 주소
s.license -> 라이센스
s.author -> 작성자
s.source -> 소스 주소
s.ios.deployment_target -> 타겟 iOS버전 
s.source_files -> 소스파일 경로
s.resource_bundles -> 리소스 파일 경로

출처: daddy73님 블로그(하단 주소 참고)

 

 

내가 작성한 부분

 

 

#
# Be sure to run `pod lib lint CustomPopupView.podspec' to ensure this is a
# valid spec before submitting.
#
# Any lines starting with a # are optional, but their use is encouraged
# To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html
#

Pod::Spec.new do |s|
  s.name             = '라이브러리이름'
  s.version          = '0.1.0'
  s.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!

  s.description      = <<-DESC
TODO: Add long description of the pod here.
                       DESC

  s.homepage         = '홈페이지주소(없으면 깃헙주소)'
  # s.screenshots     = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  s.author           = { '닉네임' => '메일주소@gmail.com' }
  s.source           = { :git => '깃헙주소', :tag => s.version.to_s }
  # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'

  s.ios.deployment_target = '13.0'

  s.source_files = 'CustomPopupView/Classes/**/*'
  
  #s.resource_bundles = {
  #  'CustomPopupView' => ['CustomPopupView/Assets/*.png']
  #}

  # s.public_header_files = 'Pod/Classes/**/*.h'
  # s.frameworks = 'UIKit', 'MapKit'
  # s.dependency 'AFNetworking', '~> 2.3'
end

 

 

나는 위처럼 썼다.

위에서 '깃헙주소'라고 된 부분은

깃헙에서 레포지토리를 만든 후,

주소를 복사해서 넣으면 된다.

 

 

 

 

 

private로 만들거기 때문에

위와같이 작성해주면된다.

 

 

3. 제대로 잘 적용됐는지 확인하기

 

이전에 라이브러리 만드는 것에

실패했을 때, 깃에 적용하려니

계속 오류가 났었는데,

 

지금까지 잘 하고 있는건지 알아볼 수 있는

코드가 있다고해서 놀랐다.

 

 

pod spec lint

 

 

라고 하는데 나는 단박에 에러가 났다.

 

 

 

 

이 때에는 이게 뭐지...

이러다가, 일단 확인만 한거니깐

일단 넘어가고 나중에 다시 검사해보기로 했다.

 

그런데 지금와서 보니

github 주소를 검색할 수 없다는 문구가 똭 떠있다..

처음에는 이 컴퓨터에 기본으로 설정되어 있는

깃헙 계정이랑 안 맞아서

private 레포지터리에 접근하려니

검색을 못하는 것 같다고 생각했다.

 

그래서 github 키체인 삭제하고

깃헙에서 토큰키 생성해서

라이브러리 만든 계정 키체인데

암호란에 토큰키 넣어주고 다시 실행 해봐도

같은 오류가 나고 있었다.

 

그런데 알고보니..

그냥 github 키체인 삭제하면

자동으로 등록된 계정이 초기화되서

깃에 올리거나 할 때 아이디와 비밀번호를

입력하는 스코프가 추가되는데

그부분의 암호에 토큰키를 넣어주면 되는 거였다.

왜냐면, 인증방법?이 바뀌어서

이제는 토큰키로 깃헙 업로드나 풀 등을 할 수 있기 때문이다.

깃헙 블로그에 해당 내용이 있으니 참고.

 

어쨌든 이유는 private 레포지토리에

접근하려해서 나는 문제가 맞다.

 

 

4. 라이브러리 코드 작성하기

 

그리고 아까 _Pods.xcodeproj 파일이 있던 곳으로

되돌아가서,

이번에는 내가 만든 라이브러리 이름으로 되어 있는

폴더에서 Classes 폴더에 들어가면

RenameMe..?이게 맞나? 아무튼

이름 다시 지어달라는 .swift 확장자 파일이 있는데

원하는 이름으로 지어주고, 편집을 해보자

 

여기에 만든 클래스들이

실제 이 라이브러리를 가져다 쓰는 곳에서

호출하는 클래스, 메소드들이 될 것이다.

 

수정은 _Pods.xcodeproj 파일을 실행해서

 

 

 

 

이 뎁스에서 수정하면 더 편하다.

 

 

public class CustomPopup: NSObject {
    public func callLib() {
        print("call from CustomPopupLib")
    }
}

 

 

나는 이렇게 적어주었다.

여기서 주의할 점은,

이 라이브러리에 접근해서 호출할 수 있게 하려면

꼭 public 접근 연산자를 써주어야 한다.

 

 

5. 라이브러리 코드 테스트 하기

 

 

여기서 수정했다면,

이 화면은 끄고, Example폴더의 xcworkspace를 켜준다.

그다음에 ViewController에서

내가 만든 라이브러리를 import해주고

방금 만든 클래스의 메서드를 호출하는 코드를 작성하고

실행해서, 해당 동작을 하는지 확인하면 된다.

 

 

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    CustomPopup().callLib()
}

 

 

나는 디버그 창에 로그가 잘 떴다.

 

 

6. 배포하기

 

 

이제는 다시 터미널로 가서

 

 

git add .
git commit -m "first commit"
git remote add origin git주소
git tag 0.1.0
git push origin 0.1.0

 

 

이 코드를 차례대로 적어서 실행하면 되는데,

 

 

git push origin 0.1.0

 

 

이 코드 부분에서 계속

 

 

remote: Repository not found.
fatal: repository 'https://github.com/jeung-dev/CustomPopupView.git/' not found

 

 

이런 오류가 생겼다.

 

이게 내가 위에서 말했던

private 레포지토리에 접근하지 못해서

발생하는 문제이다.

 

그래서 키체인에서 github을 제거하고

다시 명령어를 입력하니

아이디와 비밀번호 입력하는 영역이 추가되었다.

하지만, 여기서 그냥 깃헙 계정 비밀번호를 쓰면

 

 

CustomPopupView % git push origin 0.1.0
Username for 'https://github.com': 아이디
Password for '-': 계정비밀번호
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: Authentication failed for 'https://github.com/jeung-dev/CustomPopupView.git/'

 

 

오류문구를 대충 보면,

2021년 8월 13일부터 비밀번호 인증은 지원이 중지됐어.

대신에 개인접근 토큰키를 이용해줘.

라는 문구다.

그리고 바로 밑에 문구는

내가 엄청 예전에 깃허브 블로그 만든다고

생성한다고 만들어둔 토큰키가 있었는데

그걸로 인증을 못했다고, 치명적인 오류가 발생했다고

문구가 떴다.

 

그래서 토큰을 다시 생성하고 해당 토큰을

비밀번호 입력부분에 넣었더니

 

 

CustomPopupView % git push origin 0.1.0
Username for 'https://github.com': 계정
Password for '-': 토큰키
Enumerating objects: 108, done.
Counting objects: 100% (108/108), done.
Delta compression using up to 12 threads
Compressing objects: 100% (102/102), done.
Writing objects: 100% (108/108), 52.70 KiB | 4.79 MiB/s, done.
Total 108 (delta 27), reused 0 (delta 0)
remote: Resolving deltas: 100% (27/27), done.
To https://github.com/jeung-dev/CustomPopupView.git
 * [new tag]         0.1.0 -> 0.1.0

 

 

이렇게 잘 업로드 되는걸 볼 수 있다.

여기서 끝이냐?

아니다... ㅎㅎ

그래도

이제 80%는 했다고 봐도 된다.

 

7. 버전관리하기

 

아까 처음에 말했던 repo가 사실은 2개 만들어진다고

했던 부분이 이제 나올 때가 되었다.

 

 

pod repo add [REPO_NAME] [git주소]

 

 

일단, cocoapods의 repos에 spec repo를 추가한다.

REPO_NAME은 Spec Repo를 의미한다고 하는데

이게 무슨소리람 ㅋㅋ...

 

 

-수정 및 추가-

private Cocoapods 레포지토리를 만드려면

public과 달리 배포된 버전정보 등을 알 수 없으니

'배포된 버전정보 등을 저장, 관리하는 레파지토리'

내가 만든 github에 추가해야 한다.

그래야, pod을 install했을 때

버전 등을 관리할 수 있을 것이다.

 

'배포된 버전정보 등을 저장, 관리하는 레파지토리'

가 바로 Spec 레파지토리(Spec Repo)다.

그럼,  cocoapods 라이브러리를 만들 때

버전 정보를 가지고 있는 파일은 무엇인가?

 

바로, .podspec 파일이다.

즉, 이 Spec Repository는

.podspec만을 가지는 저장소인 것이다.

 

그래서 일단 위에서 적은 명령어처럼

내 라이브러리의 버전정보를 관리할 저장소를 만들고(위 코드)

 

참고로 github주소를 쓰는 이유는

이 레파지토리를 저장할 위치를 가리키고 있는 것이다.

 

 

cd
cd ~/.cocoapods/repos

 

 

이 경로로 이동해서 방금 만든

Spec Repo를 확인할 수 있다.

 

해당경로의 폴더를 열고싶다면

open ~/.cocoapods/repos를 하면 될 것이다.

 

 

pod repo push [REPO_NAME] [라이브러리 폴더 안에있는 .podspec경로]

 

 

그리고 당연한 말이지만,

내가 만든 라이브러리의

'현재 버전정보'가 담겨있는 .podspec 파일을

Spec(.podspec들을 모아둔곳)에

추가해야한다.

그 코드가 바로 위 코드다.

 

 

이해를 돕기위해 예를들어 말하자면,

 

내가 0.1.0 버전으로 먼저 추가하고

나중에 더 최적화를 시켜서 

버전 0.2.0

버전 0.3.0

등을 만들고 추가 업로드했다면 Spec Repo엔,

0.1.0

0.2.0

0.3.0

등의 버전정보를 모두 가지고 있고,

내가 만든 라이브러리의 .podspec파일엔

마지막 버전(최신버전)이 저장되어 있을 것이다.

 

-수정 및 추가 끝-

 

 

 

하지만 안타깝게도... 나는...

위 작업을 한 뒤에 오류가 발생했다.

 

 

터미널에 해당 파일을 끌어다 놓아서

경로를 알아낸 다음, 복붙하니,

중간에 계속 이상한 경로가 추가되더라...(왜지???)

 

워낙 이것저것 다 해봐서

뭐 때문이었는지 정확하게 알 수는 없지만

둘 중 하나인 것 같다.

 

1. 경로 중에 한글이름이 깨졌던가

 

2. 경로를 복붙하는 과정에서

이상한 경로가 계속 추가 되었거나...

 

나는 폴더 이름을 영어로 바꾸고

경로를 복붙하는게 아니라,

터미널의 코드 중, 입력해야 하는 부분에

파일을 끌어다 놓아서 경로가

정확하게 표시되도록 했더니 해결되었다.

 

 

하지만 나는 오류를 발생시키는 똥손이지 ㅠ

엔터를 쳐도 이런 오류가 났다.

 

 

 

 

아까 .podspec파일에서 설정하는 것중에

있던 속성인데,

그 부분은 원래 주석처리 되어 있던 것을

내가 주석을 푼 것이었는데

에러가나서... 일단은 다시 주석으로 묶었다.

(일단 나중에 수정 해보는 것으루...)

 

+ 할 일 추가

 

 

 

 

이번엔 오류가 아니라 경고가 뜬다.

경고는 무시할 수 있는 코드가 있는데,

 

 

pod repo push [REPO_NAME] [라이브러리 폴더 안에있는 .podspec경로] --allow-warnings

 

 

계속 시도하던 코드에 --allow-warnings를 붙이면

경고가 무시되고 실행된다.

 

지금은 이렇게 하지만 글 초반에 했던

pod spec lint를 해서 오류와 경고가 없을 때

웬만하면 그 때, 업로드 하는게 제일 좋다고 한다.
+ 할 일 추가

 

 

 

 

이제 90% 다 했다.

 

 

8. 만든 라이브러리 적용해보기

 

깃헙 라이브러리 올린 페이지에서

잘 업로드 되었는지 확인해본 뒤,

'새로운 프로젝트'를 만들어서

이 라이브러리를 적용해볼 것이다.

 

최종 확인쓰~!

 

나는 이전에 테스트용으로 쓰던 프로젝트가 있는데

그걸 사용할 것이다.

 

 

일단 늘 하던것처럼

 

 

% cd /Users/app/ImageTest/ImageTest 
% cd ../
% pod init

 

 

해주고, 생긴 Podfiles를 수정한다.

 

 

 

 

source에 내 라이브러리 깃 주소를 입력하고,

pod '라이브러리이름' 적은 뒤에 저장하고,

 

 

% pod install

 

 

이걸 해주면, 다운로드가 정상적으로 된다.

쓰려는 곳에 내가 만든 라이브러리를 import하고

만들어둔 라이브러리의 메서드를 호출하면

실행했을 때 해당 코드가

잘 작동되는 걸 볼 수 있다.

 

 

 

9. 라이브러리 업데이트 해보기

 

 

다 된 것 같지만,

놀랍게도 아직 95%까지밖에 못했다.

유지보수는 해야하니깐.

 

이제 Cocoapods를 update해볼 거다.

 

 

public class CustomPopup: NSObject {
    public func callLib() {
        print("call from CustomPopupLib")
    }
    
    public func printJeung() {
        print("Jeung")
    }
}

 

 

printJeung이라는 메소드를 추가하고

.podspec파일에서 s.version을 수정하고

(이런식으로)

 

 

s.version         = "0.2.0"

 

 

터미널에서

 

 

git add .
git commit -m "커밋 메시지"
git tag 0.2.0
git push origin 0.2.0

 

 

이거 한 뒤에 (이전과 다르게 remote가 빠진 것 확인.)

다시 아래와같이 써주고

 

 

pod repo push [REPO_NAME] [라이브러리 폴더 안에있는 .podspec경로] --allow-warnings

 

 

적용할 프로젝트에서 pod update해주면

업데이트 끗!

 

- pod lib create로 만들어진 폴더 = A

- cocoapods/repo/내라이브러리 = Repo

- 적용하는 프로젝트 = B

라고 하면, 

 

1. A를 수정

2. Repo로 가서(경로) pod repo push 작업.

3. B에서 pod update

 

이렇게 정리할 수 있다.

 

그다음 다시, 새로 만든 메서드가 잘 작동하는지

확인해보면 된다.

나는 잘 적용되었다.

하지만 앞으로 수정해야할 게 많아 보인다..ㅠ

 

 

 

 

 

 

참고한 글


 

라이브러리 만들기 참고

https://zeddios.tistory.com/701

https://daddy73e.tistory.com/5

https://tong94.tistory.com/22

https://stackoverflow.com/questions/61962019/how-add-storyboard-to-my-framework-and-appear-in-library-pod-as-resources-when-m

https://liveupdate.tistory.com/374

https://ichi.pro/ko/swift-jeongjeog-laibeuleoli-mich-lisoseu-beondeullo-kodeu-mich-lisoseu-jaesayong-229183350192957

https://yagom.net/forums/topic/cocoapods으로-라이브러리를-만들고-있는데-라이브러리-안/

 

깃헙 토큰키 만들기 참고

https://formestory.tistory.com/22

 

github remote: Repository not found 에러 참고

https://velog.io/@nonz/git-mac-에서-github-remote-Repository-not-found

https://coding-sojin2.tistory.com/114

 

zsh: command not found 참고

https://velog.io/@palette/zsh-command-not-found-nvm-오류해결법

 

private, public 라이브러리 동시에 추가하기 참고

https://stackoverflow.com/questions/53213695/pod-install-doesnt-have-access-to-private-repo-but-git-clone-etc-work-on-the

https://stackoverflow.com/questions/45287082/using-private-pod-and-public-pod-in-the-same-project

 

 

cocoapods 관련

 

https://littleshark.tistory.com/33

블로그의 정보

Beautiful Coding

사슴비행기

활동하기