📦 SwiftyLaunch Modules
🗄️ DatabaseKit
DBKit Usage Example

DatabaseKit (DBKit) Usage Example

DatabaseKit (SwiftyLaunch Module) - Usage Example

This example demonstrates how to use the DB environment object to interact with the database in your app.

Features

  • Create a Post: Create a new post with a title and description. Anonymously or with a shared User ID.
  • Browse Posts: See posts created by all other users.
  • Delete Posts: Delete your posts or posts of other users.
  • AnalyticsKit Integration: If AnalyticsKit is selected during project generation, events and errors regarding user interacting with the DBKit Example will automatically be tracked with db as the source.

Demo

Here's a demo of the DBKit example in action:

Deep Dive

Definitions

The example defines a bunch of functions and parameters that are used to interact with the database.

Posts Collection

An array that contains fetched posts from the database.

FirebaseBackend.swift
@MainActor
public class DB: ObservableObject {
    @Published var posts: [PostData] = []
}

Is of type PostData:

FirebaseBackend.swift
struct PostData: Codable, Identifiable, Equatable {
	@DocumentID var id: String?
	let title: String
	let content: String
	let creationDate: Date
	let postUserID: String?
}

Fetching Posts

The fetchPosts() function fetches all posts from the database and sets the posts array.

FirebaseBackend.swift
extension DB {
    @MainActor
	public func fetchPosts() async { }
}

Creating a Post (Anonymously)

The addPost() function creates a new post with a title and content. The resulting postUserID in the post is set to Anonymous. Returns a bool value depending on the success of the operation.

FirebaseBackend.swift
extension DB {
    public func addPost(title: String, content: String) async -> Bool { }
}

Creating a Post (With User ID)

The addSignedPost() function creates a new post with a title and content. The resulting postUserID in the post is set to currently logged in user (see AuthKit).

FirebaseBackend.swift
extension DB {
    public func addSignedPost(title: String, content: String) async -> Bool { }
}

Deleting a Post

The deletePost() function deletes a post with a given id. Returns a bool value depending on the success of the operation. Note that any user can delete any post. (But we actually prevent doing that in the UI using the executeIfSignedIn function. See below).

FirebaseBackend.swift
extension DB {
    public static func deletePost(id: String) async { }
}

Usage

In the DatabaseExampleView, we use the DB object and its variables and functions (defined above) to interact with the database.

  • When the view appears, we fetch all posts from the database using the fetchPosts() function.
  • We show each post in a List, by passing the db.posts array to the ForEach loop.
  • We have a Button to delete a post by calling db.deletePost(). We pass it to the executeIfSignedIn function to prevent deleting posts of other users. This function is used to execute a block of code only if the user is signed in. After that we fetch all posts again.
  • In the toolbar we have a navigation link that opens the PostCreationView to create a new post. After creating a post, we fetch all posts again.
DatabaseExampleView.swift
 
public struct DatabaseExampleView: View {
	@EnvironmentObject var db: DB
    // ...
	public var body: some View {
		NavigationStack(path: /* ... */) {
			List {
				// ...
				ForEach(db.posts) { post in
                    // Below is a single post view
					Section(
                        // Post Creation Date and User ID ("Anonymous" if nil)
						footer: Text(
							"\(post.creationDate.description) | by \(post.postUserID ?? "Anonymous")")
					) {
						HStack {
							Text(post.title)
 
							// ...
 
							Button(role: .destructive) {
								Task {
									await db.executeIfSignedIn(withUserID: post.postUserID) {
										await db.deletePost(id: post.id!)
									}
									await db.fetchPosts()
								}
							} label: {
								Image(systemName: "trash")
							}
 
						}
						Text(post.content)
					}
				}
			}
			// ...
 
			// Fetch Data when View Appears
			.onAppear {
				// ...
				await db.fetchPosts()
				// ...
			}
 
			// ... pull down to refresh
 
			.toolbar {
				// ...
				NavigationLink(value: DBExamplePath.postNew) {
					Image(systemName: "square.and.pencil")
				}
			}
			.navigationDestination(for: /* ... */) { path in
                // ...
                PostCreationView {
                    // ...
                    await db.fetchPosts()
                    // ...
                }
			}
		}
	}
}