hi,i've seen this type of behaviour come and go during some development, but not for some time now. and everytime i think i fixed it ... whether i knew what i was doing or not ... it involved tweaking the Identifiability of an object and the ForEach thing.i would suggest that if you want to conform to Identifiable, that you not rely on the objectID from CoreData (i think this can change over time, and it certainly changes from run to run). instead, put a real id field in your CoreData entities, and set id = UUID() upon creation. see if that helps.also, i'd wait a little for Swift 2.0 to come out (in about 7-8 days) to see what we find out about navigation changes. if you're using @FetchRequest, i think there will be changes there (at least internally). and, maybe some documentation ⚠EDIT: (added after posting) don't worry too much about "table laying out ..." messages. SwiftUI is certainly built on top of UIKit. most everyone ignores messages like this these days. wait for Swift 2.0)hope that helps,DMG
Post
Replies
Boosts
Views
Activity
hi,"what KMT said." wait for Swift 2.0.for what it's worth, perhaps the functionality of View thing > Edit thing could be redesigned into a single View? i have a simple project that i put out in public (while i am still learning SwiftUI and have no real idea where it will lead) where i have joined these functionalities. there is also a button in the combined View/Edit thing that deletes the object and returns to the list of things. it uses CoreData for persistence -- which means that some things are a little magical because of the use of @FetchRequest and the fact that CoreData objects are already ObservableObjects -- but the concept is right, i think. look at h ttps://github.com/DelawareMathGuy/ShoppingList.***added as an after-thought. your Edit thing could return to your View thing, with edits showing in some obvious fashion, which could then prominently display a "save the changes you made to this View thing" before going back up the navigation stack to your List of things?hope that helps,DMG
hi Dude,are you trying to store 2D and 3D arrays of other CoreData entities, or are you trying to store 2D and 3D arrays of arrays of (arrays of) Strings, Ints, or something simple like that?if it's the latter, think about a CoreData entity having an attribute of type Transformable, with its custom type set, for example, to [[String]] for a 2D array of strings (this is Swift syntax). i have used this idea several times before for 1D arrays of UUIDs and of Strings (these are all transformable compliant without any extra work), but haven't encountered a 2D situation; perhaps everything will work equally well for you in a higher dimension? i'd be curious to find out.alternatively, consider writing your arrays either as json (think Codable), and put that in CoreData, or otherwise writing your own transformer code.hope that helps,DMG
hi Thomas (and readers)i probably have some experience on this project, since you asked yesterday in the HackingWithSwift forums about adding a search bar to this project and i did look through it.i've posted some code for you to look at this project on github: delawaremathguy/Thomas. basically, let's address only one thing here that you are asking about in this post:to get your code to save correctly, you have to update the userData.movies array and then write it out. i don't think you were doing that in your project as i saw it yesterday -- you were updating an individual movie, but not updating its entry in the userData movies array. the code to read and write to your documents directory is working fine -- you just kept writing out the same thing with no changes.for the code that i have posted above, i've added a few lines here and there to be sure to get this done, as well as to incorporate some code i posted yesterday on HWS (albeit slightly modified) so that the search bar works as well.as for the other thing, welll that's a different matter. doing one big list is what i have shown in the code; but getting lists to section out (dynamically, as data changes) is a little more tedious in SwiftUI, so i would defer that for now, work on other parts of your project, and hope that SwiftUI 2.0 will make it easier.hope that helps,DMG
hi greay,if you have something out on Github, or one of the other hosting sites, i would take a look at it. i've been frustrated myself several times by this general problem: data structure A changes and, even though you have some combination of @State, @Binding, @ObservableObject, @ObservedObject, and @Published scattered around in your code, a view that relies on A does not appear to update. your situation of "first time works, the others don't" is particularly puzzling.looking forward to anything you might post, and hope that helps,DMG
hi,you did not show us the definition of Check or CheckView or ContentView (if ChecksView is not the opening screen), but i put together your code as it stands with some simple assumptions and came up with the following, that works as (i think) expected and does not show the behaviour you suggest:struct Check {
var date: String = "Date"
var name: String = "Name"
var amount: Double = 0.0
}
struct ContentView: View {
@State var checks = [Check]()
var body: some View {
VStack {
Text("Check count is \(checks.count)")
Divider()
ChecksView(checks: $checks)
}
}
}
struct ChecksView: View {
@Binding var checks: [Check]
var body: some View {
HStack(alignment: .top, spacing: 0) {
Button("add prereq", action: {
self.checks.append(Check())
})
VStack {
ForEach(self.checks.indices, id: \.self) { i in
CheckView(check: self.$checks[i])
}
}
}
}
}
struct CheckView: View {
@Binding var check: Check
var body: some View {
HStack {
Text(check.date)
Spacer()
Text(check.name)
Spacer()
Text(String(check.amount))
}
}
}i'm running XCode 11.5 on MacOS 10.15.4 and simulator running iOS 13.5. could there be a problem elsewhere in code you are not showing?hope that helps,DMG
hi,be sure to look in the Global.swift file, and set the kPerformInitialDataLoad variable to true when you do the first run (then, put it back to false). that will load data from the .json files included in the project.this is far form a sensitive project, so enjoy. i think it has a lot of what you were asking for.good luck,DMG
hi,Scala? not anything i have written. it looks like there are a gazillion things on github that come up by searching for shopping list, but only one is mine.did you find mine correctly?h ttps://github.com/delawaremathguy/ShoppingListhope that helps,DMG
hii'll offer an example ... on github, look for delawaremathguy/ShoppingListi'll leave this public for a short time. it's a (very small) work in progress as i get more into the spirit of SwiftUI, but it has the features you are looking for: CoreData, multiple tabs, and the ability to edit on a second screen with edits reflected on the main screen.comments welcome!hope that helps,DMG
hi,oops ... it should probably befetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \ProgrammingLanguage.id, ascending: true)]i keep forgetting that you specificy an array of sort descriptors, not a single sort descriptor. good luck,DMG
hi,there's a lot going on with your code and with your question, so here are a few comments.(1) your ContentView (lines 3 - 30) has a @FetchRequest and an @Environment variable that is passed along to you by the SceneDelegate. in order to display, it uses the @FetchRequest (and its assumed managedObjectContext) to provide a list of ProgrammingLanguage objects (i.e., entities on the CoreData side). the problem, of course, is that you probably have no CoreData entities, so you rely on using the .onAppear() modifier to go out and add a few ProgrammingLanguages to work with.you might see this recent thread. (2) rather than just write a simple function inside ContentView that creates some data, you seem to want to invent a MyClass object that will do it for you.OK, that design could work -- but your definition of MyClass has a serious problem: even though it has made its own @FetchRequest and @Environment declaration, these are not useful. these property wrappers make sense for Views and their child views, but they don't mean much to objects defined inside the ContentView.so the real problem of creating objects in your MyClass.createData function is that there is no managedObjectContext available to it. we don't know where the ProgrammingLanguage objects are being created, and chances are the try self.managedObjectContext.save() statement on line 49 simply fails.(3) if you do want MyClass to work, kill lines 34 through 41, then ask the createData() function to go find the viewContext of the persistentContainer of the AppDelegate to use, in which to create the objects and save them. the code would look like this: (you'll need to import UIKit and CoreData to make this work).let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedObjectContext = appDelegate.persistentContainer.viewContext
for i in 1...5 {
let language = ProgrammingLanguage(context: managedObjectContext)
language.id = Int32(i) // << here !!
language.name = "\(i) SwiftUI"
do {
try managedObjectContext.save()
} catch let error as NSError {
print("Error saving ProgrammingLanguages: \(error.localizedDescription), \(error.userInfo)")
}
}(4) if you want MyClass to do its own fetching of ProgrammingLanguage objects (the ContentView does this for you already with its @FetchRequest, so be careful in how you might use it), then you'd need to define it this way:func readData() -> [ProgrammingLanguage] {
let fetchRequest: NSFetchRequest<ProgrammingLanguage> = ProgrammingLanguage.fetchRequest()
fetchRequest.sortDescriptor = NSSortDescriptor(keyPath: \ProgrammingLanguage.id, ascending: true)
do {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedObjectContext = appDelegate.persistentContainer.viewContext
let languages = try managedObjectContext.fetch(fetchRequest)
return languages
} catch let error as NSError {
print("Error fetching ProgrammingLanguages: \(error.localizedDescription), \(error.userInfo)")
}
return [ProgrammingLanguage]()
}i think this all makes sense ...hope that helps,DMG
hi,instead of defining a global window variable outside of the AppDelegate:var window: UIWindow?
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate{
// code
}perhaps you should be writing this, which implements a window property for the AppDelegate@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate{
var window: UIWindow?
// code
}this looks more like how a storyboard-based app delegate is set up in order to use the main storyboard (rather than a SwiftUI setup which uses a SceneDelegate for iOS 13).hope that helps,DMG
hi,not very helpful, indeed! i'm sure i had the same problem when i tried to something with coredata in an init.my suggestion would be that you remove your init(), take the code you have now, and put it into a function called, say, "loadData." modify the code of loadData to be of the formfunc loadData() {
if languages.count == 0 {
// run the code you run now to create an initial ProgrammingLanguage entity
}
}now attach an .onAppear() modifier to your List, as in.onAppear(perform: loadData)that should do it. the view will appear -- it will call loadData, which will add the new entity if there's nothing there yet -- and the FetchRequest will recognize the change, re-computing the body property.i think that should do it.hope that helps,DMG
hi,i think the first thing to do is to see if there's an error coming back at line 17, so something like this:do {
try self.managedObjectContext.save()
} catch let error as NSError {
print("Error saving: \(error.localizedDescription), \(error.userInfo)")
}i'll go out on a limb on this one: the managedObjectContext may not be set correctly. because you've supplied your own init() method, the normal sequencing of identifying the managedObjectContext from the environment may not have taken place yet.hope that helps,DMG
hi,we'll need a little more information on this, as well as the code you're using to check available space, confirm that the file does not exist, and how you call createFile(atPath:contents:attributes:). we'd especially want to see how you set up the path.hopefully we can say more when we see these.hope that helps,DMG