1 - Active Record (like Data Mapper or Repository) is a pattern, very popular, for data access, we use where needed, I use some example to show that model is not only property’s structs. For a library you can use Product, Order as active record but for an app you should include a ProductStore (state), OrderStore (state)… also you can implement all Product, Order tasks on Store and not use Product, Order as active record at all. Remember: typically a framework, like StoreKit 2, need to be flexible, more stateless. A framework is used by an app. For an app like SwiftUI you need one or more state objects, stateful.
2 - Yes, objectWillChange.send() do the @Published job, also @Published is a convenience for objectWillChange.send() and use it. See 2019 post about this, initially (SwiftUI betas)we don’t have @Published. Forget in last posts, you should call objectWillChange.send() before you change the property, not after, be careful with asyncs stuffs.
@Published var selectedFolder: Folder? = nil
=
var selectedFolder: Folder? = nil {
willSet {
objectWillChange.send()
}
}
3 - Yes!
4 - As I said in 1 point, you can handle everything on ObservableObject and keep only property structs, and just add some needed tasks to structs.
struct Product {
// Properties (data)
// Tasks
func purchase() async throws { ... }
// Factory Method
static products: [Self] {
get async throws {
return try await WebService.shared.request(…)
}
}
}
class ProductStore: ObservableObject {
@Published var products: [Product] = []
func load() async {
do {
products = try await Product.products
} catch {
// handle error
}
}
}
or
struct Product {
// Properties (data)
// Tasks
func purchase() async throws { ... }
}
class ProductStore: ObservableObject {
@Published var products: [Product] = []
func load() async {
do {
products = try await WebService.shared.request(…)
} catch {
// handle error
}
}
}
or
struct Product {
// Properties (data)
}
class ProductStore: ObservableObject {
@Published var products: [Product] = []
func purchase(_ product: Product) async throws { ... }
func load() async {
do {
products = try await WebService.shared.request(…)
} catch {
// handle error
}
}
}
5 - In active record you use static func / vars for “Factory Method”, not single instance. For this pattern you only use shared (single instance) for your service / provider objects (e.g. WebService.shared.request(…)). And in general for SwiftUI you should avoid singleinstance for non service / provider objects, use @EnvironmentObject.