Skip to content

Commit ed66181

Browse files
authored
🔀 [Home] Mock JSON으로 제품 리스트 가져오는 흐름 구현 (#29)
* 📦 Add Entity Module * ✨ Add `Product` Entity and ResponseDTO * ✨ Add ConvenienceStore, Promotion Entities * ➕ Add Entity dependency to APIService * ✨ Establish model for inquiry API * ✨ Add HomeAPI Service * 👽 Update `HomeEndPoint` and Mock JSON * ✨ Update HomeAPI JSON and modify models with id * ✨ Implement AppRootComponent and inject into SplashView * ✨ Add HomeViewModel * ✨ Implement `SplashView` transition to `HomeView` - SplashView is now displayed for 1 second before transitioning to HomeView. - Injected HomeViewModel into HomeView as an environmentObject. * ✨ Bind `Product` model in HomeViewModel to HomeView * 🔥 Remove `Group` View * ♻️ Refactor Text initializer usage - Switched from `Text(verbatim:)` to `Text(_:)` initializer * ⏪ Revert "♻️ Refactor Text initializer usage" This reverts commit f418abb. * ♻️ Refactor price text using `formatted` function
1 parent 2b45ac9 commit ed66181

File tree

19 files changed

+453
-117
lines changed

19 files changed

+453
-117
lines changed

APIService/Package.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// swift-tools-version: 5.9
2-
// The swift-tools-version declares the minimum version of Swift required to build this package.
32

43
import PackageDescription
54

@@ -18,12 +17,14 @@ let package = Package(
1817
],
1918
dependencies: [
2019
.package(path: "../Core"),
20+
.package(path: "../Entity"),
2121
],
2222
targets: [
2323
.target(
2424
name: "HomeAPI",
2525
dependencies: [
2626
.product(name: "Network", package: "Core"),
27+
.product(name: "Entity", package: "Entity"),
2728
]
2829
),
2930
.target(

APIService/Sources/HomeAPI/HomeEndPoint.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ import Foundation
99
import Network
1010

1111
struct HomeEndPoint: EndPoint {
12-
var method: HTTPMethod
12+
let method: HTTPMethod = .get
1313

14-
var path: String
14+
let path: String = "v2/products"
1515

16-
var parameters: Network.HTTPParameter
16+
let parameters: HTTPParameter = .plain
1717

18-
var headers: [String: String]
18+
let headers: [String: String] = ["Content-Type": "application/json"]
1919
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// HomeService.swift
3+
//
4+
//
5+
// Created by 홍승현 on 1/31/24.
6+
//
7+
8+
import Entity
9+
import Foundation
10+
import Network
11+
12+
// MARK: - HomeServiceRepresentable
13+
14+
public protocol HomeServiceRepresentable {
15+
func fetchProductList() async throws -> [Product]
16+
}
17+
18+
// MARK: - HomeService
19+
20+
public struct HomeService {
21+
private let network: Networking
22+
23+
public init(network: Networking) {
24+
self.network = network
25+
}
26+
}
27+
28+
// MARK: HomeServiceRepresentable
29+
30+
extension HomeService: HomeServiceRepresentable {
31+
public func fetchProductList() async throws -> [Product] {
32+
let products: [ProductResponse] = try await network.request(with: HomeEndPoint())
33+
return products.map(Product.init)
34+
}
35+
}
36+
37+
private extension Product {
38+
init(dto: ProductResponse) {
39+
self.init(
40+
id: dto.id,
41+
imageURL: dto.imageURL,
42+
price: dto.price,
43+
name: dto.name,
44+
promotion: dto.promotion,
45+
convenienceStore: dto.convenienceStore
46+
)
47+
}
48+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// ProductRequest.swift
3+
//
4+
//
5+
// Created by 홍승현 on 1/31/24.
6+
//
7+
8+
import Entity
9+
import Foundation
10+
11+
public struct ProductRequest: Encodable {
12+
public let store: ConvenienceStore
13+
public let promotion: Promotion
14+
public let order: Order
15+
public let pageSize: Int
16+
public let offset: Int
17+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// ProductResponse.swift
3+
//
4+
//
5+
// Created by 홍승현 on 1/31/24.
6+
//
7+
8+
import Entity
9+
import Foundation
10+
11+
public struct ProductResponse: Decodable {
12+
public let id: Int
13+
public let imageURL: URL
14+
public let price: Int
15+
public let name: String
16+
public let promotion: Promotion
17+
public let convenienceStore: ConvenienceStore
18+
19+
public enum CodingKeys: String, CodingKey {
20+
case id
21+
case imageURL = "image_url"
22+
case price
23+
case name
24+
case promotion
25+
case convenienceStore
26+
}
27+
}
Lines changed: 92 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,92 @@
1-
{
2-
"count": 10,
3-
"products": [
4-
{
5-
"date": "2024:01",
6-
"img": "https://image.woodongs.com/imgsvr/item/GD_8809288634967_001.jpg",
7-
"price": 2500,
8-
"name": "BR)레인보우샤베트과즙워터500ML",
9-
"tag": "1+1",
10-
"store": "GS25"
11-
},
12-
{
13-
"date": "2024:01",
14-
"img": "https://image.woodongs.com/imgsvr/item/GD_8809288635315_003.jpg",
15-
"price": 2500,
16-
"name": "BR)망고탱고과즙워터500ML",
17-
"tag": "1+1",
18-
"store": "GS25"
19-
},
20-
{
21-
"date": "2024:01",
22-
"img": "https://image.woodongs.com/imgsvr/item/GD_8809288634974_001.jpg",
23-
"price": 2500,
24-
"name": "BR)피치요거트과즙워터500ML",
25-
"tag": "1+1",
26-
"store": "GS25"
27-
},
28-
{
29-
"date": "2024:01",
30-
"img": "https://image.woodongs.com/imgsvr/item/GD_8806002010861_865.jpg",
31-
"price": 5000,
32-
"name": "광동)헛개파워100ML",
33-
"tag": "1+1",
34-
"store": "GS25"
35-
},
36-
{
37-
"date": "2024:01",
38-
"img": "https://image.woodongs.com/imgsvr/item/GD_8806011416005_001.JPG",
39-
"price": 5000,
40-
"name": "동아)모닝케어D100ML",
41-
"tag": "1+1",
42-
"store": "GS25"
43-
},
44-
{
45-
"date": "2024:01",
46-
"img": "https://image.woodongs.com/imgsvr/item/GD_8806011415992_001.JPG",
47-
"price": 5000,
48-
"name": "동아)모닝케어H100ML",
49-
"tag": "1+1",
50-
"store": "GS25"
51-
},
52-
{
53-
"date": "2024:01",
54-
"img": "https://image.woodongs.com/imgsvr/item/GD_8809556566891_001.jpg",
55-
"price": 5000,
56-
"name": "서영)모닝이즈백100ML",
57-
"tag": "1+1",
58-
"store": "GS25"
59-
},
60-
{
61-
"date": "2024:01",
62-
"img": "https://image.woodongs.com/imgsvr/item/GD_8809125061857_002.jpg",
63-
"price": 5000,
64-
"name": "종근당)헛개땡큐골드100ML",
65-
"tag": "1+1",
66-
"store": "GS25"
67-
},
68-
{
69-
"date": "2024:01",
70-
"img": "https://image.woodongs.com/imgsvr/item/GD_8809329050015_018.jpg",
71-
"price": 5000,
72-
"name": "천지개벽)숙취해소음료100ML",
73-
"tag": "1+1",
74-
"store": "GS25"
75-
},
76-
{
77-
"date": "2024:01",
78-
"img": "https://image.woodongs.com/imgsvr/item/GD_8801013777260_001.jpg",
79-
"price": 5000,
80-
"name": "큐원)상쾌환부스터100ML",
81-
"tag": "1+1",
82-
"store": "GS25"
83-
}
84-
]
85-
}
1+
[
2+
{
3+
"id": 1,
4+
"date": "2024:01",
5+
"image_url": "https://image.woodongs.com/imgsvr/item/GD_8809288634967_001.jpg",
6+
"price": 2500,
7+
"name": "BR)레인보우샤베트과즙워터500ML",
8+
"promotion": "1+1",
9+
"convenienceStore": "GS25"
10+
},
11+
{
12+
"id": 2,
13+
"date": "2024:01",
14+
"image_url": "https://image.woodongs.com/imgsvr/item/GD_8809288635315_003.jpg",
15+
"price": 2500,
16+
"name": "BR)망고탱고과즙워터500ML",
17+
"promotion": "1+1",
18+
"convenienceStore": "GS25"
19+
},
20+
{
21+
"id": 3,
22+
"date": "2024:01",
23+
"image_url": "https://image.woodongs.com/imgsvr/item/GD_8809288634974_001.jpg",
24+
"price": 2500,
25+
"name": "BR)피치요거트과즙워터500ML",
26+
"promotion": "1+1",
27+
"convenienceStore": "GS25"
28+
},
29+
{
30+
"id": 4,
31+
"date": "2024:01",
32+
"image_url": "https://image.woodongs.com/imgsvr/item/GD_8806002010861_865.jpg",
33+
"price": 5000,
34+
"name": "광동)헛개파워100ML",
35+
"promotion": "1+1",
36+
"convenienceStore": "GS25"
37+
},
38+
{
39+
"id": 5,
40+
"date": "2024:01",
41+
"image_url": "https://image.woodongs.com/imgsvr/item/GD_8806011416005_001.JPG",
42+
"price": 5000,
43+
"name": "동아)모닝케어D100ML",
44+
"promotion": "1+1",
45+
"convenienceStore": "GS25"
46+
},
47+
{
48+
"id": 6,
49+
"date": "2024:01",
50+
"image_url": "https://image.woodongs.com/imgsvr/item/GD_8806011415992_001.JPG",
51+
"price": 5000,
52+
"name": "동아)모닝케어H100ML",
53+
"promotion": "1+1",
54+
"convenienceStore": "GS25"
55+
},
56+
{
57+
"id": 7,
58+
"date": "2024:01",
59+
"image_url": "https://image.woodongs.com/imgsvr/item/GD_8809556566891_001.jpg",
60+
"price": 5000,
61+
"name": "서영)모닝이즈백100ML",
62+
"promotion": "1+1",
63+
"convenienceStore": "GS25"
64+
},
65+
{
66+
"id": 8,
67+
"date": "2024:01",
68+
"image_url": "https://image.woodongs.com/imgsvr/item/GD_8809125061857_002.jpg",
69+
"price": 5000,
70+
"name": "종근당)헛개땡큐골드100ML",
71+
"promotion": "1+1",
72+
"convenienceStore": "GS25"
73+
},
74+
{
75+
"id": 9,
76+
"date": "2024:01",
77+
"image_url": "https://image.woodongs.com/imgsvr/item/GD_8809329050015_018.jpg",
78+
"price": 5000,
79+
"name": "천지개벽)숙취해소음료100ML",
80+
"promotion": "1+1",
81+
"convenienceStore": "GS25"
82+
},
83+
{
84+
"id": 10,
85+
"date": "2024:01",
86+
"image_url": "https://image.woodongs.com/imgsvr/item/GD_8801013777260_001.jpg",
87+
"price": 5000,
88+
"name": "큐원)상쾌환부스터100ML",
89+
"promotion": "1+1",
90+
"convenienceStore": "GS25"
91+
}
92+
]

Entity/.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
xcuserdata/
5+
DerivedData/
6+
.swiftpm/configuration/registries.json
7+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8+
.netrc

Entity/Package.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// swift-tools-version: 5.9
2+
3+
import PackageDescription
4+
5+
let package = Package(
6+
name: "Entity",
7+
products: [
8+
.library(
9+
name: "Entity",
10+
targets: ["Entity"]
11+
),
12+
],
13+
targets: [
14+
.target(
15+
name: "Entity"
16+
),
17+
]
18+
)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// ConvenienceStore.swift
3+
//
4+
//
5+
// Created by 홍승현 on 1/31/24.
6+
//
7+
8+
import Foundation
9+
10+
public enum ConvenienceStore: String, Codable {
11+
case cu = "CU"
12+
case gs25 = "GS25"
13+
case _7Eleven = "7-Eleven"
14+
case emart24
15+
case ministop = "MINISTOP"
16+
}

Entity/Sources/Entity/Order.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//
2+
// Order.swift
3+
//
4+
//
5+
// Created by 홍승현 on 1/31/24.
6+
//
7+
8+
import Foundation
9+
10+
public enum Order: String, Codable {
11+
case normal
12+
case ascending = "asc"
13+
case descending = "desc"
14+
}

0 commit comments

Comments
 (0)