NSManagedObject relationship changes handling
All CoreData objects are ObservableObject
s if you want to see changes you have to wrap them in a @ObservedObject
.
To do this make subviews that take profile
, wallet
, and balance
as a parameter vs having all those variables with your subviews.
Why does @Published not work in NSManagedObject?
The solution is to add a transient Core Data attribute. Transient attributes are published but not persisted.
Alternatively, you can publish changes like this:
class Data2: NSManagedObject {
@Published var direction: Direction = .left { // @Published is optional
willSet {
objectWillChange.send()
}
}
}
SwiftUI: trigger redraw when NSManagedObject (not part of fetch request) bool property changes?
Move it all into a sub-View and use @ObservedObject
like this:
struct DealerSection : View {
@ObservedObject var dealer: Dealer // body will be called when dealer changes.
var body: some View {
Section(header: DealerSHView(dealer: dealer)) {
if dealer.isOpen {
ForEach(section) { channel in
....
}
} else {
....
}
}
}
Then in your parent View's body it's just:
ForEach(carsResult) { section in
if let dealer = section.first?.dealer {
DealerSection(dealer: dealer)
}
}
SwiftUI update view on core data object change
Try to observe Asset
(cause NSManagedObject
is-a ObservableObject
)
struct AssetRowView: View {
@ObservedObject var asset: Asset // << here !!
var body: some View {
HStack {
Text(asset.name)
Text(asset.assetDescription)
}
}
}
if that will not be enough, also might be needed to update Done
button action as
}, trailing: Button("Done") {
self.asset.objectWillChange.send() // << here !!
self.asset.name = self.name
self.asset.assetDescription = self.description
try? self.moc.save()
// better do this at the end of activity
self.presentationMode.wrappedValue.dismiss()
}
Core data not triggering immediate refresh with SwiftUI
I used the approach suggested by jnpdx and it works.
import SwiftUI
class PointsViewModel: ObservableObject {
@Published var points = [Point]()
func movePoint(index: Int, x: CGFloat, y: CGFloat) {
points[index].x = x
points[index].y = y
objectWillChange.send()
}
}
struct RedrawEdgeTestCoreData: View {
@Environment(\.managedObjectContext) private var viewContext
@ObservedObject var viewModel: PointsViewModel
@State var originalPosition: CGPoint? = nil
private var movePointDragGesture: some Gesture {
DragGesture(minimumDistance: 0, coordinateSpace: .local)
.onChanged { value in
if viewModel.points.isEmpty {
return
}
if originalPosition == nil {
originalPosition = CGPoint(x: viewModel.points.last!.x, y: viewModel.points.last!.y)
}
let lastIndex = viewModel.points.count - 1
viewModel.movePoint(index: lastIndex, x: originalPosition!.x + value.translation.width, y: originalPosition!.y + value.translation.height)
}
.onEnded { value in
originalPosition = nil
}
}
private var addNewPointGesture: some Gesture {
TapGesture(count: 2)
.onEnded {
viewModel.points.append(Point(context: viewContext))
}
}
var body: some View {
GeometryReader { geometry in
ZStack {
ShapeTest(points: viewModel.points.map { CGPoint(x: $0.x, y: $0.y) })
.stroke()
}
.contentShape(Rectangle())
.gesture(movePointDragGesture.simultaneously(with: addNewPointGesture))
}
}
}
struct RedrawEdgeTestCoreData_Previews: PreviewProvider {
static var previews: some View {
RedrawEdgeTestCoreData(viewModel: PointsViewModel())
.environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
}
}
FetchedResults won't trigger and SwiftUI update but the context saves it successfully
If first code block is a part of ObservableObject, then it does not look that third block, view one, depends on it, and if there is no changes in dependencies, view is not updated.
Try this approach.
But if there are dependencies, which are just not provided then change order of save and publisher as
try context.save()
self.objectWillChange.send()
Related Topics
Swift Extension on Generic Struct Based on Properties of Type T
Swift 2.0 Get Mirrored Superclass Properties
In Swift, Does Int Have a Hidden Initializer That Takes a String
Enumerate Is Unavailable Call the Enumerate Method on the Sequence
How to Convert Hexstring to Bytearray in Swift 3
Nstimer.Scheduledtimerwithtimeinterval in Swift Playground
How to Subclass Nsoperation in Swift to Queue Skaction Objects for Serial Execution
Uibarbuttonitem Selector Not Working
Making Swift Generics Play with Overloaded Functions
How Do Generators Whose Element Is Optional Know When They'Ve Reached the End
Swiftui - Add Border to One Edge of an Image
iOS 11 Large Title Navigation Bar Snaps Instead of Smooth Transition
Using Scenekit in Swift Playground
Adding Swift 3 Packages to Xcode 8 Using the Swift Package Manager