Last active
March 13, 2023 09:21
-
-
Save yimajo/48495479a1d11417423b6f2dfbed85b1 to your computer and use it in GitHub Desktop.
An example of using TCA FirestoreClient with Firestore ios sdk automatically bridged from Objective-C to Swift Concurrency.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import ComposableArchitecture | |
import FirebaseFirestore | |
import FirebaseFirestoreSwift | |
// MARK: - FirestoreClient | |
struct FirestoreClient { | |
enum Input { | |
enum Create { | |
struct Food { | |
typealias ID = String | |
let name: String | |
let bestBeforeDate: Date | |
let userID: ID | |
} | |
} | |
} | |
var createFood: (Input.Create.Food, CollectionReference) async throws -> FirestoreEntity.FoodID | |
} | |
extension FirestoreClient { | |
static let liveValue = Self.live() | |
static func live() -> Self { | |
let firestore = Firestore.firestore() | |
let foodStorageCollectionName = "/foodStorages" | |
return Self( | |
createFood: { food, collectionReference in | |
// Objective-C completion handlers are automatically converted to async functions. | |
// https://github.com/apple/swift-evolution/blob/main/proposals/0297-concurrency-objc.md | |
let reference = try await collectionReference.addDocument( | |
data: try Firestore.Encoder().encode( | |
FirestoreEntity.Food( | |
name: food.name, | |
bestBeforeDate: food.bestBeforeDate | |
) | |
) | |
) | |
return reference.documentID | |
} | |
) | |
} | |
} | |
// MARK: - For SwiftUI Preview | |
extension FirestoreClient { | |
public static let noop = Self( | |
createFood: { _, _ in try await Task.never()} | |
) | |
} | |
// MARK: - For Dependencies | |
enum FirestoreClientKey: DependencyKey { | |
static let liveValue = FirestoreClient.liveValue | |
static let previewValue = FirestoreClient.noop | |
} | |
extension DependencyValues { | |
var firestoreClient: FirestoreClient { | |
get { self[FirestoreClientKey.self] } | |
set { self[FirestoreClientKey.self] = newValue } | |
} | |
} | |
// MARK: - FirestoreEntity | |
enum FirestoreEntity {} | |
extension FirestoreEntity { | |
typealias FoodID = String | |
struct Food: Equatable, Encodable, Decodable, Identifiable { | |
@DocumentID var id: FoodID? | |
@ServerTimestamp var createdDate: Timestamp? | |
let name: String | |
let bestBeforeDate: Date | |
} | |
} | |
extension FirestoreEntity.Food { | |
init(name: String, date: Date) { | |
self.name = name | |
self.bestBeforeDate = date | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment