Skip to content

Commit ba99920

Browse files
Add animations to @FirestoreQuery (#11437)
* Feature: Add animations to @FirestoreQuery - Adds a SwiftUI `Animation` parameter to the FirebaseQuery initializer. - If animation is not `nil` then setting the data to the published value will be executed inside of a `withAnimation` block (with the given `Animation`) * feature: Add `FavouriteFruitsAnimationView` This view demostrates how to use the ``FirestoreQuery`` property wrapper, using the `animation` parameter to make sure list items are animated when being added or removed. * Explore alternative strategy for animating changes This is an alternatice to the approach for animating changes in PR #10813 * Update sample project to include a view with and without animations --------- Signed-off-by: Peter Friese <[email protected]> Co-authored-by: Brianna Zamora <[email protected]>
1 parent f0378e9 commit ba99920

23 files changed

+506
-132
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,4 @@ FirebaseAppCheck/Apps/AppCheckCustomProvideApp/AppCheckCustomProvideApp/GoogleSe
155155
/Example/FirestoreSample/FirestoreSample/GoogleService-Info.plist
156156
/Example/FirestoreSample/ui-debug.log
157157
/Example/FirestoreSample/firestore-debug.log
158+
/Example/FirestoreSample/firebase-debug.log

Example/FirestoreSample/.firebaserc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
{}
1+
{
2+
"projects": {
3+
"default": "fir-firestore-sample-ios"
4+
}
5+
}

Example/FirestoreSample/FirestoreSample.xcodeproj/project.pbxproj

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10-
8817084426B9593E009E9281 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8817084326B9593E009E9281 /* GoogleService-Info.plist */; };
1110
8817084726B95A63009E9281 /* FirebaseFirestore in Frameworks */ = {isa = PBXBuildFile; productRef = 8817084626B95A63009E9281 /* FirebaseFirestore */; };
1211
8817084926B95A63009E9281 /* FirebaseFirestoreSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 8817084826B95A63009E9281 /* FirebaseFirestoreSwift */; };
1312
88327B8826D62908002AA6D9 /* FavouriteFruitsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88327B8726D62908002AA6D9 /* FavouriteFruitsView.swift */; };
1413
8844BA6126E0DD3F000786F0 /* FavouriteFruitsMappingErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8844BA6026E0DD3F000786F0 /* FavouriteFruitsMappingErrorView.swift */; };
1514
88D5E37826EBD2F200808AFF /* FavouriteFruitsMappingErrorView2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88D5E37726EBD2F200808AFF /* FavouriteFruitsMappingErrorView2.swift */; };
15+
88D9354A2A39CB3E00FD8AFF /* FavouriteFruitsAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88D935492A39CB3E00FD8AFF /* FavouriteFruitsAnimationView.swift */; };
16+
88D9354C2A39D72300FD8AFF /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 88D9354B2A39D72300FD8AFF /* FirebaseAuth */; };
17+
88E5A79A2A39DDE400462B64 /* FavouriteFruitsNoAnimationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88E5A7992A39DDE400462B64 /* FavouriteFruitsNoAnimationsView.swift */; };
18+
88E5A79C2A39E11A00462B64 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 88E5A79B2A39E11A00462B64 /* GoogleService-Info.plist */; };
1619
88FBD98826B9485F00982BF2 /* FirestoreSampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88FBD98726B9485F00982BF2 /* FirestoreSampleApp.swift */; };
1720
88FBD98C26B9486100982BF2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 88FBD98B26B9486100982BF2 /* Assets.xcassets */; };
1821
88FBD98F26B9486100982BF2 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 88FBD98E26B9486100982BF2 /* Preview Assets.xcassets */; };
@@ -21,10 +24,12 @@
2124

