ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Fastlane Tutorial: Getting Started
    Raywenderlich/Articles 2020. 11. 2. 10:00

    www.raywenderlich.com/233168-fastlane-tutorial-getting-started

     

    fastlane Tutorial: Getting Started

    In this fastlane tutorial, you’ll learn how to provision, screenshot, build and upload an app to the App Store using fastlane.

    www.raywenderlich.com

    Version

    Other, macOS 10.14, Other

     

    Update note: Lyndsey Scott이 Xcode 10.1, Swift 4.2, Ruby 2.5.1, fastlane 2.112.0으로 이 튜토리얼(tutorial)을 업데이트(updated)했다. Satraj Bambra가 원본(original)을 작성했다.

    정말 멋진 순간(moment)이다. 앱을 만드는 데 며칠, 몇 주, 심지어 몇 달을 쏟아 부었고(poured), 마침내 전 세계와 공유(share)할 준비가 되었다. App Store에 제출(submit)만 하면 된다. 하지만 이는 꽤 힘든 작업이다.

    귀찮은(grunt) 작업이 엄청나게 많다(mountains): 수 많은(tons of) 스크린샷(screenshots) 캡처(capturing), Apple Developer 및 App Store Connect 사이트에 앱(app) 추가, 바이너리(binary) 및 메타 데이터(metadata) 업로드(uploading) 등의 무신경한(mindless) 작업들.

    지원되는(supported) 모든 기기(devices)에서 모든 스크린샷(screenshots)을 자동으로(automagically) 캡처하는 공통 언어의 단일 명령(single command)을 실행(run)할 수 있다면, 이런 스크린샷(screenshots)을 업로드(upload)하는 단일 명령(single command)이 있다면, Apple 개발자 사이트(developer sites)에 앱(app)을 추가하고 모두 제출(submit)할 수 있을 것이며, 절약할 수 있는 시간은 꽤 클 것이다.

    제작자(creator) Felix Krause와 수석 유지 관리자(lead maintainer) Josh Holtz 덕분에 이 모든 것을, 그리고 더 많을 것을 수행할 수 있는 도구(tool)가 있다. 바로 fastlane 이다. 이 튜토리얼(tutorial)에서는 fastlane을 사용하여 App Store에 앱(app)을 배포하(deploy)는 방법을 배운다. 틀림없이 가장 친한 새로운 친구가 될 것이다. 심지어 Google이 2017년에 fastlane을 인수(acquiring)했다.

    막대기가 스크린샷이라면, 이 개는 fastlane만큼 도움이 될 것이다.

     

    Note: 이 튜토리얼(tutorial)은 유료(paid) Apple Developer 계정(account)이 있고, command line, Xcode와 앱(app) 제출(submission) 과정(process)에 대한 기본 지식(basic knowledge)이 있다고 가정한다. 계정이없는 경우 이 튜토리얼(tutorial)이 도움이 될 것이다.

     

    Getting Started

    먼저 Download Materials 버튼(button)을 사용하여, 페이지(page)의 상단(top) 또는 하단(bottom)에서 이 튜토리얼(tutorial)의 자료를 다운로드(download)한 다음, 편한 위치(convenient location)에 저장(save)한다.

    이 튜토리얼(tutorial)의 샘플 앱(sample app)인 mZone Poker는 No Limit Texas Hold‘Em 토너먼트(tournaments)용 포커 계산기(poker calculator)이다. 칩(chip)의 수(count)와 현재의 빅 블라인드 레벨(current big blind level)을 기반으로(based on) 권장 행동(recommended action)를 표시(displays)한다.

    Xcode에서 mZone 프로젝트(project)를 열어 빌드(build), 실행(run) 및 확인(check it out)한다.

     

    Setting Up fastlane

    fastlane 도구(tool)는 Ruby 스크립트(scripts)의 모음(collection)이므로, 올바른 버전(correct version)의 Ruby가 설치(installed)되어 있어야 한다. 기본적으로(default) OS와 함께 Ruby 2.0이 제공되지만, 터미널(Terminal)을 열고 다음을 입력(entering)하여 이를 확인(confirm)할 수 있다:

    ruby -v

    설치(installed)되어 있지 않은 경우, 가장 쉬운 설치 방법은 macOS 용 패키지 관리자(package manager)인 Homebrew를 사용하는 것이다.

    다음 터미널(Terminal) 명령(command)을 입력(entering)하여, Homebrew를 설치(Install)한다:

    /usr/bin/ruby -e \
      "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

    그런 다음 Ruby를 설치(install)한다:

    brew update && brew install ruby

    brew link --overwrite ruby를 실행(run)하거나 Homebrew가 지시하는 경우 새 터미널(Terminal) 세션(session)을 연다.

    Xcode Command Line Tools (CLT)도 필요하다. 설치(installed)되었는지 확인(ensure)하려면 터미널(Terminal)에 다음을 입력(enter)한다:

    xcode-select --install

    Xcode CLT가 이미 설치(installed)되어 있는 경우, 다음 오류가 표시된다. xcode-select: error: command line tools are already installed, use "Software Update" to install updates. 그렇지 않은 경우에는 프롬프트가 깜빡이며(prompted) 설치(installation)를 계속한다.

    이제 fastlane을 설치(install)할 준비가 되었다. 다음 명령(command)을 입력한다:

    sudo gem install -n /usr/local/bin fastlane --verbose

    Homebrew를 사용하려면, 다음 명령(command)을 입력(enter)한다:

    brew cask install fastlane
    Note: OS X는 El Capitan 이후, 사용자의 루트(root) 접근(access)을 방지(prevents)하는 루트리스(Rootless)라는 시스템 무결성 보호(System Integrity Protection)를 도입(introduced)했다. /usr/local/bin은 여전히 쓰기 가능(writable)하므로, 여기에 fastlane을 설치(installing)한다.

    시스템 암호(system password)를 입력(entering)하면, 터미널(Terminal)에서 설치(installation)가 진행 중(progress)임을 나타내는(indicating) 여러 작업(bunch of activity)을 볼 수 있다. 이 작업은 몇 분 정도 걸릴 수 있으므로 커피를 마시고(grab some coffee) 개를 산책(walk your dog)시키거나 좀비를 퇴치할 전략(zombie-fighting tactics)을 짤 수 있다.

    설치(installation)가 완료(completes)되면, 프로젝트(project)에서 fastlane을 설정(set up)할 준비(ready to)가 된 것이다. 하지만 시작하기 전에 fastlane 도구(tools)에 대해 자세히 살펴본다(high-level look at).

     

    The fastlane Toolchain

    fastlane은 다음과 같은 도구 세트(set of tools)를 제공한다:

    • produce: App Store Connect와 Apple Developer Portal 모두에서 새로운 iOS 앱(apps)을 생성(creates)한다.
    • cert: iOS 코드 서명 인증서(code-signing certificates)를 자동으로(automatically) 생성(creates)하고 유지(maintains)한다.
    • sigh: 프로비저닝 프로파일(provisioning profiles)을 생성(creates), 갱신(renews), 다운로드(downloads) 및 복구(repairs)한다.
    • snapshot: 모든 기기(device)에서 iOS 앱(app)의 현지화된(localized) 스크린샷(screenshots)을 자동으로 생성(automates)한다.
    • frameit: 스크린샷(screenshots)을 올바른 기기(device) 프레임(frames)에 넣는다.
    • gym: iOS 앱을 빌드(builds)하고 패키징(packages)한다.
    • deliver: 스크린샷(screenshots), 메타 데이터(metadata) 및 앱(apps)을 App Store에 업로드(uploads)한다.
    • pem: 푸시 알림 프로필(push notification profiles)을 자동으로(automatically) 생성(generates)하고 갱신(renews)한다.
    • spaceship: Apple Developer Center 및 App Store Connect API에 접근(access)할 수있는 Ruby 라이브러리(library)이다.
    • pilot: TestFlight 배포(deployments)를 자동화(automates)하고, 베타 테스터(beta testers)를 관리(manages)한다.
    • boarding: 베타 테스터(beta testers)를 초대(invites)한다.
    • match: Git을 사용하여 팀(team) 전체에서 인증서(certificates) 및 프로비저닝 프로필(provisioning profiles)을 동기화(syncs)한다.
    • scan: 앱(apps)에서 테스트(tests)를 실행(runs)한다.

    이러한 도구(tools) 중 몇 가지(several)를 오늘 사용하게 될 것이다. 지금은 이론(theory)으로 충분(enough)하다. 이제 이 튜토리얼(tutorial)을 진행하면서 빠른 차선(fast lane)으로 진입할 때이다.

     

    Adding fastlane to Your Project

    터미널(Terminal)을 열고, mZone 시작 프로젝트(starter project)로 cd한다. 예를 들어(for example), mZone_Sample_Project 폴더(folder)를 바탕화면(desktop)에 추가한 경우 다음과 같이 입력(enter)할 수 있다:

    cd ~/Desktop/mZone_Sample_Project/mZone

    mZone 시작 프로젝트(starter project)를 작업 디렉토리(working directory)로 설정(set)한다.

    다음을 입력(enter)한다:

    fastlane init
    Note: "permission denied" 오류(error)가 발생하면, 이 명령(command) 앞(prefix)에 sudo를 붙인다.
    어느 시점에서 fastlane이 최신 버전(newer version)으로 업데이트(update)하라고 알려주지만, sudo gem update fastlane을 실행하면 “Nothing to update,”라는 메시지가 출력(outputs)되는 경우에는 사용중인 Ruby 관리자(manager)가 최신 버전(up to date)이 아닐 수 있다. gem sources --add https://rubygems.org/을 실행(run)하면 Ruby Gems을 최신 정보(most current information)를 생성(produce)해 설치(install)한다.

    몇 가지 출력(output)한 후, 어떤 용도로 fastlane을 사용하는지 묻는다.

    fastlane init output

     

    fastlane은 "먼저 하나의 액션을 자동화(automating)할 것을 권장(recommend)"하지만, 이 튜토리얼(tutorial)에서는 여러(multiple) 자동화(automated) 액션(actions)을 구현(implement)하므로 4를 입력(input)하여 수동 설정(manual setup)으로 시작한다. 출력(output)을 읽고 프롬프트가 표시(prompted)되면 Enter를 누른다(press).

    mZone 폴더(folder)로 돌아가 보면, 몇 가지 새로운 항목이 표시된다. 프로젝트 종속성(project dependency)으로 fastlane gem을 포함하는 Gemfile과 다음 항목을 포함(containing)하고 있는 fastlane 폴더(folder)이다:

    Appfile: 앱 식별자(app identifier), Apple ID 및 fastlane이 앱(app)을 설정(set up)하는 데 필요한 기타 식별 정보(identifying information)를 저장(stores)한다.

    Fastfile: fastlane 액션(actions)을 호출(invoke)하기 위해 생성해야 하는 lanes을 관리(manages)한다.

     

    텍스트 편집기(text editor)에서 Fastfile을 열고, 텍스트 편집기(text editor)가 스마트 따옴표(smart quotes)를 지원하는 경우 이를 비활성화(disable)한 다음 파일(file) 내용(contents)을 다음으로 바꾼다(replace):

    default_platform(:ios)
    
    platform :ios do
      desc "Create app on Apple Developer and App Store Connect sites"
      # lane에 대한 설명을 제공한다. lane은 순차적인 workflow 이다.
      lane :create_app do
        # lane의 이름을 create_app으로 지정한다.
        produce
        # produce를 사용하여 Developer Portal과 App Store Connect에 앱을 추가한다.
      end
    end

    Ruby를 본 적이 없다면 횡설수설(gibberish)하는 것처럼 보일 수 있다. 이제 첫 번째 lane을 만들었다.

     

    Fastfile을 저장(save)한 다음, Appfile을 연다. 우물 정자(pound, #) 기호(sign)를 제거(remove)하여 apple_id로 시작하는 행(line)의 주석 처리를 제거(uncomment)한 다음 [[APPLE_ID]]를 실제 Apple ID 사용자 이름으로 바꾼다. 지금 이 정보(information)를 설정하면, fastlane이 나중에 반복해서(repeatedly) 이 정보를 요청(prompt)하지 않는다.

    Note: App Store Connect와 Apple Developer Portal 사용자 이름(usernames)이 다른 경우, apple_id 행(line)을 다음으로 바꾼다(replace):
    apple_dev_portal_id("[[APPLE_DEVELOPER_ACCOUNT_USERNAME]]")
    itunes_connect_id("[[APP_STORE_CONNECT_ACCOUNT_USERNAME]]")
    그런 다음 각 사용자 이름(username)의 자리 표시자(placeholder)를 해당(respective) 사용자 이름(username)으로 바꾼다(replace).

    닫기 전에 Appfile을 저장(savr)한다.

     

    Creating Your App

    프로젝트(project) 폴더(folder)에서 터미널(Terminal)을 열고, 다음을 입력(enter)한다:

    fastlane create_app

    방금 생성한 create_app lane이 실행(runs)된다.

    다음과 같은 내용이 표시되어야 한다:

     

    해당 출력의 맨 위에서 fastlane은 gem 번들(bundle)의 컨텍스트(context)에서 fastlane을 더 빠르게 시작하기 위해, fastlane 명령 앞에 "bundle exec"를 사용하도록 제안(suggests)한다. 앞으로는(going forward) 그렇게 사용한다.

    프롬프트(prompted)가 나타나면 App Store Connect 암호(password)를 입력한다. Developer Portal에 여러(multiple) 팀(teams)이 있는 경우, mZone Poker 앱(app)에서 사용할 팀에 해당하는(corresponding) 번호(number)를 입력(enter)한다.

    결국에는(eventually), bundle ID를 입력하라고 요구(ask)할 것이다. 하나를 만들 시간이다.

    번들 식별자(bundle identifier)는 App Store Connect에서 사용했던 모든 다른 번들 식별자(bundle identifier)와 달라야 한다. 다음 형식(format)을 사용하여 고유한(unique) 번들 식별자(bundle identifier)를 입력(enter)한다:

    com.mZone-Poker.[Insert your email address minus “@” and “.”]

     

    번들 식별자(bundle identifier)가 이미 사용된 경우, 이를 수정(edit)하여 고유한(unique) ID를 제출할 때까지 다시 시도(try)한다.

    그런 다음 앱(app) 이름(name)을 제출(submit)하라는 프롬프트(prompted)가 표시되는데, 이 역시 고유(unique)해야 한다. 다음 형식(format)을 사용한다:

    mZone Poker [Insert your email address minus “@” and “.”]

    하지만 앱 이름(app names)은 30자(characters)를 넘을 수 없으므로, 필요에 따라 잘라내야(truncate) 할 수도 있다.

    App Store Connect 계정(account)에 여러 팀(multiple teams)이 있는 경우, 사용하려는 팀에 해당하는(corresponding) 번호(number)를 입력(enter)한다.

    Apple Developer 계정(account)에 문제가 있다는 오류(errors)가 표시되는 경우(예를 들어, 새 프로그램 계약(agreement)에 동의(accept)해야하는 경우), 문제(issue)를 수정(correct)한 다음 다시 produce를 실행한다(run).

    앱 이름(app name)을 사용할 수 없는(unavailable) 경우, 과정(process)이 오류(error)와 함께 종료(end)된다. 다시 실행(run produce again)하여 Apple ID와 방금 생성한 동일한 Bundle ID를 다시 입력(re-enter)한 다음 창의력(creative muscles)을 발휘하여 고유한(unique) 새 ID를 만들거나 이 단락(paragraph)의 맨 위로 돌아가 반복(repeat)한다. 실망(confident)스럽겠지만 이 무한 반복(infinite loop)을 깰(break) 것이라 확신한다.

     

    Apple Developer Center와 App Store Connect에 로그인(log in)한다. 앱(app)이 이미 둘 다(both)에 추가되어 있다. 정말 멋진 일이다.

     

    Appfile을 다시 열고 app_identifier로 시작하는 행(line)의 주석을 제거(uncomment)한 다음, [[APP_IDENTIFIER]]를 방금 만든 번들(bundle) ID로 바꾼다(replace).

    이전에는 팀(team)을 선택해야 했다면, lane을 실행(running)할 때에는 다시 입력(enter)할 필요가 없도록 팀 이름을 추가한다. Developer Portal/App Store Connect에서의 팀 이름(team name)을 지정하려면 다음을 추가한다:

    team_name ("[[TEAM_NAME]]")

    [[TEAM_NAME]]을 팀 이름으로 대체(replace)한다.

     

    Generating the Deliverfile

    터미널로 돌아가 다음을 입력(enter)한다:

    bundle exec fastlane deliver

    fastlane이 "Do you want to setup deliver?"라고 묻는다(asks)면, y를 입력(enter)한다.

    다음으로 fastlane은 "Would you like to use Swift instead of Ruby?"라고 물을 것이다. iOS 개발자(developer)는 Swift로 작업하는 것이 더 편할(comfortable) 수 있지만, 이 튜토리얼(tutorial)을 작성하는 현재 fastlane.swift는 아직 베타(beta) 버전이다. 따라서 fastlane 파일(files)에서 Ruby를 사용하려면 n을 입력(enter)한다.

    deliver가 성공적으로 완료(completes)되면, Finder에서 mZone/fastlane으로 다시 이동한다. 그러면 다음과 같은 몇 가지 새로운 사항을 확인할 수 있다:

    • metadata 디렉토리(directory)는 앱(app) 메타 데이터(metadata)의 대부분(majority)을 보관(hold)한다.
    • Deliverfile은 몇 개의 나머지(remaining pieces) 메타 데이터(metadata)를 보유(hold)한다.
    • screenshots 디렉토리(directory)는 앱(app) 스크린샷(screenshots)을 포함(contain)한다.

     

    metadata 디렉토리(directory)에서 description, keywords, categories 등과 같은 일반적인(common) App Store 항목(items)의 이름을 따서 명명된 많은(bunch) 텍스트(text) 파일(files)을 볼 수 있다. fastlane은 이러한 파일(files)을 사용하여 앱(app)의 메타 데이터(metadata) 정보(information)를 App Store Connect에 제출(submit)한다.

    en-US/description.txt를 열고, 다음을 추가한다:

    mZone is a simple poker calculator for No Limit Texas Hold 'Em tournaments that displays a recommended course of action based on your chip count and the current big blind level.

    keywords.txt에 다음을 추가한다:

    Poker, Cards, Gambling

    name.txt에 이미 앱 이름이 포함(contains)되어 있는지 확인한 다음, privacy_url.txtsupport_url.txthttps://www.raywenderlich.com을 추가한다.

    이 앱은 프랑스어와 영어를 모두 지원(supports)하지만, en-US 폴더(folder)만 존재(exists)한다. 이 문제를 해결(fix)하려면, 동일한 디렉토리(directory)에 en-US 폴더(folder)의 복사본(copy)을 만들고 fr-FR라고 명명한다. 이 fastlane 튜토리얼(tutorial)을 짧게 마무리하기 위해, 이번에는 메타 데이터(metadata)를 프랑스어로 번역(translate)하지 않는다.

    metadata 폴더(folder)에서 다음을 추가적으로 수정한다:

    • copyright.txt에 Copyright (c) 2019 Razeware LLC를 추가한다.
    • primary_category.txtGames를 추가한다.
    • primary_first_sub_category.txtCard를 추가한다.
    • primary_second_sub_category.txtCasino를 추가한다.

    그런 다음 동일한 폴더(folder)에서 선호하는 텍스트(text)/코드(code) 편집기(editor)를 사용하여, 다음이 포함된 app_store_rating_config.json이라는 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": 2,
      "SEXUAL_CONTENT_NUDITY": 0,
      "GRAPHIC_SEXUAL_CONTENT_NUDITY": 0,
      "UNRESTRICTED_WEB_ACCESS": 0,
      "GAMBLING_CONTESTS": 0
    }

    이 등급(rating) 구성(configuration)은 앱(app)에 "frequent/intense"한 도박 시뮬레이션(simulated gambling, value = 2)이 있고, 기타 나열된 내용(content)은 없음을 나타낸다. 이 파일(file)은 적절한(appropriate) 연령 등급(age rating)을 지정하는 데 필요한 정보를 Apple에 제공(information)한다.

    마지막으로, review_information 폴더(folder)에서 이메일 주소를 email_address.txt에, 이름을 first_name.txt에, 성을 last_name.txt에, 전화 번호를 phone_number.txt에 추가한다. 전화 번호 앞에 ‘+’를 붙이고, 그뒤에 국가 코드(country code)를 붙인다. 예를 들면 +44 844 209 0611 와 같다. 

    축하한다. 제출(submission)에 필요한(required) 모든 메타 데이터(metadata)를 추가했다.

    Note: 여기에서 메타 데이터 옵션 및 Deliverfile 설정(settings)의 전체 목록(full list)을 찾을 수 있다.

     

    Automating Screenshots

    스크린샷(screenshots)을 찍는 것은 지루할 수 있다. 앱(app)에서 지원(supports)하는 기기(devices)와 언어(languages)가 많을수록, 더 많은 시간을 소모(burn)하게 되는 괴로운(painful) 작업이다.

    mZone Poker는 2개의 언어(languages)와 2가지의 iPhone 화면 비율(screen aspect ratios)을 지원(supports)한다. 각 언어(language)와 화면 비율(screen aspect ratio)에 대해 기기(device)당 5개의 스크린샷(screenshots)을 찍어야 한다면, 모두 20개의 스크린샷이 필요하게 된다. 그러나(however) fastlane을 사용하면 단일 명령(single command)을 실행(running)하여, 이 모든 작업을 처리할 수 있다.

    터미널(Terminal)에 다음을 입력하여 스냅샷(snapshot)용 프로젝트(project)를 설정(set up)한다:

    fastlane snapshot init

    이제 fastlane 폴더(folder)에 Snapfile 파일이 나타난다(appear). 그것을 열고, 파일(file)의 내용(contents)을 다음으로 바꾼다(replace):

    # 1 - A list of devices you want to take the screenshots from
    # fastlane에서 screenshots을 캡쳐하려는 기기 목록
    devices([
      "iPhone 8 Plus",
      "iPhone SE"
    ])
    
    # 2 - A list of supported languages
    # 캡쳐할 지역화 언어
    languages([
      'en-US',
      'fr-FR'
    ])
    
    # 3 - The name of the scheme which contains the UI Tests
    # screenshot 자동화를 실행하기 위해 곧 생성할 Xcode scheme 이름
    scheme("mZone Poker UITests")
    
    # 4 - Where should the resulting screenshots be stored?
    # screenshot의 output directory
    output_directory "./fastlane/screenshots"
    
    # 5 - Clears previous screenshots
    # fastlane은 새로운 screenshot을 캡쳐하기 전에 output directory의 screenshots을 삭제한다.
    clear_previous_screenshots(true)

    닫기(closing) 전에 파일(file)을 저장(save)한다.

    터미널(Terminal)로 돌아가서, fastlane snapshot init를 실행(running)한 후, 표시(note)되는 지침(instructions)을 확인한다:

    이것이 다음으로 할 일들이다(that’s what you’ll do next).

     

    Creating a Test Target

    Xcode에서 mZone Poker.xcodeproj를 열고 File ▸ New ▸ Target으로 이동(navigate)한다. iOS 탭(tab)의 Test 섹션(section)에서 iOS UI Testing Bundle을 선택(select)한 후 Next를 클릭(click)한다.

     

    Product Name 필드(field)에 mZone Poker UITests를 입력(enter)하고 Finish를 클릭(click)한다.

     

    이제 mZone Poker UITests 폴더(folder)가 Xcode의 왼쪽 탐색 메뉴(left-hand navigator menu)에 나타난다(appear).

    대상(target)의 General 페이지(page)로 이동한다. mZone Poker 타겟(target) 아래에 mZone Poker UITests가 표시된다. mZone Poker UITests를 선택(select)하고 Signing for “mZone Poker UITests” requires a development team는 오류(error)가 표시(stating)되면 팀(team)을 선택(select)한다.

     

    fastlane 디렉토리(directory)로 돌아가 SnapshotHelper.swift를 Xcode 프로젝트 탐색기(project navigator)의 mZone Poker UITests 폴더(folder) 아래로 드래그(drag)한다. 파일 추가 옵션 선택(options) 창(window)이 나타나면(appears), 다음을 선택(select)한다.

    • Copy items if needed.
    • Create groups.
    • mZone Poker UITests.

    Finish를 클릭(clicking)하기 전에, mZone Poker 타겟(target)을 선택 해제(Deselect)한다.

     

    다음으로(next), mZone Poker UITests에서 mZone_Poker_UITests.swift를 연다. setUp()tearDown()을 모두 제거한 다음, testExample()의 내용(contents)을 다음으로 바꾼다(replace):

    let app = XCUIApplication()
    setupSnapshot(app)
    app.launch()
    //snapshots을 생성하고, 앱을 실행하도록 test를 설정한다.
    
    let chipCountTextField = app.textFields["chip count"]
    chipCountTextField.tap()
    chipCountTextField.typeText("10")
    //Chip Count 텍스트 필드(Storyboard에서 "chip count"로 설정된 accessibility identifier)를 tap하고 10을 입력한다.
    
    let bigBlindTextField = app.textFields["big blind"]
    bigBlindTextField.tap()
    bigBlindTextField.typeText("100")
    //Big Blind 텍스트 필드를 tap하고 100을 입력한다.
    
    snapshot("01UserEntries")    
    //app이 어떻게 보이는지 보여주는 snapshot을 01UserEntries 이름으로 생성한다.
    
    app.buttons["what should i do"].tap()
    snapshot("02Suggestion")   
    //What Should I Do? 버튼을 tap하고 screenshot을 02Suggestion 이름으로 생성하여, resulting alert을 캡쳐한다.

    다음으로 mZone Poker UITests 구성표(scheme)를 생성하려면, 실행 및 중지(run and stop) 버튼(buttons) 바로 오른쪽(immediately to the right)에 있는 버튼(button)을 클릭(click)하고 Manage Schemes...를 선택(select)한다. mZone Poker UITests 옆(next)의 Show를 선택(select)하고, 두(both) 대상(targets) 옆에 있는 Shared를 선택(select)하여 fastlane 접근(access) 권한을 부여(grant)한다. 그런 다음 mZone Poker UITests 행(row)을 클릭(click)하고 Edit...를 누른다.

    Note: 구성표(scheme)가 나타나지 않으면 +를 클릭(click)하고, Target 드롭 다운(drop-down)에서 mZone Poker UITests를 선택(select)한다.

    구성표(scheme) 편집기(editor)의 왼쪽 메뉴(left-hand menu)에서 Build를 클릭(click)한다. 그런 다음 mZone Poker UITests 대상(target) 옆에 있는 TestRun 옵션(options)을 선택하고 Close를 클릭(click)하여 변경 사항(changes)을 저장한다.

     

    Xcode에서 나와(leave) Fastfile을 열고, create_app lane 아래에 다음을 추가한다:

    desc "Take screenshots"
    lane :screenshot do
      snapshot
    end

    screenshot lane은 snapshot을 사용하여, Snapfile의 설정(settings)에 따라 스크린샷(screenshots)을 찍는다.

    Fastfile을 저장(save)하고, 터미널(Terminal)로 돌아가 다음을 입력(enter)한다.

    bundle exec fastlane screenshot

    이제 다른 작업을 수행하지 않아도 스크린샷(screenshots)이 캡처(captured)된다. 귀찮은(grunt) 일을 건너뛰는(skipping) 기쁨을 만끽한다(bask in).

    스냅샷(snapshot)이 완료(completes)되면, 스크린샷(screenshots)의 HTML 미리보기(preview)가 자동으로(automatically) 열린다.

     

    Note: snapshotSnapfile에 나열된(listed in) 시뮬레이터(simulators)에 접근(access)할 수 있어야 한다. 목록(list)에서 하나 이상의 기기(devices)가 누락(missing)된 경우, Window ▸ Devices로 이동하여 Xcode에 추가한다. 그런 다음 + 를 클릭(click)하여 새 시뮬레이터(simulators)를 추가한다.
    ambiguous simulator names에 대한 경고(warnings)가 표시되면, 중복(duplicate) 시뮬레이터(simulators)를 삭제(delete)하거나 시뮬레이터(simulator) 이름을 Snapfile의 이름과 일치(match)하도록 변경(change)해야 할 수도 있다.

    단 한 번의 명령(command)으로 영어와 프랑스어로 된 모든 기기(device)의 스크린샷(screenshots)을 볼 수 있다. 이보다 더 나아질 수는 없을 것이다(it doesn’t get better than that).

     

    Creating the IPA File

    앱(app)을 빌드(building)하고 업로드(uploading)하는 것도 시간이 많이 걸리는(time-consuming) 과정(process)이 될 수 있다. 하지만, fastlane의 gym 도구(tool)로 이를 작업할 수 있다.

    Note: Xcode의 mZone Poker 타겟(target)에서 번들 식별자(bundle identifier)와 서명 ID(signing identity)를 설정(signing identity)했는지 확인(be sure)한다.

    터미널(Terminal)에서 다음을 실행(run)한다:

    fastlane gym init

    Gymfile이 생성된다.

    Gymfile을 열고, 내용(contents)을 다음으로 바꾼다(replace):

    scheme("mZone Poker")
    # scheme를 지정한다.
    output_directory("./fastlane/builds")
    # fastlane이 .ipa 앱 바이너리 파일을 저정할 위치를 지정한다.
    include_bitcode(false)
    # build에서 bitcode를 제외한다. bitcode를 사용하면 앱을 최적화할 수 있지만, 지금은 이를 제외하여 build 속도를 높인다.
    include_symbols(false)
    # build에서 symbols을 제외한다. symbols을 포함하면 debug 정보에 접근할 수 있지만, build 속도를 높이기 위해 일단 제외한다.
    export_xcargs("-allowProvisioningUpdates")
    # Xcode가 automatic provisioning을 사용할 수 있도록 허용한다.

    Fastfile을 열고, screenshot lane 아래에 다음을 추가한다:

    desc "Create ipa"
    lane :build do
      enable_automatic_code_signing
      # Xcode에서 automatic provisioning을 사용한다.
      increment_build_number
      # build number를 1증가 시킨다. 
      # App Store Connect의 업로드 요구사항으로, 각 build number가 고유해야 한다.
      gym
      # 서명된 .ipa 파일을 생성한다.
    end

    Fastfile을 저장(save)한 다음, 터미널(Terminal)에서 build를 실행(run)한다:

    bundle exec fastlane build

    fastlane이 인증서(certificates)에 접근(access)하기 위해(in order for), 키 체인(keychain) 암호(password)를 입력(enter)하라는 메시지가 표시(prompted)되면 입력(enter)한다. 동일한 권한(permission)에 반복적으로(repeatedly) 입력해 승인(grant)하지 않으려면, 항상 허용(Allow Always)을 선택(select)한다. build가 성공적으로(successfully) 완료(completes)되면, 서명된(signed) .ipafastlane/builds에 나타난다(appear).

     

    Uploading to App Store Connect

    스크린샷(screenshots), 메타 데이터(metadata), .ipa 파일(file)을 App Store Connect에 업로드(upload)하려면 deliver을 사용한다.

    먼저, Deliverfile의 내용(contents)을 다음으로 바꾼다(replace):

    price_tier(0)
    # price tier을 0(무료)으로 설정한다.
    submission_information({
        export_compliance_encryption_updated: false,
        export_compliance_uses_encryption: false,
        content_rights_contains_third_party_content: false,
        add_id_info_uses_idfa: false
    })
    # review를 수동으로 제출할 때 제출해야 하는 Apple의 질문에 대한 답변을 설정한다.
    app_rating_config_path("./fastlane/metadata/app_store_rating_config.json")
    # app rating의 configuration 위치를 지정한다.
    ipa("./fastlane/builds/mZone Poker.ipa")
    # .ipa 파일의 위치를 지정한다.
    submit_for_review(true)
    # review 제출을 자동으로 하려면, submit_for_review를 true로 설정한다.
    automatic_release(false)
    # review 통과 이후, app을 수동으로 제출하려면 automatic_release을 false로 설정한다.

    Fastfile을 연다. build lane 뒤에 다음을 추가한다:

    desc "Upload to App Store"
    lane :upload do
      deliver
    end

    그런 다음 fastlane이 메타 데이터(metadata) 미리보기(preview)를 생성하게 하려면, 터미널(Terminal)을 열고 다음을 입력(enter)한다:

    bundle exec fastlane upload

    모든 것이 제대로 설정되었다면, 터미널(Terminal)에 y를 입력(type)하여 승인(approve)한다.

    lane이 완료(completes)되면, App Store Connect에 로그인(log in)한다. 스크린샷(screenshots), 메타 데이터(metadata), 빌드(build)가 있어야 하며, 심사를 기다리는 중(waiting for review) 상태가 되어 있어야 한다.

     

    Putting It All Together

    이제 앱 생성(creating your app), 스크린샷 생성(taking screenshots), 빌드(building), 업로드(uploading) 라는 별도(separate)의 lanes이 있다. 하나씩(one-by-one) 호출(call)할 수 있지만, 모든 것을 한 번에 수행하는 하나의 명령(command)이 있다면 더 좋을 것이다.

    Fastfile을 연다. upload 레인(lane) 뒤에 다음을 추가한다:

    desc "Create app, take screenshots, build and upload to App Store"
    lane :do_everything do
      create_app
      screenshot
      build
      upload
    end

    do_everything적절하게 모든 것을 처리한다.

    또한(furthermore) lane을 완전하게 손을 쓰지 않고 이용할 수 있게(hands-free) 하려면, Deliverfile을 열고 맨 아래에 다음을 추가한다:

    force(true)

    이 명령을 사용하면, fastlane이 스크린샷(screenshot)과 메타 데이터(metadata)에서 승인(approval)을 건너 뛴다(skip).

    fastlane이 이 모든 과중한 작업(heavy lifting)을 수행하도록 하려면, 다음을 실행(run)한다:

    bundle exec fastlane do_everything

     

    Supporting Multiple Targets

    mZone_Sample_Project에는 또 다른 Multiple_Targets 폴더(folder)가 있다. Xcode에서 Multiple_Targets/mZone-2/mZone Poker.xcodeproj를 연다. 이 프로젝트(project)는 mZone Poker PromZone Poker Pro UITest라는 두 개의 새로운 대상(targets)을 제외(except)하고는 첫 번째 프로젝트(project)와 매우 유사하다.

    mZone Poker와 mZone Poker Pro의 실행을 전환(switch)하려면, 실행 및 중지(Run and Stop) 버튼(buttons) 바로 오른쪽(immediately to the right)에 있는 버튼(button)을 클릭(click)한 다음, 실행(run)하려는 앱(app)의 구성표(scheme)를 선택(select)한다.

    실행할 앱의 scheme를 선택한다.

     

    mZone Poker Pro를 빌드(build)하고 실행(run)한다. mZone Poker와 거의(almost) 동일(identical)하지만, 더 자세한(detailed) 제안(suggestions)을 제공(returns)한다.

    mZone Poker / mZone Poker Pro

     

    General 페이지(page)에서 mZone Poker의 번들 식별자(bundle identifier)를 이전에 생성한 식별자로 설정한다.

    그런 다음, mZone Poker Pro의 임시(tentative) 새 번들(bundle) ID를 설정(set)한다. 예를 들면 다음과 같다:

    com.mZone-Poker-Pro.[Insert your email address minus “@”  and “.”]

    이제 Finder로 돌아간다(return). mZone에서 Gemfile과 fastlane 디렉토리(directory)를 복사(copy)하여 mZone-2에 붙여 넣는다(paste). 그런 다음 mZone-2/fastlane/SnapshotHelper.swift를 새 프로젝트(project)로 드래그(drag)한다. 이 파일을 추가하기 위한 옵션 선택(options) 창(window)이 나타나면(appears), 다음을 선택(select)한다:

    • Copy items if needed
    • Create groups
    • mZone Poker UITests
    • mZone Poker Pro UITests

    그런 다음, Finish를 클릭(click)한다.

     

    Setting Up Multiple Environments

    환경(environment, .env) 파일(files)은 앱(app)이 실행(execution) 중에 다양하게 접근(access)할 수 있는 구성(configuration) 설정(settings)을 보유(hold)한다. 이 프로젝트(project)에서는 각 앱(app) 대상(target)에 대해 하나씩, 총 두 개의 환경(environments)을 만든다.

    좋아하는 텍스트 편집기(favorite text editor)를 열고, 스마트 따옴표(smart quotes)를 비활성화(disable)한 후 다음을 입력한다:

    SCHEME = "mZone Poker"
    TEST_SCHEME = "mZone Poker UITests"
    BUNDLE_IDENTIFIER = "[[YOUR UNIQUE BUNDLE IDENTIFIER]]"
    APP_NAME = "[[YOUR UNIQUE APP NAME]]"

    이 환경(environment)에는 mZone Poker의 환경 구성표(environment scheme), 테스트 구성표(test scheme), 번들 식별자(bundle identifier), 앱 이름(app name)이 있다. [[YOUR UNIQUE BUNDLE IDENTIFIER]]를 mZone Poker의 번들(bundle) ID로, [[YOUR UNIQUE APP NAME]]을 앱(app)의 고유한(unique) 이름으로 바꾼다.

    파일을 mZone-2/fastlane.env.mZone_Poker(파일 접미사 없음)로 저장(save)한다. .env 변수(variables)는 기본적(default)으로 숨긴 파일(hidden files)이므로, Finder에서 .env.mZone_Poker를 볼 수 없는 경우 Shift-Command-. 을 누르면 숨긴 파일(hidden files)을 볼 수(visible) 있다.

    마찬가지로 다음을 포함(containing)하는 두 번째 파일을 만든다:

    SCHEME = "mZone Poker Pro"
    TEST_SCHEME = "mZone Poker Pro UITests"
    BUNDLE_IDENTIFIER = "[[YOUR UNIQUE BUNDLE IDENTIFIER]]"
    APP_NAME = "[[YOUR UNIQUE APP NAME]]"

    [[YOUR UNIQUE BUNDLE IDENTIFIER]]을 mZone Poker Pro의 현재(current) 번들(bundle) ID를 교체(replace)한다. 그런 다음 임시(tentative) 고유(unique) 앱(app) 이름을 만든다. 예를 들면 다음과 같다:

    mZone Poker Pro [Insert your email address minus “@”  and “.”]

    앱 이름(app names)은 30자(characters)를 넘을 수 없으므로, 필요한 경우 잘라낸다(truncate).

    파일(file)을 같은 디렉토리(directory)에 .env.mZone_Poker_Pro로 저장(save)한다.

    이제 구성표(schemes)를 전환(switch)할 때 ,변수(variables)를 사용하여 현재(current) 설정(current)에 접근(access)할 수 있다.

    우선 Appfile을 열고 app_identifier 행(line)의 주석을 제거(uncomment)하고 다음을:

    app_identifier("[[APP_IDENTIFIER]]")

    아래와 같이 바꾼다(replace):

    app_identifier(ENV['BUNDLE_IDENTIFIER'])

    “ENV [‘BUNDLE_IDENTIFIER’]”는 현재(current) 환경(environment)으로 설정(set)한 번들(bundle) ID를 가져 오도록(grab), fastlane에 지시(tells)한다.

    Deliverfile에서 .ipa 행(line)을 다음으로 바꾼다(replace):

    ipa("./fastlane/builds/#{ENV['APP_NAME']}.ipa")

    Gymfile에서 scheme 행(line)을 다음으로 바꾼다(replace):

    scheme(ENV['SCHEME'])

    Snapfile에서 scheme와 output_directory 행(line)을 각각(respectively):

    scheme(ENV['TEST_SCHEME'])

    와:

    output_directory "./fastlane/screenshots/#{ENV['SCHEME']}"

    으로 바꾼다(replace).

    마지막으로(lastly), 새로운 metadata 디렉토리(directory)로 돌아간다(return). 모든 내용(contents)을 선택(select)하여, mZone Poker라는 새 폴더(folder)에 넣는다.

     

    그런 다음 해당 폴더(folder)를 복제(duplicate)하고, 이름을 mZone Poker Pro으로 지정한다.

     

    mZone Poker Pro/en-US/name.txtmZone Poker Pro/fr-FR/name.txt의 내용(contents)을 새 앱(app)의 이름으로 변경(change)한다. 지금은 단순성(simplicity)을 위해(sake), 다른 모든 메타 데이터(metadata)를 동일하게 유지(keep)한다.

    이제 두 번째 대상(target)에 대한 모든 명령(commands)을 실행하려면 다음을 입력(enter)한다:

    bundle exec fastlane do_everything --env mZone_Poker_Pro

    .env.mZone_Poker_Pro의 변수(variables)를 사용하여, do_everything을 실행(run)한다.

    그러나 한 번에 모든 대상(targets)에 대해, 모든 명령(commands)을 실행(run)해야 할 때도 있다.

    Fastfile을 연다. do_everything 아래에 다음을 추가한다:

    def execute_for_all_envs
      schemeList = Dir.glob(".env.*")
      # 현재 directory의 .env. 파일을 array에 넣는다.
      schemeList.each do |file|
      # .env 파일을 loop한다.
        Dotenv.overload(file)
        # 현재 .env 파일로 ENV를 오버로드 한다.
        yield
        # execute_for_all_envs 호출 후, block을 실행한다.
      end
    end

    그런 다음 do_everything에서 execute_for_all_envs를 호출(call)하려면 do_everything의 내용(content)을 다음으로 바꾼다(replace):

    if ENV['SCHEME'] != nil
      create_app
      screenshot
      build
      upload
    else
      execute_for_all_envs{ do_everything }
    end

    이제 command line에 환경(environment)을 지정(specify)하지 않으면, ENV [‘SCHEME’] == nil이 실행되므로 execute_for_all_envs가 실행(runs)된다. execute_for_all_envs는 ENV를 첫 번째 환경(environment)으로 설정(sets)하고, 호출 블록(calling block)으로 돌아간(returns) 다음 do_everything을 다시 실행(re-runs)한다.

    do_everything이 해당 환경(environment)에 대한 모든 작업을 수행한 후, execute_for_all_envs의 반복(loop)는 계속되며 다음 환경(environment)을 반환(returns)한다.

    다 됐다(that’s it).

    이제 다음을 실행(run)할 수 있다:

    bundle exec fastlane do_everything

    편안히 앉아(sit back) 휴식(relax)을 취하는 동안, 두 대상(targets)에 대한 모든 과중한 작업(heavy lifting)을 fastlane이 대신해 준다.

     

    주의(caution): fastlane을 사용하기 이전(pre-fastlane)과 비교해(compared to), 너무 많은 시간이 생긴 것(much time on your hands)같아 이상하게(weird) 느껴질 수도 있지만, 믿어라. 금방 익숙해 질 것이다.

     

    Where to Go From Here?

    튜토리얼(tutorial) 상단(top) 또는 하단(bottom)에 있는 Download Materials 버튼(button)을 사용하여, mZone-FinalmZone-Final-2를 확인하고 최종 프로젝트(final projects)를 비교(compared)할 수 있다.

    또한 fastlane은 TestFlight 제출(submission) 및 수 많은(a ton of) 통합(integrations)도 지원(supports)한다. lanes을 사용자 정의(customize)하여, Slack에 실시간(real-time) 피드백(feedback)을 제공하고 Jira 보드(boards)와 상호 작용(interact)하는 등의 작업을 수행할 수 있다. 자세한 내용은 fastlane 공식(official) 웹 사이트(website)를 방문하여 확인한다.

    질문(questions)이나 의견(comments)이 있다면, 아래의 포럼(forum)에 참여하여 자유롭게 토론(discussion)할 수 있다.

Designed by Tistory.