From 6d8a1bf9c8e8c8ee546c2468d3f83f1fde0ba7f7 Mon Sep 17 00:00:00 2001 From: keonjo Date: Tue, 16 Sep 2025 16:27:20 +0900 Subject: [PATCH] =?UTF-8?q?=EC=B0=A8=EB=9F=89=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=A0=88=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20?= =?UTF-8?q?=EC=B6=94=EC=83=81=ED=99=94(restAPI,=20=ED=8C=8C=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=EB=B2=A0=EC=9D=B4=EC=8A=A4)=20"=EC=A0=84=EC=B2=B4?= =?UTF-8?q?=EB=B3=B4=EA=B8=B0"=20=ED=81=B4=EB=A6=AD=ED=95=98=EB=A9=B4=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=ED=99=94=EB=A9=B4=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=84=98=EC=96=B4=EA=B0=91=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- campick/GoogleService-Info.plist | 30 +++++++++++++++++++ campick/Models/Car.swift | 14 +++++++++ campick/Models/CarFirebase.swift | 25 ++++++++++++++++ campick/Models/CarSpring.swift | 19 ++++++++++++ .../Repositories/CarFiebaseRepository.swift | 21 +++++++++++++ .../Repositories/CarRepositoryProtocol.swift | 11 +++++++ .../Repositories/CarSpringRepository.swift | 20 +++++++++++++ campick/ViewModels/CarViewModel.swift | 27 +++++++++++++++++ campick/Views/CarListView.swift | 30 +++++++++++++++++++ campick/Views/HomeView.swift | 2 +- campick/campickApp.swift | 5 ++++ 11 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 campick/GoogleService-Info.plist create mode 100644 campick/Models/Car.swift create mode 100644 campick/Models/CarFirebase.swift create mode 100644 campick/Models/CarSpring.swift create mode 100644 campick/Repositories/CarFiebaseRepository.swift create mode 100644 campick/Repositories/CarRepositoryProtocol.swift create mode 100644 campick/Repositories/CarSpringRepository.swift create mode 100644 campick/ViewModels/CarViewModel.swift create mode 100644 campick/Views/CarListView.swift diff --git a/campick/GoogleService-Info.plist b/campick/GoogleService-Info.plist new file mode 100644 index 0000000..ea0ebd0 --- /dev/null +++ b/campick/GoogleService-Info.plist @@ -0,0 +1,30 @@ + + + + + API_KEY + AIzaSyDDXXGt2O1elBA0wB9X3bbXMfGWhOhTGsU + GCM_SENDER_ID + 717701143130 + PLIST_VERSION + 1 + BUNDLE_ID + com.nobody.campick + PROJECT_ID + campick-8b1ac + STORAGE_BUCKET + campick-8b1ac.firebasestorage.app + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:717701143130:ios:4fbfcf7017bff4fb9b9663 + + \ No newline at end of file diff --git a/campick/Models/Car.swift b/campick/Models/Car.swift new file mode 100644 index 0000000..b4924bc --- /dev/null +++ b/campick/Models/Car.swift @@ -0,0 +1,14 @@ +// +// Car.swift +// campick +// +// Created by Kihwan Jo on 9/16/25. +// + + +struct Car: Identifiable { + let id: String? // ID는 옵셔널로, 플랫폼에 따라 생성 여부 달라짐 + let brand: String + let model: String + let year: Int +} \ No newline at end of file diff --git a/campick/Models/CarFirebase.swift b/campick/Models/CarFirebase.swift new file mode 100644 index 0000000..2f1c927 --- /dev/null +++ b/campick/Models/CarFirebase.swift @@ -0,0 +1,25 @@ +// +// CarFirebase.swift +// campick +// +// Created by Kihwan Jo on 9/16/25. +// + + +import FirebaseFirestore + +struct CarFirebase: Codable { + @DocumentID var id: String? // Firestore 문서 ID + let brand: String + let model: String + let year: Int + + enum CodingKeys: String, CodingKey { + case brand, model, year + } + + // 도메인 모델로 변환 + func toDomain() -> Car { + Car(id: id, brand: brand, model: model, year: year) + } +} diff --git a/campick/Models/CarSpring.swift b/campick/Models/CarSpring.swift new file mode 100644 index 0000000..f0a51b4 --- /dev/null +++ b/campick/Models/CarSpring.swift @@ -0,0 +1,19 @@ +// +// CarSpring.swift +// campick +// +// Created by Kihwan Jo on 9/16/25. +// + + +struct CarSpring: Codable { + let id: String? // Spring Boot에서 ID 제공 여부에 따라 조정 + let brand: String + let model: String + let year: Int + + // 도메인 모델로 변환 + func toDomain() -> Car { + Car(id: id, brand: brand, model: model, year: year) + } +} \ No newline at end of file diff --git a/campick/Repositories/CarFiebaseRepository.swift b/campick/Repositories/CarFiebaseRepository.swift new file mode 100644 index 0000000..322b340 --- /dev/null +++ b/campick/Repositories/CarFiebaseRepository.swift @@ -0,0 +1,21 @@ +// +// CarFiebaseRepository.swift +// campick +// +// Created by Kihwan Jo on 9/16/25. +// + +import FirebaseFirestore + +class CarFirebaseRepository: CarRepositoryProtocol { + private let db = Firestore.firestore() + private let collectionPath = "cars" + + func fetchCars() async throws -> [Car] { + let snapshot = try await db.collection(collectionPath).getDocuments() + return try snapshot.documents.compactMap { document in + let carFirebase = try document.data(as: CarFirebase.self) + return carFirebase.toDomain() + } + } +} diff --git a/campick/Repositories/CarRepositoryProtocol.swift b/campick/Repositories/CarRepositoryProtocol.swift new file mode 100644 index 0000000..bccb8b9 --- /dev/null +++ b/campick/Repositories/CarRepositoryProtocol.swift @@ -0,0 +1,11 @@ +// +// CarRepositoryProtocol.swift +// campick +// +// Created by Kihwan Jo on 9/16/25. +// + + +protocol CarRepositoryProtocol { + func fetchCars() async throws -> [Car] +} diff --git a/campick/Repositories/CarSpringRepository.swift b/campick/Repositories/CarSpringRepository.swift new file mode 100644 index 0000000..7c8d4f0 --- /dev/null +++ b/campick/Repositories/CarSpringRepository.swift @@ -0,0 +1,20 @@ +// +// CarSpringRepository.swift +// campick +// +// Created by Kihwan Jo on 9/16/25. +// + +import Foundation + +class CarSpringRepository: CarRepositoryProtocol { + private let urlSession = URLSession.shared + private let baseURL = URL(string: "http://192.168.201.15:8080")! + + func fetchCars() async throws -> [Car] { + let url = baseURL.appendingPathComponent("cars") + let (data, _) = try await urlSession.data(from: url) + let carsSpring = try JSONDecoder().decode([CarSpring].self, from: data) + return carsSpring.map { $0.toDomain() } + } +} diff --git a/campick/ViewModels/CarViewModel.swift b/campick/ViewModels/CarViewModel.swift new file mode 100644 index 0000000..4b53683 --- /dev/null +++ b/campick/ViewModels/CarViewModel.swift @@ -0,0 +1,27 @@ +// +// CarViewModel.swift +// campick +// +// Created by Kihwan Jo on 9/16/25. +// +import SwiftUI + +@MainActor +class CarViewModel: ObservableObject { + @Published var cars: [Car] = [] + + private let repository: CarRepositoryProtocol + + init(repository: CarRepositoryProtocol = CarSpringRepository()) { +// init(repository: CarRepositoryProtocol = CarFiebaseRepository()) { + self.repository = repository + Task { + await fetchCars() + } + } + + func fetchCars() async { + let cars = try? await repository.fetchCars() + self.cars = cars ?? [] + } +} diff --git a/campick/Views/CarListView.swift b/campick/Views/CarListView.swift new file mode 100644 index 0000000..1d72cbd --- /dev/null +++ b/campick/Views/CarListView.swift @@ -0,0 +1,30 @@ +// +// CarListFirebaseView.swift +// campick +// +// Created by Kihwan Jo on 9/16/25. +// + +import SwiftUI + +struct CarListView: View { + @StateObject private var viewModel = CarViewModel() + + var body: some View { + NavigationView { + List(viewModel.cars) { car in + VStack(alignment: .leading) { + Text("\(car.brand) \(car.model)") + .font(.headline) + Text("Year: \(car.year)") + .font(.subheadline) + } + } + .navigationTitle("Cars") + } + } +} + +#Preview { + CarListView() +} diff --git a/campick/Views/HomeView.swift b/campick/Views/HomeView.swift index afbee08..9a3f4c4 100644 --- a/campick/Views/HomeView.swift +++ b/campick/Views/HomeView.swift @@ -125,7 +125,7 @@ struct HomeView: View { .font(.headline) } Spacer() - NavigationLink(destination: Text("전체 매물")) { + NavigationLink(destination: CarListView()) { HStack { Text("전체보기") .foregroundColor(.brandLightOrange) diff --git a/campick/campickApp.swift b/campick/campickApp.swift index 621e2af..f4822eb 100644 --- a/campick/campickApp.swift +++ b/campick/campickApp.swift @@ -6,9 +6,14 @@ // import SwiftUI +import FirebaseCore @main struct campickApp: App { + init() { + FirebaseApp.configure() + } + var body: some Scene { WindowGroup { ContentView()