import UIKit
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
struct LottoAPIResponse: Codable {
let page: Int64
let perPage: Int64
let totalCount: Int64
let currentCount: Int64
let matchCount: Int64
let data: [LottoStore]
}
struct APIError: Codable {
let code: Int
let msg: String
}
struct LottoStore: Codable {
let 번호: Int
let 상호: String
let 도로명주소: String
let 지번주소: String
}
class LottoAPITest {
static func testFetchLottoStores() {
let baseURL = "https://api.odcloud.kr/api"
let path = "/15086355/v1/uddi:ef7ca84b-c2bc-404a-9743-85752073b61b"
let serviceKey = "S4Z3xung5wpu6TPz1bUEfRu8ln55RTZu4rwIDF61MPCFNDzcfOFIO7N2AFFgrCWLY2DooC%2B0Soo4pSsQ0U%2BIWg%3D%3D"
let urlString = "\(baseURL)\(path)?page=1&perPage=10&serviceKey=\(serviceKey)"
guard let url = URL(string: urlString) else {
print("❌ URL 생성 실패")
return
}
print("🔍 요청 URL: \(url.absoluteString)")
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print("❌ 네트워크 에러: \(error.localizedDescription)")
return
}
guard let httpResponse = response as? HTTPURLResponse else {
print("❌ HTTP 응답이 아님")
return
}
print("📡 HTTP 상태 코드: \(httpResponse.statusCode)")
guard let data = data else {
print("❌ 데이터 없음")
return
}
if let jsonString = String(data: data, encoding: .utf8) {
print("📦 수신된 JSON 데이터:")
print(jsonString)
}
do {
if httpResponse.statusCode != 200 {
let errorResponse = try JSONDecoder().decode(APIError.self, from: data)
print("❌ API 에러: 코드=\(errorResponse.code), 메시지=\(errorResponse.msg)")
} else {
let response = try JSONDecoder().decode(LottoAPIResponse.self, from: data)
print("\n✅ 파싱 성공!")
print("📊 총 데이터 수: \(response.totalCount)")
print("📑 현재 페이지: \(response.page)")
print("📝 페이지당 항목 수: \(response.perPage)")
if let firstStore = response.data.first {
print("\n📍 첫 번째 판매점 정보:")
print("번호: \(firstStore.번호)")
print("상호: \(firstStore.상호)")
print("도로명주소: \(firstStore.도로명주소)")
print("지번주소: \(firstStore.지번주소)")
}
}
} catch {
print("❌ 파싱 에러: \(error)")
if let decodingError = error as? DecodingError {
switch decodingError {
case .dataCorrupted(let context):
print("Data corrupted: \(context.debugDescription)")
case .keyNotFound(let key, let context):
print("Key '\(key)' not found: \(context.debugDescription)")
case .typeMismatch(let type, let context):
print("Type '\(type)' mismatch: \(context.debugDescription)")
case .valueNotFound(let type, let context):
print("Value of type '\(type)' not found: \(context.debugDescription)")
@unknown default:
print("Unknown decoding error")
}
}
}
}
task.resume()
RunLoop.main.run(until: Date(timeIntervalSinceNow: 5))
}
}
print("🚀 로또 판매점 API 테스트 시작")
LottoAPITest.testFetchLottoStores()
1. 전체 과정 요약
사용자 앱 → API 서버 요청 → 서버 응답 → 데이터 처리 → 화면 표시
2. 상세 설명
2-1. 데이터 모델 준비
struct LottoAPIResponse: Codable {
let page: Int64
let data: [LottoStore]
}
struct LottoStore: Codable {
let 번호: Int
let 상호: String
}
- 서버에서 받을 데이터의 형태를 미리 구조체로 정의
Codable 프로토콜을 채택하여 JSON ↔ Swift 객체 간 변환 가능하게 함
2-2. API 요청 준비
let baseURL = "https://api.odcloud.kr/api"
let serviceKey = "발급받은 인증키"
let urlString = "\(baseURL)\(path)?serviceKey=\(serviceKey)"
- API 서버 주소와 필요한 인증 정보를 준비
- 마치 실제 주소를 적는 것처럼 URL을 조합
2-3. 네트워크 요청 보내기
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
}
task.resume()
URLSession을 사용하여 실제 네트워크 통신 수행
- 마치 편지를 보내고 답장을 기다리는 것과 같은 과정
2-4. 응답 처리
if let error = error {
print("네트워크 에러 발생!")
return
}
guard let data = data else {
print("데이터가 없음!")
return
}
do {
let response = try JSONDecoder().decode(LottoAPIResponse.self, from: data)
print("성공! 데이터 받았음!")
} catch {
print("데이터 변환 실패!")
}
3. 실제 동작 과정
1. 앱에서 요청 보내기
└─ "로또 판매점 정보 좀 보내주세요!"
2. 서버가 요청 받기
└─ "네, 잠시만 기다려주세요"
3. 서버가 응답 보내기
└─ "여기 로또 판매점 정보입니다!"
4. 앱에서 응답 처리하기
└─ 받은 정보를 사용자가 볼 수 있게 변환
4. 비유하자면...
- 전체 과정은 마치 식당에서 주문하는 것과 비슷합니다:
- 손님(앱)이 주문서(요청) 작성
- 주문서를 주방(서버)에 전달
- 주방에서 음식(데이터) 준비
- 웨이터가 음식을 가져옴(응답)
- 손님이 음식을 받아서 먹음(데이터 처리)
5. 주의할 점
- 네트워크 통신은 시간이 걸립니다
- 언제든 실패할 수 있습니다
- 받은 데이터가 예상한 형식과 다를 수 있습니다
- 적절한 에러 처리가 중요합니다