2225
/* Begin PBXFileReference section */
2326
8809D0AE26B9520B00DE7864 /* firebase-ios-sdk */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "firebase-ios-sdk"; path = ../..; sourceTree = "<group>"; };
24-
8817084326B9593E009E9281 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
2527
88327B8726D62908002AA6D9 /* FavouriteFruitsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavouriteFruitsView.swift; sourceTree = "<group>"; };
2628
8844BA6026E0DD3F000786F0 /* FavouriteFruitsMappingErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavouriteFruitsMappingErrorView.swift; sourceTree = "<group>"; };
2729
88D5E37726EBD2F200808AFF /* FavouriteFruitsMappingErrorView2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavouriteFruitsMappingErrorView2.swift; sourceTree = "<group>"; };
30+
88D935492A39CB3E00FD8AFF /* FavouriteFruitsAnimationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FavouriteFruitsAnimationView.swift; sourceTree = "<group>"; };
31+
88E5A7992A39DDE400462B64 /* FavouriteFruitsNoAnimationsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavouriteFruitsNoAnimationsView.swift; sourceTree = "<group>"; };
32+
88E5A79B2A39E11A00462B64 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
2833
88FBD98426B9485F00982BF2 /* FirestoreSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FirestoreSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
2934
88FBD98726B9485F00982BF2 /* FirestoreSampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirestoreSampleApp.swift; sourceTree = "<group>"; };
3035
88FBD98B26B9486100982BF2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@@ -38,6 +43,7 @@
3843
buildActionMask = 2147483647;
3944
files = (
4045
8817084726B95A63009E9281 /* FirebaseFirestore in Frameworks */,
46+
88D9354C2A39D72300FD8AFF /* FirebaseAuth in Frameworks */,
4147
8817084926B95A63009E9281 /* FirebaseFirestoreSwift in Frameworks */,
4248
);
4349
runOnlyForDeploymentPostprocessing = 0;
@@ -84,7 +90,7 @@
8490
88FBD99526B948A100982BF2 /* App */,
8591
88FBD99626B948A900982BF2 /* Views */,
8692
88FBD98B26B9486100982BF2 /* Assets.xcassets */,
87-
8817084326B9593E009E9281 /* GoogleService-Info.plist */,
93+
88E5A79B2A39E11A00462B64 /* GoogleService-Info.plist */,
8894
88FBD98D26B9486100982BF2 /* Preview Content */,
8995
);
9096
path = FirestoreSample;
@@ -109,10 +115,12 @@
109115
88FBD99626B948A900982BF2 /* Views */ = {
110116
isa = PBXGroup;
111117
children = (
112-
88FBD99726B948E200982BF2 /* MenuView.swift */,
113118
88327B8726D62908002AA6D9 /* FavouriteFruitsView.swift */,
114119
8844BA6026E0DD3F000786F0 /* FavouriteFruitsMappingErrorView.swift */,
115120
88D5E37726EBD2F200808AFF /* FavouriteFruitsMappingErrorView2.swift */,
121+
88E5A7992A39DDE400462B64 /* FavouriteFruitsNoAnimationsView.swift */,
122+
88D935492A39CB3E00FD8AFF /* FavouriteFruitsAnimationView.swift */,
123+
88FBD99726B948E200982BF2 /* MenuView.swift */,
116124
);
117125
path = Views;
118126
sourceTree = "<group>";
@@ -136,6 +144,7 @@
136144
packageProductDependencies = (
137145
8817084626B95A63009E9281 /* FirebaseFirestore */,
138146
8817084826B95A63009E9281 /* FirebaseFirestoreSwift */,
147+
88D9354B2A39D72300FD8AFF /* FirebaseAuth */,
139148
);
140149
productName = FirestoreSample;
141150
productReference = 88FBD98426B9485F00982BF2 /* FirestoreSample.app */;
@@ -179,8 +188,8 @@
179188
isa = PBXResourcesBuildPhase;
180189
buildActionMask = 2147483647;
181190
files = (
191+
88E5A79C2A39E11A00462B64 /* GoogleService-Info.plist in Resources */,
182192
88FBD98F26B9486100982BF2 /* Preview Assets.xcassets in Resources */,
183-
8817084426B9593E009E9281 /* GoogleService-Info.plist in Resources */,
184193
88FBD98C26B9486100982BF2 /* Assets.xcassets in Resources */,
185194
);
186195
runOnlyForDeploymentPostprocessing = 0;
@@ -193,7 +202,9 @@
193202
buildActionMask = 2147483647;
194203
files = (
195204
88FBD99826B948E200982BF2 /* MenuView.swift in Sources */,
205+
88E5A79A2A39DDE400462B64 /* FavouriteFruitsNoAnimationsView.swift in Sources */,
196206
88327B8826D62908002AA6D9 /* FavouriteFruitsView.swift in Sources */,
207+
88D9354A2A39CB3E00FD8AFF /* FavouriteFruitsAnimationView.swift in Sources */,
197208
88FBD98826B9485F00982BF2 /* FirestoreSampleApp.swift in Sources */,
198209
88D5E37826EBD2F200808AFF /* FavouriteFruitsMappingErrorView2.swift in Sources */,
199210
8844BA6126E0DD3F000786F0 /* FavouriteFruitsMappingErrorView.swift in Sources */,
@@ -409,7 +420,11 @@
409420
};
410421
8817084826B95A63009E9281 /* FirebaseFirestoreSwift */ = {
411422
isa = XCSwiftPackageProductDependency;
412-
productName = "FirebaseFirestoreSwift";
423+
productName = FirebaseFirestoreSwift;
424+
};
425+
88D9354B2A39D72300FD8AFF /* FirebaseAuth */ = {
426+
isa = XCSwiftPackageProductDependency;
427+
productName = FirebaseAuth;
413428
};
414429
/* End XCSwiftPackageProductDependency section */
415430
};

