forked from parse-community/Parse-Swift
-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathContents.swift
137 lines (117 loc) · 4.28 KB
/
Contents.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//: [Previous](@previous)
//: If you are using Xcode 13+, ignore the comments below:
//: For this page, make sure your build target is set to ParseSwift (iOS) and targeting
//: an iPhone, iPod, or iPad. Also be sure your `Playground Settings`
//: in the `File Inspector` is `Platform = iOS`. This is because
//: SwiftUI in macOS Playgrounds does not seem to build correctly
//: Be sure to switch your target and `Playground Settings` back to
//: macOS after leaving this page.
import PlaygroundSupport
import Foundation
import ParseSwift
import SwiftUI
PlaygroundPage.current.needsIndefiniteExecution = true
//: Create your own value typed ParseObject.
struct GameScore: ParseObject {
//: These are required by `ParseObject`.
var objectId: String?
var createdAt: Date?
var updatedAt: Date?
var ACL: ParseACL?
var originalData: Data?
//: Your own properties.
var points: Int? = 0
var location: ParseGeoPoint?
var name: String?
/*:
Optional - implement your own version of merge
for faster decoding after updating your `ParseObject`.
*/
func merge(with object: Self) throws -> Self {
var updated = try mergeParse(with: object)
if updated.shouldRestoreKey(\.points,
original: object) {
updated.points = object.points
}
if updated.shouldRestoreKey(\.name,
original: object) {
updated.name = object.name
}
if updated.shouldRestoreKey(\.location,
original: object) {
updated.location = object.location
}
return updated
}
}
//: It's recommended to place custom initializers in an extension
//: to preserve the memberwise initializer.
extension GameScore {
//: Custom initializer.
init(name: String, points: Int) {
self.name = name
self.points = points
}
}
//: Be sure you have LiveQuery enabled on your server.
//: Create a query just as you normally would.
var query = GameScore.query("points" < 11)
//: To use subscriptions inside of SwiftUI
struct ContentView: View {
//: A LiveQuery subscription can be used as a view model in SwiftUI
@StateObject var subscription: Subscription<GameScore>
var body: some View {
VStack {
if subscription.isSubscribed {
Text("Subscribed to query!")
} else if subscription.isUnsubscribed {
Text("Unsubscribed from query!")
} else if let event = subscription.event {
//: This is how you register to receive notifications of events related to your LiveQuery.
switch event.event {
case .entered(let object):
Text("Entered with points: \(String(describing: object.points))")
case .left(let object):
Text("Left with points: \(String(describing: object.points))")
case .created(let object):
Text("Created with points: \(String(describing: object.points))")
case .updated(let object):
Text("Updated with points: \(String(describing: object.points))")
case .deleted(let object):
Text("Deleted with points: \(String(describing: object.points))")
}
} else {
Text("Not subscribed to a query")
}
Text("Update GameScore in Parse Dashboard to see changes here:")
Button(action: {
Task {
try? await query.unsubscribe()
}
}, label: {
Text("Unsubscribe")
.font(.headline)
.background(Color.red)
.foregroundColor(.white)
.padding()
.cornerRadius(20.0)
})
Spacer()
}
}
}
@MainActor
func startView() async throws {
let subscribe = try await query.subscribe()
PlaygroundPage.current.setLiveView(ContentView(subscription: subscribe))
}
Task {
do {
try await initializeParse()
try await startView()
} catch {
print("Error subscribing: \(error)")
}
}
PlaygroundPage.current.finishExecution()
//: [Next](@next)