관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 3. GraphQL - Apollo 모델 생성 (generate model) 본문

iOS framework

[iOS - swift] 3. GraphQL - Apollo 모델 생성 (generate model)

jake-kim 2022. 3. 2. 22:53

1. GraphQL - 개념

2. GraphQL - Apollo 사용 준비

3. GraphQL - Apollo 모델 생성 (generate model)

4. GraphQL - Apollo의 request pipeline, Interceptor, token, header

5. GraphQL - Apollo의 fetch 예제  (Pagination)

GraphQL 튜토리얼 - 예제에 사용할 Query 획득

query Query {
  launches {
    cursor
  }
}
  • Response

  • Qeury name은 아무거나 작성해도 무관
    • Query -> MyQuery로 변경

위에서 얻은 query를 Xcode에 넣기

  • Empty 파일 생성
    • 파일 이름은 위에서 정의한 MyQuery와 동일하게 설정 (안해줄 경우, runtime error 발생)
    • {QueryName}.graphql

  • 위에서 얻은 query 복붙
query MyQuery {
  launches {
    cursor
  }
}

예제에 사용할 schema.json 획득

  • schema.json이란?
    • 위에서 작성한 query에 대한 내부 스키마 SDL(Storage Definition Language) 역할
      * 내부 스키마(SDL): 시스템 프로그래머나 시스템 설계짜가 보는 관점의 데이터베이스의 물리적인 구조를 정의한 형태
  • schema.json 다운로드

  • SDL 클릭

  • Raw 버튼 옆에 아래 화살표를 클릭 > json을 선택하여 파일 다운
    • 이름을 schema(디폴트 상태)로 다운로드

다운받은 schema

* 이름을 schema.json으로 하는 이유: 아래처럼, Build Phase에 추가한 스크립트에서 localSchemaFile이름을 "schema.json"으로 설정했기 때문

  • schema.json 파일을 받는 다른 방법
    • Build Phases에 다운로드하는 명령어 기입
    • 아래 주석 처리된 부분을 풀고 다시 실행하면, finder에서 schema.json파일이 생성된 것을 확인 가능
# Don't run this during index builds
if [ $ACTION = "indexbuild" ]; then exit 0; fi

SCRIPT_PATH="${PODS_ROOT}/Apollo/scripts"

# "${SCRIPT_PATH}"/run-bundled-codegen.sh schema:download --endpoint="https://apollo-fullstack-tutorial.herokuapp.com/graphql" ExApollo/schema.json

cd "${SRCROOT}/${TARGET_NAME}"
"${SCRIPT_PATH}"/run-bundled-codegen.sh codegen:generate --target=swift --includes=./**/*.graphql --localSchemaFile="schema.json" API.swift

schema.json파일을 받아오는 코드

  • 이전에 만든 .graphql파일과 같은 위치에 있도록 schema.json 파일 복사 붙여넣기

  • cmd + B를 눌러서 빌드 > 빌드 성공 (API.swift 파일 생성)
  • schema 파일 > 오른쪽 마우스 클릭 > show in finder 클릭

  • 생성된 API.swift파일 확인

  • API.swift파일을 Xcode에 복붙

  • 자동으로 생성된 API.swift파일을 보면, 아래와 같이 이전에 입력했던 쿼리형식이 반영되어 있는것을 확인

Request 테스트

 

  • apollo 싱글톤으로 사용하기 위해 Network 클래스 생성
    • 아래처럼 싱글톤으로 사용하지 않으면 sessionInvalidated에러 발생하므로 주의
// singletown으로 사용하지 않으면 sessionInvalidated에러 발생
let apollo = ApolloClient(url: URL(string: "https://apollo-fullstack-tutorial.herokuapp.com/graphql")!)
apollo.fetch(query: MyQueryQuery()) { result in
  switch result {
  case .success(let data):
    print(data.data?.launches.cursor)
  case .failure(let error):
    print(error) // sessionInvalidated
  }
}
  • singletown으로 사용
class Network {
  static let shared = Network()

  private(set) lazy var apollo = ApolloClient(url: URL(string: "https://apollo-fullstack-tutorial.herokuapp.com/graphql")!)
}

Network.shared.apollo.fetch(query: MyQueryQuery()) { result in
  switch result {
  case .success(let data):
    print(data.data?.launches.cursor) // Optional("1581951955")
  case .failure(let error):
    print(error)
  }
}

generate에 NameSpace 적용 방법

  • 아래처럼 MyAPI라는 namespace를 주는 방법
    • Types.graphql이라는 곳에 MyAPI enum 타입이 생기고 나머지는 extension으로 들어가는 형태

  • Build Phases에서 만든 스크립트를 수정
    • --namespace=MyAPI 추가
    • API.swift파일을 지우고 자동 생성될 경로만 표시 "API"
cd "${SRCROOT}/${TARGET_NAME}"
"${SCRIPT_PATH}"/run-bundled-codegen.sh codegen:generate --target=swift --namespace=MyAPI --includes=./**/*.graphql --localSchemaFile="schema.json" API

* 스크립트 전체 코드

# Don't run this during index builds
if [ $ACTION = "indexbuild" ]; then exit 0; fi

SCRIPT_PATH="${PODS_ROOT}/Apollo/scripts"

#"${SCRIPT_PATH}"/run-bundled-codegen.sh schema:download --endpoint="https://apollo-fullstack-tutorial.herokuapp.com/graphql" ExApollo/schema.json

cd "${SRCROOT}/${TARGET_NAME}"
"${SCRIPT_PATH}"/run-bundled-codegen.sh codegen:generate --target=swift --namespace=MyAPI --includes=./**/*.graphql --localSchemaFile="schema.json" API
  • 위 코드 입력 후 실행하면 finder에 코드 생성

* 전체 코드: https://github.com/JK0369/ExApollo

 

* 참고

https://www.apollographql.com/docs/ios/tutorial/tutorial-execute-query/

https://studio.apollographql.com/sandbox/schema/sdl

https://www.apollographql.com/docs/ios/downloading-schema/

https://www.apollographql.com/docs/ios/swift-scripting/

Comments