Computer >> 컴퓨터 >  >> 스마트폰 >> iPhone

SwiftUI로 비동기 GET REST API 호출하기: 초보자를 위한 ICNDB 예제 가이드

이 초보자용 튜토리얼에서는 유명한 Internet Chuck Norris DataBase(ICNDB)를 예제로 활용해 SwiftUI에서 API를 호출하는 기본기를 배워봅니다. Swift와 SwiftUI만으로 농담 데이터를 빠르고 간단하게 화면에 표시할 수 있습니다.

크로스 플랫폼 프레임워크인 SwiftUI는 iOS, iPadOS, macOS, watchOS, App Clips, tvOS 어디에서든 완전히 동일한 코드를 사용할 수 있게 해줍니다. 다른 접근 방식으로는 불가능했던 일이죠.

여기에 Swift 5.5에서 도입된 async-await까지 활용하면, UI 스레드를 얼리지 않으면서 버튼 클릭 한 번으로 비동기 네트워크 호출을 처리할 수 있습니다. async-await는 iOS 15.0 이상이 설치된 아이폰 등 비교적 최신 운영체제에서 지원됩니다.

먼저 필요한 코드 변경 사항을 소개하고, 이어지는 섹션에서는 초보자도 전체 흐름을 이해할 수 있도록 코드를 간단히 분석해 보겠습니다.

SwiftUI로 비동기 GET REST API 호출하기: 초보자를 위한 ICNDB 예제 가이드
코드가 실행된 tvOS 앱 화면. 버튼을 클릭하면 농담을 가져옵니다.

Swift와 SwiftUI로 API 호출하는 방법

먼저 Xcode를 설치할 수 있는 Mac이 필요합니다. 설치가 끝나면 Xcode를 열고 새 프로젝트를 생성한 뒤, iOS, macOS, tvOS 또는 watchOS 중 원하는 플랫폼의 'App'을 선택하세요.

ContentView

기존 ContentView SwiftUI 파일에 버튼을 추가하고, @State 변수를 사용해 ICNDB API로부터 농담이 반환될 때 화면의 텍스트를 자동으로 갱신하도록 수정합니다:

import Foundation
import SwiftUI
struct ContentView: View {
    @State private var joke: String = ""
    var body: some View {
        Text(joke)
        Button {
            Task {
                let (data, _) = try await URLSession.shared.data(from: URL(string:"https://api.chucknorris.io/jokes/random")!)
                let decodedResponse = try? JSONDecoder().decode(Joke.self, from: data)
                joke = decodedResponse?.value ?? ""
            }
        } label: {
            Text("Fetch Joke")
        }
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
struct Joke: Codable {
    let value: String
}

농담 가져오기!

빌드/실행 버튼을 누르면 앞서 선택한 플랫폼으로 앱이 빌드됩니다:

SwiftUI로 비동기 GET REST API 호출하기: 초보자를 위한 ICNDB 예제 가이드
동일한 코드로 실행된 watchOS, macOS, iOS 앱의 스크린샷

코드 분석

랜덤 농담 URL에 직접 접속해 보면 데이터가 JSON 형식으로 제공되는 것을 확인할 수 있습니다. 이 데이터를 복사해서 JSON Linter 도구로 구조를 살펴보면, Joke 객체에 어떤 프로퍼티가 필요한지 쉽게 파악할 수 있습니다.

이를 바탕으로 위의 코드를 작성하게 됩니다. 핵심은 Codable 프로토콜(다른 언어의 인터페이스와 유사)입니다. Codable을 사용하면 JSON 데이터 객체를 실제 Swift 클래스나 구조체로 변환할 수 있고, 저장하고 싶은 값에 대한 프로퍼티(여기서는 value)를 정의하면 됩니다.

JSONDecoder는 Codable 객체를 활용해 JSON 문자열을 파싱하는 역할을 담당합니다. 앱 실행 시 로드되는 첫 화면의 이름이 어떤 플랫폼에서든 ContentView로 동일하기 때문에, 이 코드는 플랫폼에 관계없이 그대로 작동합니다.

App Clips

App Clips는 Apple이 선보인 새로운 방식으로, 'App Clip Code'를 통해 앱스토어에서 전체 앱을 다운로드하지 않고도 네이티브 앱 기능을 바로 사용할 수 있게 해줍니다.

App Clips는 일반 iOS 앱과 거의 같게 작동합니다. 차이점이라면 별도의 새 프로젝트를 만들 필요가 없다는 것뿐입니다. Xcode에서 기존 iOS 앱을 연 상태에서 File → New → Target → iOS → App Clip 경로로 이동해, 기존 앱에 타겟으로 추가하기만 하면 됩니다.

아이폰/아이패드 위젯이 궁금하다면? 위젯에는 애니메이션이 적용되지 않습니다. 따라서 버튼을 눌러도 해당 앱을 열어줄 뿐, 외부 API를 호출해 텍스트를 독립적으로 업데이트하는 것은 불가능합니다.

마무리

이번 글에서는 SwiftUI에서 가장 간단한 방식으로 RESTful GET API를 호출하는 방법을 배웠습니다!

궁금한 점이 있다면 언제든 질문해 주세요. 저 역시 다른 글을 참고해 이 내용을 익힌 뒤, 더 단순화해서 정리해 보았습니다. 더 자세한 설명과 코드를 확장하는 방법이 궁금하다면 아래 글도 함께 확인해 보세요:

async/await in SwiftUI — Audrey Tam (raywenderlich.com): SwiftUI 앱을 새로운 Swift 동시성 모델로 전환하고, 화려한 문법 뒤에 숨은 원리까지 파헤치는 심화 튜토리얼입니다.