-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProductListView.swift
More file actions
95 lines (83 loc) · 2.57 KB
/
ProductListView.swift
File metadata and controls
95 lines (83 loc) · 2.57 KB
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
// [START complete-tutorial.display-products]
import SwiftUI
struct ProductListView: View {
@StateObject private var viewModel = ProductListViewModel()
var body: some View {
NavigationView {
List(viewModel.products) { product in
ProductRow(
product: product,
onAddToCart: { viewModel.addToCart(product: product) }
)
}
.navigationTitle("Products")
.overlay {
if viewModel.isLoading {
ProgressView()
}
}
}
.task {
await viewModel.loadProducts()
}
}
}
struct ProductRow: View {
let product: Product
let onAddToCart: () -> Void
var body: some View {
HStack {
AsyncImage(url: URL(string: product.featuredImage?.url ?? "")) { image in
image.resizable().scaledToFit()
} placeholder: {
Color.gray.opacity(0.3)
}
.frame(width: 60, height: 60)
.cornerRadius(8)
VStack(alignment: .leading) {
Text(product.title)
.font(.headline)
if let price = product.variants.edges.first?.node.price {
Text("$\(price.amount) \(price.currencyCode)")
.font(.subheadline)
.foregroundColor(.secondary)
}
}
Spacer()
Button("Add to Cart") {
onAddToCart()
}
.buttonStyle(.borderedProminent)
}
}
}
@MainActor
class ProductListViewModel: ObservableObject {
@Published var products: [Product] = []
@Published var isLoading = false
private let client = StorefrontClient(
shopDomain: "{shop}.myshopify.com",
accessToken: "your-storefront-access-token"
)
func loadProducts() async {
isLoading = true
defer { isLoading = false }
do {
products = try await client.fetchProducts()
} catch {
print("Failed to load products: \(error)")
}
}
func addToCart(product: Product) {
guard let variantId = product.firstVariantId else { return }
Task {
do {
let cart = try await client.createCart(variantId: variantId)
print("Checkout URL: \(cart.checkoutUrl)")
} catch {
print("Failed to create cart: \(error)")
}
}
}
}
// [END complete-tutorial.display-products]