-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathStorefrontClient.swift
More file actions
124 lines (105 loc) · 3.98 KB
/
Copy pathStorefrontClient.swift
File metadata and controls
124 lines (105 loc) · 3.98 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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import Foundation
class StorefrontClient {
// [START integrate.config]
let shopDomain: String
let accessToken: String
let apiVersion: String
init(shopDomain: String, accessToken: String, apiVersion: String = "2026-01") {
self.shopDomain = shopDomain
self.accessToken = accessToken
self.apiVersion = apiVersion
}
// [END integrate.config]
// [START complete-tutorial.fetch-products]
func fetchProducts() async throws -> [Product] {
let url = URL(string: "https://\(shopDomain)/api/\(apiVersion)/graphql.json")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(accessToken, forHTTPHeaderField: "X-Shopify-Storefront-Access-Token")
let query = """
query Products {
products(first: 10) {
edges {
node {
id
title
description
featuredImage { url }
variants(first: 1) {
edges {
node {
id
title
price { amount currencyCode }
}
}
}
}
}
}
}
"""
let body = ["query": query]
request.httpBody = try JSONSerialization.data(withJSONObject: body)
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw StorefrontError.requestFailed
}
let result = try JSONDecoder().decode(ProductsResponse.self, from: data)
return result.data.products.edges.map { $0.node }
}
// [END complete-tutorial.fetch-products]
// [START complete-tutorial.create-cart]
func createCart(variantId: String, quantity: Int = 1) async throws -> Cart {
let url = URL(string: "https://\(shopDomain)/api/\(apiVersion)/graphql.json")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(accessToken, forHTTPHeaderField: "X-Shopify-Storefront-Access-Token")
let mutation = """
mutation CartCreate($input: CartInput!) {
cartCreate(input: $input) {
cart {
id
checkoutUrl
}
userErrors {
field
message
}
}
}
"""
let variables: [String: Any] = [
"input": [
"lines": [
["merchandiseId": variantId, "quantity": quantity]
]
]
]
let body: [String: Any] = ["query": mutation, "variables": variables]
request.httpBody = try JSONSerialization.data(withJSONObject: body)
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw StorefrontError.requestFailed
}
let result = try JSONDecoder().decode(CartCreateResponse.self, from: data)
if let error = result.data.cartCreate.userErrors.first {
throw CartError.userError(error.message)
}
guard let cart = result.data.cartCreate.cart else {
throw CartError.cartNotCreated
}
return cart
}
// [END complete-tutorial.create-cart]
// [START integrate.cart-permalink]
func buildCartPermalink(variantId: String, quantity: Int = 1) -> URL {
let numericVariantId = variantId.split(separator: "/").last.map(String.init) ?? variantId
return URL(string: "https://\(shopDomain)/cart/\(numericVariantId):\(quantity)")!
}
// [END integrate.cart-permalink]
}