다들 로또 좋아하시나요?
오랜만에 돼지꿈을 생생하게 경험했는데요! 🐷🐽
이번주 기대가 됩니다.
자 오늘은 SwiftUI와 Alamofire + ObservableObject를 이용하여
로또 API 조회하는 부분을 간단하게 구현해 보겠습니다.
우선 Alamofire 라이브러리를 추가합니다.
[iOS/Swift] 외부 라이브러리 관리 - CocoaPods, Swift Package Manager(SPM)
오늘은 iOS 프로젝트 외부 라이브러리 관리 또는 프로젝트 종속성을 관리하기 위한 두 가지 도구를 소개하려고 합니다. 💁♂️💁♂️ CocoaPods(코코아팟) / Swift PackageManager(SPM) 두둥! 왜 하필
salmonpack.tistory.com
반드시 필요한 준비물
바로 데이터를 조회할 REST Api입니다.
저는 오늘 간단하게 사용 가능한 로또 당첨 번호 조회 API를 사용해 보겠습니다.
(이번주 당첨되면 뭐부터 해볼까 고민되네요 🤔🤔🤔)
간단하게 제가 사용할 API에 대하여 알려드리겠습니다.
[ 로또 당첨번호 조회 API 예시 ]
www.dhlottery.co.kr/common.do?method=getLottoNumber&drwNo=1110
"www.dhlottery.co.kr/common.do"를 BaseUrl로 두고
@GET 방식을 통하여
method = "getLottoNumber"
drwNo = "\(조회하고자 하는 회차 번호)"
[ 로또 당첨번호 조회 Response 예시 ]
{"totSellamnt":81032551000,"returnValue":"success","drwNoDate":"2019-06-01","firstWinamnt":4872108844,"drwtNo6":25,"drwtNo4":21,"firstPrzwnerCo":4,"drwtNo5":22,"bnusNo":24,"firstAccumamnt":19488435376,"drwNo":861,"drwtNo2":17,"drwtNo3":19,"drwtNo1":11}
자 준비는 끝났습니다.
REST API 통신을 통하여 성공적인 데이터를 조회하려면
Codable Struct를 생성해야 합니다.
저는 LotteryData라는 이름으로 생성했습니다.
// LotteryData.swift
import Foundation
struct LotteryData : Codable {
var totSellamnt: Double
var firstWinamnt: Double
var firstAccumamnt: Double
var firstPrzwnerCo: Int
var returnValue: String
var drwNoDate: String
var drwNo: Int
var drwtNo1: Int
var drwtNo2: Int
var drwtNo3: Int
var drwtNo4: Int
var drwtNo5: Int
var drwtNo6: Int
var bnusNo: Int
}
여기서 SwiftUI에서는 'Identifiable' 프로토콜이 자주 사용된다고 들었는데
이 부분 관련해서는 조금 더 학습 후 완벽하게 사용 가능해지면 다시 정리해 봐야겠습니다.
(메모 >> Codable, Identifiable )
이후 Alamofire request 부분을 작성합니다.
// LotteryViewModel.swift
import Foundation
import Alamofire
class LotteryViewModel: ObservableObject {
@Published var lotteryData: LotteryData? = nil
@Published var lotteryNum: String = ""
func getLotteryData(drwNo: String) {
let url = "https://www.dhlottery.co.kr/common.do"
guard let sessionUrl = URL(string: url) else {
print("Invalid URL")
return
}
let param: [String: Any] = [
"method" : "getLottoNumber",
"drwNo" : drwNo
]
AF.request(sessionUrl, method: .get, parameters: param, encoding: URLEncoding.default, headers: ["Content-Type":"application/json", "Accept":"application/json"])
.validate(statusCode: 200..<300)
.responseDecodable(of: LotteryData.self) { response in
switch response.result {
case .success(let data) :
self.lotteryData = data
self.lotteryNum = "\(data.drwtNo1) \(data.drwtNo2) \(data.drwtNo3) \(data.drwtNo4) \(data.drwtNo5) \(data.drwtNo6)"
print(self.lotteryData ?? "nil data")
case .failure(let error) :
print(error)
}
}
}
}
저는 아직 Swift와 친해지고 있는 단계이기 때문에
Alamofire를 아주 간단하게 사용했지만
Alamofire와 Combine의 조합으로 네트워크 모듈을 활용하는 것 같습니다.
(메모 >> Alamofire & Combine )
Swift에서 ObservableObject를 사용할 때 3가지를 구현해야 합니다.
우선 위의 소스에서도 확인 가능한
protocol ObservableObject를 클래스가 채택해야 합니다.
채택 후 @Published로 선언된 속성들의 관찰을 시작하고
@Published 속성들이 업데이트되면 관찰 대상에게 전달합니다.
// ContentView.swift
import SwiftUI
struct ContentView: View {
@ObservedObject var lotteryViewModel = LotteryViewModel()
@State private var inputLotteryDrwNo = ""
var body: some View {
VStack{
TextField("Input DrwNo", text: $inputLotteryDrwNo)
Text("\(lotteryViewModel.lotteryNum)")
.font(.body)
.foregroundColor(.yellow)
.background(.green)
Button {
lotteryViewModel.getLotteryData(drwNo: inputLotteryDrwNo)
} label: {
Text("Click get Lottery")
}
}
.padding()
}
}
#Preview {
ContentView()
}
다음으로는 @ObservedObject
@ObservedObject는 ObservableObject를 구독하고 있으면서
업데이트될 때마다 뷰를 갱신시킵니다.
이렇게 완성된 결과를 보여드리겠습니다.
(절대 귀찮아서는 아니고 저의 개인적인 학습용으로 만들어 퀄리티가 심각합니다...)
여기까지 저의 긴 글을 읽어주셔서 감사합니다.
제가 습관적으로 코딩을 하는 그날까지 습관적으로 코딩을 하기 위해 글 작성을 꾸준하게 해보겠습니다.
'iOS > 스터디 노트' 카테고리의 다른 글
[SwiftUI] SwiftUI 맛보기 + (VStack, HStack, ZStack) (0) | 2024.03.13 |
---|---|
[iOS/Swift] 데이터 저장, Database - Realm/RealmStudio (0) | 2023.05.11 |
[iOS/Swift] 외부 라이브러리 관리 - CocoaPods, Swift Package Manager(SPM) (2) | 2023.05.09 |
[Mac Terminal] 간지나는 터미널 커스텀 - Homebrew, iTerm2, oh my zsh (11) | 2023.05.01 |
[Xcode] 앱 빌드, 내 아이폰에서 실행 (1) | 2022.09.01 |
최근댓글