I'm trying to observe change of an NSMutableOrderedSet in my ViewModel with combine. I want to know when some element is added or removed of NSMutableOrderedSet
Some code of my ViewModel :
class TrainingAddExerciceViewModel: ObservableObject {
				
				@Published var exercice: Exercice?
				@Published var serieHistories = NSMutableOrderedSet()
		
		...
			init(...) {
				...
				
//Where i'm trying to observe
				$serieHistories
						.sink { (value) in
								print(value)
				}
				.store(in: &self.cancellables)
		}
		
		}
This is the function I use in my ViewModel to add element to NSMutableOrderedSet :
func add(managedObjectContext: NSManagedObjectContext) {
				let newSerieHistory = ExerciceSerieHistory(context: managedObjectContext)
				self.serieHistories.add(newSerieHistory)
				self.updateView()
		}
I have some other publisher working well with an other type (custom class).
Did I miss something ?
Thanks
Post
Replies
Boosts
Views
Activity
I'm trying to update a SwiftUI (sub) view on property update of NSManagedObject (Training).
The property is an NSOrderedSet (exerciceHistories).
Piece of Training class : extension Training {
...
@NSManaged public var date: Date
@NSManaged public var exerciceHistories: NSOrderedSet
}
The main view is TrainingDetail, displaying detail of Training :struct TrainingDetail: View {
@Environment(\.managedObjectContext) var managedObjectContext
@ObservedObject var training: Training
...
var body: some View {
ZStack {
...
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 0) {
...
TrainingDetailAction(training: training, new: new) //-> View that creates sheet to edit one element of training property NSOrderedSet (exerciceHistories)
TrainingDetailExercices(training: training, editing: $new) //-> View displaying training property NSOrderedSet (exerciceHistories)
.padding()
}}
....
}
...
}
}
Interesting part of TrainingDetailExercices, where editing sheet is opened :struct TrainingDetailExercices: View {
@Environment(\.managedObjectContext) var managedObjectContext
@ObservedObject var training: Training
var body: some View {
...
ForEach(training.exerciceHistories.array as! [ExerciceHistory], id: \.self) {
exerciceHistory in
ExerciceHistoryRow(exerciceHistory: exerciceHistory)
.padding(.bottom, 10)
}.sheet(isPresented: $showEditView, onDismiss: {
...
}, content: {
TrainingAddExercice(training: self.training, ...)
.environment(\.managedObjectContext, self.managedObjectContext)
})
TrainingAddExercice that is the sheet displayed, where we can edit one element of training property NSOrderedSet (exerciceHistories):struct TrainingAddExercice: View {
...
@ObservedObject private var trainingAddExerciceViewModel: TrainingAddExerciceViewModel
@ObservedObject var training: Training
...
}
The function that save and close sheet in TrainingAddExercice :
	private func trailingNavButtons() -> some View {
								HStack{
										....
										
										Button(action: {
												self.trainingAddExerciceViewModel.save(exerciceHistory: self.exerciceHistory, to: self.managedObjectContext, for: self.training)
				
/*here I'm trying to force update by creating a new NSMutableOrderedSet and assign it to training (because NSMutableOrderedSet is class, not struct) */
let newExercicesHistories = NSMutableOrderedSet(orderedSet: self.training.exerciceHistories)
												self.training.exerciceHistories = newExercicesHistories
												self.show = false
									
			}, label: {
										...
								}).disabled(...)
						}
				}
One thing I don't understand is that when I'm adding/deleting one ExerciceHistory to/of training.exerciceHistories, view updates but not when I'm editing one even so I'm trying to force by creating new OrderedSet.
Object is well update in CoreData.
I'm in ExerciceList view when I tap an ExerciceRow of my list I push new view ExerciceDetail.
ExerciceDetail view displays a VStack with some other rows produced by some calculs that taking time and make transition between ExerciceList and one ExerciceDetail not smooth.
Is there any way to reproduce lazy loading on some VStack like LazyVStack (in SwiftUI 2) with SwiftUI 1 without using list ?
I have a simple pattern : a list view with a detail view. Both have navigation bar item.
Problem:
Only on the detail view when I rotate the screen to landscape, the navigation bar item disappears and will never appear anymore even If I rotate back. This bug occurs only on iOS14.
ListView : NavigationView{
		ZStack{
(List and NavigationLink...)
}.navigationBarItems(trailing: Button(...))
.sheet(someSheet...)
}.navigationViewStyle(StackNavigationViewStyle())
DetailView :
		ZStack {
				(someView...)
				.navigationBarTitle(...)
				.navigationBarItems(trailing: Button(...))
				.sheet(someSheet...)
		}
My app on AppStore got two crashes that look very similar.
This crash seems to append when I call function that use a environnement object SubscriptionManager.
By analysing the error stack I think It happens in the function safeAddExercice() when I try to get self.subscriptionManager that is the environnement object.
These are errors stacks :
Crash1 - https://developer.apple.com/forums/content/attachment/47ab2bc3-fee7-4c69-a5a0-0fcf30cf2c36
Crash2 - https://developer.apple.com/forums/content/attachment/7ed9987f-45cf-4a03-8849-ad9b01e6644f
That is the function safeAddExercice() : private func safeAddExercice() {
if Exercice.canAddNew(for: self.subscriptionManager) {
self.showExerciceAdd = true
}else{
self.showMember = true
}
}
It's a function of ExerciceList : struct ExerciceList: View {
//some other environnement objects...
@EnvironmentObject var subscriptionManager: SubscriptionManager
...
}
ExerciceList is an item of TabBar : struct MainApp: View {
//some other envObjects...
@EnvironmentObject var subscriptionManager: SubscriptionManager
...
var body: some View {
UIKitTabView{
ExerciceList(selection: .constant(nil))
.environment(\.managedObjectContext, managedObjectContext)
.environmentObject(userSettings)
.environmentObject(subscriptionManager)
.tab(title: NSLocalizedString("My exercises", comment: ""), image: "dumbell")
...}
}
SubscriptionManager is instantiated in AppDelegate : var subscriptionManager: SubscriptionManager = {
				SubscriptionManager()
		}()
And pass to `MainApp` in `SceneDelegate`:
let subscriptionManager = (UIApplication.shared.delegate as! AppDelegate).subscriptionManager
let contentView = MainApp().environment(\.managedObjectContext, context)
.environmentObject(subscriptionManager)
...
Crash appends both on iOS 13 and 14. I try to find a moment where I missed to inject object but I'm struggling a bit to find something.
I work on iOS App project in workspace. I splitted feature in a Local Swift Package.
Workspace contains both iOS App Project and Swift Package.
https://i.stack.imgur.com/LhL5j.jpg
Swift package platform is iOS 14 and deployment target of project is iOS 13.
I put optional link on my Swift Package to avoid crash on iOS 13
https://i.stack.imgur.com/Y1HYb.png
Application run well on iOS 14 but still crash on iOS 13 :
dyld: Symbol not found: _$s7SwiftUI4ViewP14_viewListCount6inputsSiSgAA01_ceF6InputsV_tFZTq
Just for example, I would like to use Swift Package like this :
Swift
#if canImport(Classifier)
@available(iOS 14.0, *)
struct ActionClassifier: View {
var body: some View {
Text("Hello, World!")
}
}
#endif
Did I miss something on the way of link my Swift Package Binary to my project ?