정보 전달이 아닌 과정을 회고하기 위한 글입니다
Fastlane은
fastlane is a tool for iOS and Android developers to automate tedious tasks
like generating screenshots, dealing with provisioning profiles, and releasing your application.
한마디로 이거다. 스크린샷 생성, 프로비저닝 프로파일 처리, 앱 배포 등의 과정을 알아서 처리해준다. 최근 진행하고 있던 프로젝트가 끝났는데, 누군가 앱의 번들 id를 앱스토어에 등록하면서부터 프로비저닝 프로파일의 필요성을 알게되었다. 개발자 사이트에 App Identifier를 등록하고 보니 다른 팀원들이 해당 identifier를 사용해 개발 또는 배포를 할 수 없게 됐다. 이를 해결하기 위해 팀을 만들고, CSR를 생성하고, Certificate들과 프로비저닝 프로파일을 생성하는 등 복잡하고 번거로운 과정들이 필요하다. 게다가 widget extension이 포함되어 개발용, 배포용 프로파일이 각각 필요해 4개의 인증서를 발급받았다. 이렇게 생성한 Certificates, Provisioning profiles은 보안상의 문제로 매번 에어드랍을 통해서만 공유해야 했다. 그리고 이번 프로젝트에서는 유저테스트에 집중해서 진행하다보니 피드백을 반영하면서 코드를 수정하고 프로덕트를 아카이빙하고, 앱을 다시 배포하는 과정이 잦아졌다.
그러다가 어디서 이놈을 봤는데... Fastlane 깃허브에서 본 저 한 줄 설명이 프로젝트를 진행하면서 나를 가장 귀찮게 했던 애들을 아울러 처리해주는 애더라. 코드 관리자 인증에 대한 과정과 배포 절차가 매우 간단해져 배포 과정의 효율을 높였고, 이후 진행한 프로젝트 초기 단계 더 빠르게 처리해 개발 단계에 더 집중할 수 있게 됐따. 너무 늦게 발견해서 아쉽지만 한편으론 여유로울 때 발견해서 적용할 생각을 할 수 있었던 것 같다. 마침 심사에 리젝당해서 지금 적용해두면 앞으로 배포할 때 유용하게 쓸 수 있을 것 같다 🤓
Fastlane 설치
내 맥에는 Homebrew가 이미 깔려있어서 이걸로 설치했다. 터미널 명령어는 brew install fastlane 이다.
Bundler 설치
fastlane을 업데이트할 때 사용하는 프로그램으로 Bundler를 설치해준다. 참고한 블로그에서 루비를 통해 깔았길래 나도 Ruby를 먼저 설치했다. brew install ruby 로 설치하면 최신 버전이 설치된다. 그리고 gem install bundler 로 bundler로 설치한다.
나중에 fastlane의 업데이트할 때는 bundle update 를 입력하면 된다.
Fastlane 세팅
Fastlane을 세팅하려는 디렉토리로 이동해서 초기화 명령어 fastlane init 을 입력한다.
가장 처음에 뜬 노란색의 명령어를 보면 fastlane의 사용목적을 묻는데 Manual setup할거라 4 를 입력해준다.
완료되면 Gemfile, Gemfile.lock, fastlane/Appfile, fastlane/Fastfile 이 네 개의 파일이 생성된다.
Gemfile, Gemfile.lock을 건들 일이 없을 것 같고 Appfile과 Fastfile을 수정해서 세팅해주면 된다.
그리고 이 파일들은 팀원들과 공유해야하므로 .gitignore에 추가하지 않는다.
App store 인증: Cert, Sigh과 환경변수 설정
개발 중이나 배포할 때 인증서를 통해 개발자 인증 과정을 거치게 되는데 두가지 방법이 있다고 한다.
1. Cert & Sigh
내 개발자 계정에 로그인이 제대로 되어있고, 인증서가 키체인 로컬항목에 잘 넣어져있다면 인증을 알아서 진행해준다.
로컬에 인증서가 없러다도 알아서 인증서와 프로파일을 다운받아주더라. 터미널에서 확인할 수 있었다.
그나저나 sigh가 뭘까 무엇의 약자인지 모르겠어서 오타인줄 알았다.
2. Match
팀 규모가 클 때 사용한다고 한다. 하나의 인증서를 깃허브 private 레포에 넣어두고, 필요할 때마다 해당 레포에 접근해서 인증서를 가져와 사용하는 방식이다. 인증서를 중앙에서 하나만 관리하면 되기 때문에 갱신이나 계정 문제 측면에서 유용한 방법인 것 같다.
나는 공부 겸 테스트용으로 세팅해본거라 일단 1번 방법으로 진행했다. 조만간 Match 방법으로 적용해서 첨언할 게 있다면 추가 작성해야지 🥸
환경변수 설정
fastlane/Appfile에 들어가면 번들 아이디와 내 애플 계정을 입력하게 되어있는데, 여러명이 사용하는 것을 고려해 애플 계정 부분은 환경 변수로 따로 빼주더라. 나도 그렇게 해봤다!
app_identifier("프로젝트 번들 아이디") # Bundle identifier of your app
apple_id(ENV["APPLE_ID"]) # fastlane/.env에서 애플아이디 세팅
Appfile에는 위 코드만 있으면 된다. 프로젝트 번들 아이디만 내 프로젝트의 번들 아이디로 바꿔준다.
그리고 두번째 줄의 애플아이디는 fastlane 디렉토리에 .env 파일을 만들어서 환경변수로 만들어준다.
vi .env
APPLE_ID="애플 계정 아이디"
그리고 .env 파일은 .gitignore에 추가해주고 팀원 모두 각자 설정하면 된다.
TestFlight 배포 환경 세팅하기
다음은 Fastfile에서 배포에 대한 명령어를 작성해준다.
default_platform(:ios)
platform :ios do
desc "Build app and upload to testflight"
lane :beta do
get_certificates
get_provisioning_profile
increment_build_number(xcodeproj: "Fastlane-Practice.xcodeproj")
build_app(
configuration: "Debug"
)
upload_to_testflight(skip_waiting_for_build_processing: true)
end
end
- desc description을 써준다.
- lane lane명을 설정할 수 있는데 보통 테스트플라이트에 올리는건 beta로 짓는 것 같다. 여기서 설정한 이름으로 나중에 배포할 때 명령어를 사용하게 된다. ex) fastlane beta
- get_certificates, get_provisioning_profile Cert & Sigh 방식에서 사용하는 인증 함수이다.
- increment_build_number 자동으로 빌드 넘버를 1씩 올려준다. 이는 로컬에서도 자동으로 변경된다.
- build_app(cofiguration:) Debug, Release 중 어떤 스킴으로 빌드할 것인지 설정할 수 있다. 우리팀에서는 UT용으로 테스트플라이트를 썼기 때문에 Release로 배포했고 Debug는 개발용으로 썼지만, 다음으로 앱스토어 배포 세팅 과정과 비교하기 위해 Debug로 설정해준다.
- upload_to_testflight(skip_waiting_for_build_processing:) TestFlight에 배포해주는 함수이다.
여기까지 작성하고 fastlane beta 를 입력해서 테스트해보려고 했다 ...
아 근데 자꾸 내 앱아이디가 없다는거임.. 그래서 개발자 페이지들어가서 App Identifier를 추가해줬다.
근데도 똑같은 오류가 났다. 찾아보니까 무슨 번들아이디가 25자를 넘어가면 에러가 나는 버그가 있다더라..
그래서 엄청 짧게 바꿔줬다!! 그래도 오류나더라!! 🤯
죄다 영어로 된 결과만 나와서 안그래도 어지러웠는데 그 답변이 전부 저 25자 버그 얘기 밖에 없었다 ...
리프레시하려고 밥먹을 준비하다가 생각해보니 앱스토어커넥트가 생각나더라.
은연 중에 이미 한 번 배포해 본 앱은 이 오류가 안날거라고 생각했는데, 이유가 앱스토어커넥트에 이미 올라와있기 때문이었다.
바보다 ㅎ 아까 개발자 페이지에서 App ID는 등록해뒀으니 신규앱으로 등록만 해주면 된다!! 이렇게 하면 잘 될 줄 알았는데!!
이번엔 요놈이다... Unable to upload archive. Failed to get authorization for username '' and password. 뭐 .ipa 파일이 업로드 안되고 authorization 안된다고 한다... 이것도 서치해보니까 방법이 여러개고 복잡한 것도 많았는데, 스택오버플로우에서 젤 간단한 방법을 발견해서 그 방법으로 해결했다!
내 애플 아이디 관리 페이지에서 제일 마지막 항목의 '앱 암호'에서 새 암호를 생성해준다.
그리고 아까 애플아이디를 환경변수로 설정해줄 때 썼던 .env 파일에 넣어주면 된다.
FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD="생성한 앱 암호"
그러면 이번엔 그전보다 더 강렬한 에러가 뜬다.
처음에 겁먹고 다시 빽했는데, 다시 읽어보니까 앱 아이콘이 없어서 배포가 안되는거였다!
프로젝트에서 아이콘넣어주니 성공했음 🚀🚀
AppStore 배포 환경 세팅
그럼 이번엔 앱스토어 배포 환경 세팅!
아까 Fastfile에서 테스트플라이트 세팅 명령어 아래에 앱스토어 세팅 명령어도 작성해준다.
default_platform(:ios)
platform :ios do
desc "Build app and upload to testflight"
lane :beta do
get_certificates
get_provisioning_profile
increment_build_number(xcodeproj: "Fastlane-Practice.xcodeproj")
build_app(
configuration: "Debug"
)
upload_to_testflight(skip_waiting_for_build_processing: true)
end
desc "Build app and release to App Store."
lane :release do |options|
if options[:v]
get_certificates
get_provisioning_profile
increment_build_number(
build_number: latest_testflight_build_number + 1
)
build_app(
configuration: "Release"
)
upload_to_app_store(
app_version: options[:v],
submit_for_review: true,
force: true,
automatic_release: true,
skip_screenshots: true,
skip_metadata: false
)
end
end
end
이번엔 lane 명 옆에 옵션을 달아주도록 하게 했따.
배포할 때 배포 버전을 같이 달아주면 된다. fastlane release v:1.0
여기까지 세팅잘하고 심사에 추가까지 해보려고 했는데 또 오류가 잔뜩 떴다.
뭐 데이터가 없다길래 앱 정보란이 다 비어있어서 그런가보다 했다.
근데 이상하다.. 그럼 반자동 아닌가?
일단 App Store Connect에서 스크린샷, 설명, 키워드, 심사 정보 등 해당 앱에 대한 정보를 모두 채워줬다.
또, 암호화알고리즘을 썼는지 원래 앱스토어커넥트에서 문서를 제출해야하는데, Info.plist에서 App Uses Non-Exempt Encryption을 NO로 넣어준다.
그리고 다시 명령어 입력해보면 잘 됐음! 야호 🚀🚀🚀🚀
반 년 전에 어느 특강에서 누군가 SnapKit을 반드시 쓸 줄 알아야 하느냐고 묻는 사람이 었었는데,
당시 강사가 대답하기를 SnapKit을 쓰기 이전에 본인이 코드로 직접 쓸 줄 아는 상태가 기본이어야 한다고 대답한 것을 본 적이 있다.
fastlane을 적용해보면서 갑자기 이 말이 떠오르더라 ㅋㅋ
확실히 앱스토어 배포 과정을 몇 번 수동으로 진행해보고 잘 이해하고 있으니 fastlane 적용에도 큰 어려움이 없었다.
내일은 우리 팀프로젝트에 fastlane 적용해보려 했는데, 앱 정보를 처음엔 다 입력해주면 그 이후엔 자동 배포가 되는건지, 아님 암호화 알고리즘을 Info.plist에 담아 아카이빙하듯 다른 방법이 있는지 확인을 먼저 해봐야겠다.
우리팀 프로젝트에는 widget extension이 포함되어 있고, 인증 방식으로 match를 적용해볼거라 성공한다면 기분 최고일듯
나는 오늘도 성장했나 ..........? 🤓
끗 -
2023.08.14. (월) 수정
앱스토어 배포 방법도 비슷한데, deliver를 초기화해줘서 배포 설정을 어떻게 할 지 작성해야 하는데 나는 아래와 같이 작성해줬다.
// Deliverfile
app_identifier "번들 아이디"
submission_information({
price_tier: 0, # 가격
export_compliance_encryption_updated: false,
export_compliance_uses_encryption: false, # 암호화 사용 여부
content_rights_contains_third_party_content: false, # 써드파티 컨텐츠를 사용하는지
add_id_info_uses_idfa: false, # IDFA 사용 여부
})
app_rating_config_path("./fastlane/metadata/app_store_rating_config.json") # 연령 등급에 대한 정보
submit_for_review(true) # 심사까지 올릴거면 true
automatic_release(true) # 심사 통과시 앱스토어에 배포
force(true) # Does the Preview on path './fastlane/Preview.html' look okay for you? (y/n) 생략
그리고 연령 등급에 대한 정보는 json 파일로 따로 작성해준다.
{
"CARTOON_FANTASY_VIOLENCE": 0,
"REALISTIC_VIOLENCE": 0,
"PROLONGED_GRAPHIC_SADISTIC_REALISTIC_VIOLENCE": 0,
"PROFANITY_CRUDE_HUMOR": 0,
"MATURE_SUGGESTIVE": 0,
"HORROR": 0,
"MEDICAL_TREATMENT_INFO": 0,
"ALCOHOL_TOBACCO_DRUGS": 0,
"GAMBLING": 0,
"SEXUAL_CONTENT_NUDITY": 0,
"GRAPHIC_SEXUAL_CONTENT_NUDITY": 0,
"UNRESTRICTED_WEB_ACCESS": 0,
"GAMBLING_CONTESTS": 0
}
그리고 Fastfile의 release lane에서 deliver를 호출해주면 끝난다.
찾아보니 메타데이터는 앱스토어에서 일단 작성하고, 작성된 것을 다운로드해오는 형식이 좋다고 한다.
내가 생각해도 작성해야하는 앱 정보의 txt 파일이 열개가 넘는데, 직접 만들어주기보다 앱스토어에서 작성하는 편이 훨씬 쉬울 것 같다.
스크린샷은 올려둔걸 다운받게 했었는데, 한참 걸릴 것 같아서 실행해놓고 자고 인나서 다시 보니 여태 프로세싱 중이더라.
그래서 그냥 fastlane/screenshots 안에 사이즈별로 이름 맞춰서 사진 넣어두니까 알아서 올라가고 훨씬 빨랐다!
왜 그렇게 느렸는지는 모르겠다. 인터넷이 느렸을지도 모르겠다.
또 아래 오류가 한참동안이나 떠서 애먹었는데, 아마도 Deliverfile을 잘못작성했던 것 같다.
어디선가 가격에 대한 정보를 price_tier(0)으로 작성하면 된다고 봐서 그렇게 써놨다가,
공식문서에서는 또 submission_information의 파라미터로 price_tier 0으로 쓰면 된다고 해서 그렇게 또 써봤더니 문법 오류라 하고 ..
결국에는 price_tier(0)을 삭제하고 submission_information의 파라미터로 price_tier: 0으로 써줬다.
에러의 원인이 가격 정보 때문인 것은 파악했지만, fastlane 깃허브의 이슈에서도 정확한 해결방법을 못찾아서 곤란했다 🥹
the resource 'appprices' cannot be viewed, created or updated.
please view and create 'manualprices' using the resource 'apppriceschedules'.
어쨌든 앱스토어에 리뷰 요청까지 성공 🚀
이제 남은 큰 산은 Match 방식의 인증 방식 이용하기 ... 별 일 없으면 따로 글은 쓰지 않을 것 같다!
찐짜 끗 -