Skip to content

Commit 22c6c33

Browse files
committed
♻️ Update code to match changes in firebase/firebase-ios-sdk#9101
Signed-off-by: Peter Friese <peter@peterfriese.de>
1 parent 99c636d commit 22c6c33

File tree

4 files changed

+136
-132
lines changed

4 files changed

+136
-132
lines changed

FirestoreCodableSamples/Screens/MappingArraysScreen.swift

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,24 @@ class MappingArraysViewModel: ObservableObject {
2222
private func fetchBook(documentId: String) {
2323
let docRef = db.collection("books").document(documentId)
2424

25-
docRef.getDocument { document, error in
26-
if let error = error as NSError? {
27-
self.errorMessage = "Error getting document: \(error.localizedDescription)"
28-
}
29-
else {
30-
let result = Result { try document?.data(as: BookWithGenre.self) }
31-
switch result {
32-
case .success(let book):
33-
if let book = book {
34-
// A Book value was successfully initialized from the DocumentSnapshot.
35-
self.book = book
36-
self.errorMessage = nil
37-
}
38-
else {
39-
// A nil value was successfully initialized from the DocumentSnapshot,
40-
// or the DocumentSnapshot was nil.
41-
self.errorMessage = "Document doesn't exist."
42-
}
43-
case .failure(let error):
44-
// A Book value could not be initialized from the DocumentSnapshot.
45-
switch error {
46-
case DecodingError.typeMismatch(_, let context):
47-
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
48-
case DecodingError.valueNotFound(_, let context):
49-
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
50-
case DecodingError.keyNotFound(_, let context):
51-
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
52-
case DecodingError.dataCorrupted(let key):
53-
self.errorMessage = "\(error.localizedDescription): \(key)"
54-
default:
55-
self.errorMessage = "Error decoding document: \(error.localizedDescription)"
56-
}
25+
docRef.getDocument(as: BookWithGenre.self) { result in
26+
switch result {
27+
case .success(let book):
28+
self.book = book
29+
self.errorMessage = nil
30+
case .failure(let error):
31+
// A Book value could not be initialized from the DocumentSnapshot.
32+
switch error {
33+
case DecodingError.typeMismatch(_, let context):
34+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
35+
case DecodingError.valueNotFound(_, let context):
36+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
37+
case DecodingError.keyNotFound(_, let context):
38+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
39+
case DecodingError.dataCorrupted(let key):
40+
self.errorMessage = "\(error.localizedDescription): \(key)"
41+
default:
42+
self.errorMessage = "Error decoding document: \(error.localizedDescription)"
5743
}
5844
}
5945
}

FirestoreCodableSamples/Screens/MappingArraysWithNestedTypesScreen.swift

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,38 +24,24 @@ class MappingArraysWithNestedTypesViewModel: ObservableObject {
2424
private func fetchBook(documentId: String) {
2525
let docRef = db.collection("books").document(documentId)
2626

27-
docRef.getDocument { document, error in
28-
if let error = error as NSError? {
29-
self.errorMessage = "Error getting document: \(error.localizedDescription)"
30-
}
31-
else {
32-
let result = Result { try document?.data(as: BookWithTags.self) }
33-
switch result {
34-
case .success(let book):
35-
if let book = book {
36-
// A Book value was successfully initialized from the DocumentSnapshot.
37-
self.book = book
38-
self.errorMessage = nil
39-
}
40-
else {
41-
// A nil value was successfully initialized from the DocumentSnapshot,
42-
// or the DocumentSnapshot was nil.
43-
self.errorMessage = "Document doesn't exist."
44-
}
45-
case .failure(let error):
46-
// A Book value could not be initialized from the DocumentSnapshot.
47-
switch error {
48-
case DecodingError.typeMismatch(_, let context):
49-
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
50-
case DecodingError.valueNotFound(_, let context):
51-
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
52-
case DecodingError.keyNotFound(_, let context):
53-
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
54-
case DecodingError.dataCorrupted(let key):
55-
self.errorMessage = "\(error.localizedDescription): \(key)"
56-
default:
57-
self.errorMessage = "Error decoding document: \(error.localizedDescription)"
58-
}
27+
docRef.getDocument(as: BookWithTags.self) { result in
28+
switch result {
29+
case .success(let book):
30+
self.book = book
31+
self.errorMessage = nil
32+
case .failure(let error):
33+
// A Book value could not be initialized from the DocumentSnapshot.
34+
switch error {
35+
case DecodingError.typeMismatch(_, let context):
36+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
37+
case DecodingError.valueNotFound(_, let context):
38+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
39+
case DecodingError.keyNotFound(_, let context):
40+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
41+
case DecodingError.dataCorrupted(let key):
42+
self.errorMessage = "\(error.localizedDescription): \(key)"
43+
default:
44+
self.errorMessage = "Error decoding document: \(error.localizedDescription)"
5945
}
6046
}
6147
}
@@ -130,7 +116,7 @@ struct MappingArraysWithNestedTypesScreen: View {
130116
.padding(.horizontal, 4)
131117
.padding(.vertical, 2)
132118
.background(tag.color)
133-
.cornerRadius(/*@START_MENU_TOKEN@*/3.0/*@END_MENU_TOKEN@*/)
119+
.cornerRadius(3.0)
134120
}
135121
Button(action: viewModel.addTag) {
136122
Label("Add a tag", systemImage: "plus")

FirestoreCodableSamples/Screens/MappingCustomTypesScreen.swift

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,25 @@ class MappingCustomTypesViewModel: ObservableObject {
2222
private func fetchBook(documentId: String) {
2323
let docRef = db.collection("books").document(documentId)
2424

25-
docRef.getDocument { document, error in
26-
if let error = error as NSError? {
27-
self.errorMessage = "Error getting document: \(error.localizedDescription)"
28-
}
29-
else {
30-
let result = Result { try document?.data(as: BookWithCoverImages.self) }
31-
switch result {
32-
case .success(let book):
33-
if let book = book {
34-
// A Book value was successfully initialized from the DocumentSnapshot.
35-
self.book = book
36-
self.errorMessage = nil
37-
}
38-
else {
39-
// A nil value was successfully initialized from the DocumentSnapshot,
40-
// or the DocumentSnapshot was nil.
41-
self.errorMessage = "Document doesn't exist."
42-
}
43-
case .failure(let error):
44-
// A Book value could not be initialized from the DocumentSnapshot.
45-
switch error {
46-
case DecodingError.typeMismatch(_, let context):
47-
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
48-
case DecodingError.valueNotFound(_, let context):
49-
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
50-
case DecodingError.keyNotFound(_, let context):
51-
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
52-
case DecodingError.dataCorrupted(let key):
53-
self.errorMessage = "\(error.localizedDescription): \(key)"
54-
default:
55-
self.errorMessage = "Error decoding document: \(error.localizedDescription)"
56-
}
25+
docRef.getDocument(as: BookWithCoverImages.self) { result in
26+
switch result {
27+
case .success(let book):
28+
// A Book value was successfully initialized from the DocumentSnapshot.
29+
self.book = book
30+
self.errorMessage = nil
31+
case .failure(let error):
32+
// A Book value could not be initialized from the DocumentSnapshot.
33+
switch error {
34+
case DecodingError.typeMismatch(_, let context):
35+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
36+
case DecodingError.valueNotFound(_, let context):
37+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
38+
case DecodingError.keyNotFound(_, let context):
39+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
40+
case DecodingError.dataCorrupted(let key):
41+
self.errorMessage = "\(error.localizedDescription): \(key)"
42+
default:
43+
self.errorMessage = "Error decoding document: \(error.localizedDescription)"
5744
}
5845
}
5946
}

FirestoreCodableSamples/Screens/MappingSimpleTypesScreen.swift

Lines changed: 80 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,53 +15,98 @@ class MappingSimpleTypesViewModel: ObservableObject {
1515

1616
private var db = Firestore.firestore()
1717

18+
/// Use this to alteratively use async/await or callback-based implementations
19+
let useAsync = false
20+
1821
func fetchAndMap() {
19-
fetchBook(documentId: "hitchhiker")
22+
if useAsync {
23+
Task {
24+
await fetchBookAsync(documentId: "hitchhiker")
25+
}
26+
}
27+
else {
28+
fetchBook(documentId: "hitchhiker")
29+
}
2030
}
2131

2232
func fetchAndMapNonExisting() {
23-
fetchBook(documentId: "does-not-exist")
33+
if useAsync {
34+
Task {
35+
await fetchBookAsync(documentId: "does-not-exist")
36+
}
37+
}
38+
else {
39+
fetchBook(documentId: "does-not-exist")
40+
}
2441
}
2542

2643
func fetchAndTryMappingInvalidData() {
27-
fetchBook(documentId: "invalid-data")
44+
if useAsync {
45+
Task {
46+
await fetchBookAsync(documentId: "invalid-data")
47+
}
48+
}
49+
else {
50+
fetchBook(documentId: "invalid-data")
51+
}
52+
}
53+
54+
/// Alternative implementation that shows how to use async/await to call `getDocument`
55+
/// This needs to be marked as @MainActor so that we can safely access the errorMessage
56+
/// published property when encountering an error.
57+
@MainActor
58+
private func fetchBookAsync(documentId: String) async {
59+
let docRef = db.collection("books").document(documentId)
60+
do {
61+
self.book = try await docRef.getDocument(as: Book.self)
62+
}
63+
catch {
64+
switch error {
65+
case DecodingError.typeMismatch(_, let context):
66+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
67+
case DecodingError.valueNotFound(_, let context):
68+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
69+
case DecodingError.keyNotFound(_, let context):
70+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
71+
case DecodingError.dataCorrupted(let key):
72+
self.errorMessage = "\(error.localizedDescription): \(key)"
73+
default:
74+
self.errorMessage = "Error decoding document: \(error.localizedDescription)"
75+
}
76+
}
2877
}
2978

3079
private func fetchBook(documentId: String) {
3180
let docRef = db.collection("books").document(documentId)
3281

33-
docRef.getDocument { document, error in
34-
if let error = error as NSError? {
35-
self.errorMessage = "Error getting document: \(error.localizedDescription)"
36-
}
37-
else {
38-
let result = Result { try document?.data(as: Book.self) }
39-
switch result {
40-
case .success(let book):
41-
if let book = book {
42-
// A Book value was successfully initialized from the DocumentSnapshot.
43-
self.book = book
44-
self.errorMessage = nil
45-
}
46-
else {
47-
// A nil value was successfully initialized from the DocumentSnapshot,
48-
// or the DocumentSnapshot was nil.
49-
self.errorMessage = "Document doesn't exist."
50-
}
51-
case .failure(let error):
52-
// A Book value could not be initialized from the DocumentSnapshot.
53-
switch error {
54-
case DecodingError.typeMismatch(_, let context):
55-
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
56-
case DecodingError.valueNotFound(_, let context):
57-
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
58-
case DecodingError.keyNotFound(_, let context):
59-
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
60-
case DecodingError.dataCorrupted(let key):
61-
self.errorMessage = "\(error.localizedDescription): \(key)"
62-
default:
63-
self.errorMessage = "Error decoding document: \(error.localizedDescription)"
64-
}
82+
// If you expect that a document might *not exist*, use an optional type (Book?.self)
83+
// and then perform an `if let book = book` dance to handle this case.
84+
docRef.getDocument(as: Book?.self) { result in
85+
switch result {
86+
case .success(let book):
87+
if let book = book {
88+
// A Book value was successfully initialized from the DocumentSnapshot.
89+
self.book = book
90+
self.errorMessage = nil
91+
}
92+
else {
93+
// A nil value was successfully initialized from the DocumentSnapshot,
94+
// or the DocumentSnapshot was nil.
95+
self.errorMessage = "Document doesn't exist."
96+
}
97+
case .failure(let error):
98+
// A Book value could not be initialized from the DocumentSnapshot.
99+
switch error {
100+
case DecodingError.typeMismatch(_, let context):
101+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
102+
case DecodingError.valueNotFound(_, let context):
103+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
104+
case DecodingError.keyNotFound(_, let context):
105+
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
106+
case DecodingError.dataCorrupted(let key):
107+
self.errorMessage = "\(error.localizedDescription): \(key)"
108+
default:
109+
self.errorMessage = "Error decoding document: \(error.localizedDescription)"
65110
}
66111
}
67112
}

0 commit comments

Comments
 (0)