-
Notifications
You must be signed in to change notification settings - Fork 0
/
KaKaoAPI.swift
113 lines (103 loc) · 4.28 KB
/
KaKaoAPI.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//
// API.swift
// Effortless Eats
//
// Created by 김성준 on 1/8/24.
//
import Foundation
import Combine
import CoreLocation
struct KaKaoAPI {
let locationManager = LocationManager()
enum KakaoAPIError: Error, CustomStringConvertible {
case overflowRadius
case invalidURL
case invalidResponse
case decodeError
var description: String {
switch self {
case .overflowRadius:
return "radius 파라미터 값이 유효하지 않습니다. 범위는 0~200000"
case .invalidURL:
return "유효하지 않는 URL 발생"
case .invalidResponse:
return "유효하지 않는 응답."
case .decodeError:
return "Parsing 에러 발생"
}
}
}
enum EndPoint {
static let apiProtocol = Bundle.main.infoDictionary?["KAKAO_API_PROTOCOL"] as? String ?? String("")
static let domain = Bundle.main.infoDictionary?["KAKAO_API_DOMAIN"] as? String ?? String("")
static let restAPIKey = Bundle.main.infoDictionary?["KAKAO_REST_API_KEY"] as? String ?? String("")
static let restAPIMethod = Bundle.main.infoDictionary?["KAKAO_RESTAPI_AUTH_METHOD"] as? String ?? String("")
var baseURL: URL {
URL(string: "\(KaKaoAPI.EndPoint.apiProtocol)://\(KaKaoAPI.EndPoint.domain)")!
}
case kakaoLocalAPI
var request: URLRequest {
switch self {
case .kakaoLocalAPI:
let url = baseURL.appendingPathComponent("/local/search/category.json")
var request = URLRequest(url: url)
request.url?.append(queryItems: [ .init(name: "category_group_code", value: KaKaoLocalAPICategory.Restaurant.rawValue)])
request.addValue("\(KaKaoAPI.EndPoint.restAPIMethod) \(KaKaoAPI.EndPoint.restAPIKey)", forHTTPHeaderField: "Authorization")
request.httpMethod = "GET"
return request
}
}
}
enum KaKaoLocalAPICategory: String {
case Supermarket = "MT1"
case ConvenienceStore = "CS2"
case Kindergarten = "PS3"
case School = "SC4"
case Academy = "AC5"
case ParkingLot = "PK6"
case GasStation = "OL7"
case SubwayStation = "SW8"
case Bank = "BK9"
case CulturalFacility = "CT1"
case Brokerage = "AG2"
case PublicInstitution = "PO3"
case TouristAttraction = "AT4"
case Accommodation = "AD5"
case Restaurant = "FD6"
case Cafe = "CE7"
case Hospital = "HP8"
case Pharmacy = "PM9"
}
/// 내주위 음식점 정보 가지고오기
/// - Parameters:
/// - radius: 내 중심점 위도 경도 기준 반경 설정 파라미터(m단위).
/// - Returns: URL session data task publihser for a given request
func requestStores(distance radius: Int, coordinate: CLLocationCoordinate2D?) -> AnyPublisher<KaKaoLocalAPIDTO, KakaoAPIError> {
guard (0...20000).contains(radius) else {
return Empty<KaKaoLocalAPIDTO, KakaoAPIError>()
.mapError { _ in KakaoAPIError.overflowRadius}
.eraseToAnyPublisher()
}
var request = EndPoint.kakaoLocalAPI.request
request.url?.append(queryItems: [ .init(name: "radius", value: "\(radius)")])
if let coordinate = coordinate {
request.url?.append(queryItems: [ .init(name: "x", value: "\(coordinate.longitude)")])
request.url?.append(queryItems: [ .init(name: "y", value: "\(coordinate.latitude)")])
}
return URLSession.shared.dataTaskPublisher(for: request)
.receive(on: DispatchQueue.global())
.tryMap { output in
return try JSONDecoder().decode(KaKaoLocalAPIDTO.self, from: output.data)
}
.mapError { error -> KakaoAPIError in
switch error {
case is URLError:
return KakaoAPIError.invalidURL
case is DecodingError:
return KakaoAPIError.decodeError
default: return KakaoAPIError.invalidResponse
}
}
.eraseToAnyPublisher()
}
}