Post

Replies

Boosts

Views

Activity

Reply to How to access SwiftData from a background thread?
@DTS Engineer Thanks for the reply, some followup questions With respect to (2): It seems from the other thread that UI updates could be bugged still. But what is the intended behaviour when it eventually get fixed? Is @Query suppose to update from changes made from other modelContexts? And vice versa? Because if that is not the intended design, and our project requires it, we might be better off going back to core data. With respect to (3): Please comment. Is icloud sync suppose to trigger for changes made both in @Query modelContext and ModelActor's custom modelContext? (both pointed to the same container).
Sep ’24
Reply to How to access SwiftData from a background thread?
@DTS Engineer sorry I encounter another architecture question: I have been studying ModelActor and I'm trying to create one so that I can do SwiftData operations in the background (say after a network call). But according to this video https://www.youtube.com/watch?v=VG4oCnQ0bfw it seems the ModelActor itself needs to be created in the background off the main thread. I want to create one actor to be used throughout the app, and not create a new actor for each background operation. How could I do that? At first, a naive approach might be import Foundation actor ModelActor { // Your ModelActor properties and methods } class ModelActorService { static let shared = ModelActorService() private(set) var modelActor: ModelActor? private init() { // Initialize on a background queue DispatchQueue.global(qos: .background).async { self.modelActor = ModelActor() } } } // ViewModel example class SomeViewModel: ObservableObject { private let modelActor: ModelActor init(modelActor: ModelActor = ModelActorService.shared.modelActor!) { self.modelActor = modelActor } // ViewModel methods using modelActor } but that won't work because the creation of the actor is async and there's no guarantee that it would actually be ready when the viewModel wants to use it. How do I setup a actor facility that is global, created in the background, that can be used by various viewModels for background data operations?
Sep ’24
Reply to Is there a way to update Observable on the main thread but not to read from it?
Now I've asked chatgpt if there is a hack we can do to alleviate this problem by making write on the mainthreads but allow read to be from any thread. It came up with this solution: import Foundation class UserModel { private var _name: String private var _age: Int private let queue = DispatchQueue.main // Queue to ensure writes happen on the main thread init(name: String, age: Int) { self._name = name self._age = age } // Custom getter allows read access from any thread var name: String { return _name } var age: Int { return _age } // Custom setter ensures writes happen on the main thread func update(name: String, age: Int) { if Thread.isMainThread { self._name = name self._age = age } else { queue.async { self._name = name self._age = age } } } } @Observable class UserViewModel { private var _userModel: UserModel private let queue = DispatchQueue.main init(userModel: UserModel) { self._userModel = userModel } // Custom getter for the UserModel allows reads from any thread var userModel: UserModel { return _userModel } // Custom setter ensures writes happen on the main thread func updateUserModel(name: String, age: Int) { if Thread.isMainThread { _userModel.update(name: name, age: age) } else { queue.async { self._userModel.update(name: name, age: age) } } } } // NetworkManager can now read from any thread and only needs to jump to the main thread for writes class NetworkManager { func updateUserInfo(viewModel: UserViewModel) { Task { // Read values from UserModel without jumping to the main thread let userName = viewModel.userModel.name let userAge = viewModel.userModel.age print("Making network call with userName: \(userName) and userAge: \(userAge)") // Simulate network delay try await Task.sleep(nanoseconds: 1_000_000_000) // After the network call, update the UserModel on the main thread viewModel.updateUserModel(name: "Jane Doe", age: 31) } } } // Example usage let userModel = UserModel(name: "John Doe", age: 30) let viewModel = UserViewModel(userModel: userModel) let networkManager = NetworkManager() // Calling from a background thread Task { await networkManager.updateUserInfo(viewModel: viewModel) } Essentially wrapping each state with an internal backing and then controlling read and write. Does this approach have any issues? I dont trust chatgpt.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Oct ’24
Reply to Driving NavigationSplitView with something other than List?
Any Solution?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Apr ’23
Reply to Widgetkit's getTimeline is causing crash at completion(timeline)
@darkpaw why would that make a difference? I'm confused. The variable is indeed a bool otherwise compiler wont let it
Topic: App & System Services SubTopic: General Tags:
Replies
Boosts
Views
Activity
Aug ’23
Reply to @Environment(\.dismiss) var dismiss - Infinite loop bug.
dont use it ever, it loops like crazy. Just use UIKit to dismiss, thats what I do
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’23
Reply to SwiftData fatal error "Never access a full future backing data"
Is this something they will fix or we have to find workaround?
Topic: UI Frameworks SubTopic: General Tags:
Replies
Boosts
Views
Activity
Aug ’24
Reply to How to access SwiftData from a background thread?
@DTS Engineer Thanks for the reply, some followup questions With respect to (2): It seems from the other thread that UI updates could be bugged still. But what is the intended behaviour when it eventually get fixed? Is @Query suppose to update from changes made from other modelContexts? And vice versa? Because if that is not the intended design, and our project requires it, we might be better off going back to core data. With respect to (3): Please comment. Is icloud sync suppose to trigger for changes made both in @Query modelContext and ModelActor's custom modelContext? (both pointed to the same container).
Replies
Boosts
Views
Activity
Sep ’24
Reply to How to access SwiftData from a background thread?
@DTS Engineer thanks but can you confirm (3) Do changes made in a background ModelActor trigger a icloud sync?
Replies
Boosts
Views
Activity
Sep ’24
Reply to How to access SwiftData from a background thread?
@DTS Engineer thanks and I guess more a generic question, is ModelActor the intended approach to do SwfitData operations in the background? (like the scenario I outlined in the original post). Like am I on the right track?
Replies
Boosts
Views
Activity
Sep ’24
Reply to How to access SwiftData from a background thread?
@DTS Engineer sorry I encounter another architecture question: I have been studying ModelActor and I'm trying to create one so that I can do SwiftData operations in the background (say after a network call). But according to this video https://www.youtube.com/watch?v=VG4oCnQ0bfw it seems the ModelActor itself needs to be created in the background off the main thread. I want to create one actor to be used throughout the app, and not create a new actor for each background operation. How could I do that? At first, a naive approach might be import Foundation actor ModelActor { // Your ModelActor properties and methods } class ModelActorService { static let shared = ModelActorService() private(set) var modelActor: ModelActor? private init() { // Initialize on a background queue DispatchQueue.global(qos: .background).async { self.modelActor = ModelActor() } } } // ViewModel example class SomeViewModel: ObservableObject { private let modelActor: ModelActor init(modelActor: ModelActor = ModelActorService.shared.modelActor!) { self.modelActor = modelActor } // ViewModel methods using modelActor } but that won't work because the creation of the actor is async and there's no guarantee that it would actually be ready when the viewModel wants to use it. How do I setup a actor facility that is global, created in the background, that can be used by various viewModels for background data operations?
Replies
Boosts
Views
Activity
Sep ’24
Reply to Failed to launch app in reasonable time Xcode 16
accepted answer works, but pls fix xcode
Replies
Boosts
Views
Activity
Sep ’24
Reply to Is there anything wrong in operating with ModelContainer.mainContext?
@DTS Engineer Thanks for the tips, if thats the case, operations inside the viewModel should be mainactor isolated as well right? For example @Observable class SettingsViewModel { var modelContainer: ModelContainer ... @MainActor func test() { ... modelContainer.mainContext.insert(model) modelContainer.mainContext.save() }
Replies
Boosts
Views
Activity
Sep ’24
Reply to .transformable with ValueTransformer failing after Xcode 15.1 update
Does anyone have a workaround for this? I'm using Version 16.0 with iOS18 simulator, same error. So I cannot use transformer at all? Or is this a simulator issue and works on regular devices?
Replies
Boosts
Views
Activity
Oct ’24
Reply to how can I discern which SwiftData object trigger the .NSManagedObjectContextDidSave notification ?
If we have to target iOS17, what would be the solution here?
Replies
Boosts
Views
Activity
Oct ’24
Reply to ValueTransformer currently crashes XCode SwiftUI preview
After some more investigation turns out this code crashes in preview because my Previews were ran in iOS17. So I guess the question remains, why does this code works in iOS18 but not in iOS17 even though it doesn't use any iOS18 specific APIs?
Replies
Boosts
Views
Activity
Oct ’24
Reply to Is there a way to update Observable on the main thread but not to read from it?
Now I've asked chatgpt if there is a hack we can do to alleviate this problem by making write on the mainthreads but allow read to be from any thread. It came up with this solution: import Foundation class UserModel { private var _name: String private var _age: Int private let queue = DispatchQueue.main // Queue to ensure writes happen on the main thread init(name: String, age: Int) { self._name = name self._age = age } // Custom getter allows read access from any thread var name: String { return _name } var age: Int { return _age } // Custom setter ensures writes happen on the main thread func update(name: String, age: Int) { if Thread.isMainThread { self._name = name self._age = age } else { queue.async { self._name = name self._age = age } } } } @Observable class UserViewModel { private var _userModel: UserModel private let queue = DispatchQueue.main init(userModel: UserModel) { self._userModel = userModel } // Custom getter for the UserModel allows reads from any thread var userModel: UserModel { return _userModel } // Custom setter ensures writes happen on the main thread func updateUserModel(name: String, age: Int) { if Thread.isMainThread { _userModel.update(name: name, age: age) } else { queue.async { self._userModel.update(name: name, age: age) } } } } // NetworkManager can now read from any thread and only needs to jump to the main thread for writes class NetworkManager { func updateUserInfo(viewModel: UserViewModel) { Task { // Read values from UserModel without jumping to the main thread let userName = viewModel.userModel.name let userAge = viewModel.userModel.age print("Making network call with userName: \(userName) and userAge: \(userAge)") // Simulate network delay try await Task.sleep(nanoseconds: 1_000_000_000) // After the network call, update the UserModel on the main thread viewModel.updateUserModel(name: "Jane Doe", age: 31) } } } // Example usage let userModel = UserModel(name: "John Doe", age: 30) let viewModel = UserViewModel(userModel: userModel) let networkManager = NetworkManager() // Calling from a background thread Task { await networkManager.updateUserInfo(viewModel: viewModel) } Essentially wrapping each state with an internal backing and then controlling read and write. Does this approach have any issues? I dont trust chatgpt.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Oct ’24
Reply to Why aren't changes to @Published variables automatically published on the main thread?
I have a related question to this topic, I elaborated it in details here https://developer.apple.com/forums/thread/766805?page=1#810190022 @DTS Engineer / Quinn any chance we can get your help here :(
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Oct ’24