Example/FirestoreSample/FirestoreSample/App/FirestoreSampleApp.swift

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,31 @@
1313
// limitations under the License.
1414

1515
import SwiftUI
16-
import Firebase
16+
import FirebaseCore
17+
import FirebaseFirestore
18+
import FirebaseAuth
1719

18-
@main
19-
struct FirestoreSampleApp: App {
20-
init() {
20+
class AppDelegate: NSObject, UIApplicationDelegate {
21+
func application(_ application: UIApplication,
22+
didFinishLaunchingWithOptions launchOptions: [UIApplication
23+
.LaunchOptionsKey: Any]? = nil) -> Bool {
2124
FirebaseApp.configure()
2225

26+
Firestore.firestore()
27+
.useEmulator(withHost: "localhost", port: 8080)
28+
2329
let settings = Firestore.firestore().settings
24-
settings.host = "localhost:8080"
2530
settings.isPersistenceEnabled = false
2631
settings.isSSLEnabled = false
2732
Firestore.firestore().settings = settings
33+
34+
return true
2835
}
36+
}
2937

38+
@main
39+
struct FirestoreSampleApp: App {
40+
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
3041
var body: some Scene {
3142
WindowGroup {
3243
NavigationView {

Example/FirestoreSample/FirestoreSample/Assets.xcassets/AppIcon.appiconset/Contents.json

Lines changed: 99 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,66 @@
150150
"scale" : "1x",
151151
"size" : "1024x1024"
152152
},
153+
{
154+
"filename" : "16.png",
155+
"idiom" : "mac",
156+
"scale" : "1x",
157+
"size" : "16x16"
158+
},
159+
{
160+
"filename" : "32.png",
161+
"idiom" : "mac",
162+
"scale" : "2x",
163+
"size" : "16x16"
164+
},
165+
{
166+
"filename" : "32.png",
167+
"idiom" : "mac",
168+
"scale" : "1x",
169+
"size" : "32x32"
170+
},
171+
{
172+
"filename" : "64.png",
173+
"idiom" : "mac",
174+
"scale" : "2x",
175+
"size" : "32x32"
176+
},
177+
{
178+
"filename" : "128.png",
179+
"idiom" : "mac",
180+
"scale" : "1x",
181+
"size" : "128x128"
182+
},
183+
{
184+
"filename" : "256.png",
185+
"idiom" : "mac",
186+
"scale" : "2x",
187+
"size" : "128x128"
188+
},
189+
{
190+
"filename" : "256.png",
191+
"idiom" : "mac",
192+
"scale" : "1x",
193+
"size" : "256x256"
194+
},
195+
{
196+
"filename" : "512.png",
197+
"idiom" : "mac",
198+
"scale" : "2x",
199+
"size" : "256x256"
200+
},
201+
{
202+
"filename" : "512.png",
203+
"idiom" : "mac",
204+
"scale" : "1x",
205+
"size" : "512x512"
206+
},
207+
{
208+
"filename" : "1024.png",
209+
"idiom" : "mac",
210+
"scale" : "2x",
211+
"size" : "512x512"
212+
},
153213
{
154214
"filename" : "48.png",
155215
"idiom" : "watch",
@@ -180,6 +240,13 @@
180240
"scale" : "3x",
181241
"size" : "29x29"
182242
},
243+
{
244+
"idiom" : "watch",
245+
"role" : "notificationCenter",
246+
"scale" : "2x",
247+
"size" : "33x33",
248+
"subtype" : "45mm"
249+
},
183250
{
184251
"filename" : "80.png",
185252
"idiom" : "watch",
@@ -196,6 +263,13 @@
196263
"size" : "44x44",
197264
"subtype" : "40mm"
198265
},
266+
{
267+
"idiom" : "watch",
268+
"role" : "appLauncher",
269+
"scale" : "2x",
270+
"size" : "46x46",
271+
"subtype" : "41mm"
272+
},
199273
{
200274
"filename" : "100.png",
201275
"idiom" : "watch",
@@ -204,6 +278,20 @@
204278
"size" : "50x50",
205279
"subtype" : "44mm"
206280
},
281+
{
282+
"idiom" : "watch",
283+
"role" : "appLauncher",
284+
"scale" : "2x",
285+
"size" : "51x51",
286+
"subtype" : "45mm"
287+
},
288+
{
289+
"idiom" : "watch",
290+
"role" : "appLauncher",
291+
"scale" : "2x",
292+
"size" : "54x54",
293+
"subtype" : "49mm"
294+
},
207295
{
208296
"filename" : "172.png",
209297
"idiom" : "watch",
@@ -229,70 +317,24 @@
229317
"subtype" : "44mm"
230318
},
231319
{
232-
"filename" : "1024.png",
233-
"idiom" : "watch-marketing",
234-
"scale" : "1x",
235-
"size" : "1024x1024"
236-
},
237-
{
238-
"filename" : "16.png",
239-
"idiom" : "mac",
240-
"scale" : "1x",
241-
"size" : "16x16"
242-
},
243-
{
244-
"filename" : "32.png",
245-
"idiom" : "mac",
246-
"scale" : "2x",
247-
"size" : "16x16"
248-
},
249-
{
250-
"filename" : "32.png",
251-
"idiom" : "mac",
252-
"scale" : "1x",
253-
"size" : "32x32"
254-
},
255-
{
256-
"filename" : "64.png",
257-
"idiom" : "mac",
258-
"scale" : "2x",
259-
"size" : "32x32"
260-
},
261-
{
262-
"filename" : "128.png",
263-
"idiom" : "mac",
264-
"scale" : "1x",
265-
"size" : "128x128"
266-
},
267-
{
268-
"filename" : "256.png",
269-
"idiom" : "mac",
320+
"idiom" : "watch",
321+
"role" : "quickLook",
270322
"scale" : "2x",
271-
"size" : "128x128"
272-
},
273-
{
274-
"filename" : "256.png",
275-
"idiom" : "mac",
276-
"scale" : "1x",
277-
"size" : "256x256"
323+
"size" : "117x117",
324+
"subtype" : "45mm"
278325
},
279326
{
280-
"filename" : "512.png",
281-
"idiom" : "mac",
327+
"idiom" : "watch",
328+
"role" : "quickLook",
282329
"scale" : "2x",
283-
"size" : "256x256"
284-
},
285-
{
286-
"filename" : "512.png",
287-
"idiom" : "mac",
288-
"scale" : "1x",
289-
"size" : "512x512"
330+
"size" : "129x129",
331+
"subtype" : "49mm"
290332
},
291333
{
292334
"filename" : "1024.png",
293-
"idiom" : "mac",
294-
"scale" : "2x",
295-
"size" : "512x512"
335+
"idiom" : "watch-marketing",
336+
"scale" : "1x",
337+
"size" : "1024x1024"
296338
}
297339
],
298340
"info" : {

0 commit comments

Comments
 (0)