Dynamically Create Sections in Swift UI List (Using CoreData) - swift

I have a multiple Entry objects (entries) stored in CoreData that I access as a list given by a FetchRequest in my ContentView.
All entries have a date and I want to not only put all entries in a list (I have achieved that) but put them in their right SwiftUI section (that correspond to the day of the entries) in that list.
Basically, my question was answered here, but I am not sure how to implement it as I am using CoreData and don't have a user data object.
I thought about introducing a model of the list view and bind it to the list view.
I would need to incorporate the fetch request into the model and use an attribute/function to provide an [[Entry]] attribute to the view, right?
How exactly would I do this? How do I continuously maintain an [[Entry]] attribute in the model that I can access/(add to)/(delete from) from the view?
The current state of my Xcode project is almost exactly like presented in this youtube video; actually I just want to expand on this video as an exercise.

Related

Do I need to make embedded objects be key identifiable using Realm SwiftUI SDK?

For example, I have three object classes in which workout data is stored. The highest one stores the total workout and within the object is a list of workouts (which itself is an embedded object) and then within the workout I have a list of sets (which is again an object). Do these embedded objects need to have a key to be looped over to display/ edit in swiftUI view?
So far I have added a primary key within the highest object and have not modified other objects, as i am looking for how to move forward with the object models.
Embedded objects in Realm are conceptually embedded, owned and destroyed by the parent object's lifetime in the Realm. They don't have indexes including a Primary Key.
However, if you're listing them in SwiftUI, you are correct that you need to provide an id for them. This only needs to be unique for the duration of this list, so you don't have to store it. If there's a unique property in the embedded object, just use that field. Otherwise you need an id adding. Please add more code to your question to make this easier to answer.
See Working with Identifiable items in SwiftUI - HackingWithSwift

Best practice for MVC 4 Edit Views and "Hidden" parameters

I have recently added some fields for auditing purposes to existing models in an MVC 4/ Entity project. I don't need these fields to be displayed on the edit page. However, they are required fields on the model.
As it stands, the edit page still works, but on the controller side, the ModelState.IsValid check fails because the required fields that are actually set on the item are not output to the view and therefore not re-submitted when the edit page is submitted.
Is there an easy, built in way to rectify this, or if not, which of the following is best practice for this scenario? Are there more options?
1) Set up hidden fields on the view to hold the information (Not a fan of this option, passes data around too much)
2) in the controller, on submit, first load the model by ID, then set each individual parameter based on the fields present on the view (Seems like extra unnecessary work)
3) Create a constructor for the model that takes itself as a parameter and pulls any non-default values and returns a new object. Basically a merge. (Best I think, still a lot of extra work)
4) ???
Best practice is to not use your domain model inside the views. Create a view model class that contains only the id and the fields you want in the view. Pass this model to your view. Change the parameter type of the form submit action to match your new view model. This will then pass the model validation without using hidden fields. In your action method, you can then retrieve the object from the database using the id property of the view model class and update fields as required.
Hope that makes sense.
I prefer to do the 2nd option as long as I can get the existing object with a single query or db call. This lets me to keep my view clean(no hidden fields for all those other properties) and use the existing update method which updates the domain model.
Look into your code. If the update method is making updates in lot of other places(many other tables) which is really not needed, then you could possibly write a short version of the update method which updates only the relevant parts ( ex: UpdateContactDetails).

Core Data object graph design decision

I am designing an app which tracks data on Game objects. Each Game has a name, a date and other attributes. The problem I am having arises because I want the user to be able to add more names (for example) to pick from in the application. (in this case from a UITableView). So the user is presented with a list of names to choose from, and if the one they want is not in the list, they can add one to the list.
My solution is that I currently have a second entity called GameName so that I can show the user a list of those game names to pick from when they are adding a new Game. I just call an NSFetchRequest on all the GameName objects and display them in the UITableView. There doesn't have to be a Game object created yet to do this.
My dilemma is that I want to know if this is a good practice. It seems that if I do it this way, I will end up having a lot of entities with just one attribute, for the sake of allowing the user to pick from and add to a customizable list.
I hope this makes sense. I can clarify anything upon request.
Your approach is fine, and is commonly used in database design. The entity you want to add is called a "domain table" in databases. See this page, in particular this paragraph:
In a normalized data model, the reference domain is typically specified in a reference table. Following the previous example, a Gender reference table would have exactly two records, one per allowed value—excluding NULL. Reference tables are formally related to other tables in a database by the use of foreign keys.
Of course, you probably want to have an optional relationship between the GameName and Game entities.

Can you have a UItableView with mixed content (audio video text audio) from coredata?

I have a coreData model where I have an Event table and video, text, audio, image tables that have a many to one relationship with the event table.
In my app I have a rootTableViewController class that displays all the events. selecting an Event cell brings up a detailTableViewController that would display all the associated text, video, audio and image objects in the UItable. Objects should be sorted chronologically so there might be a mix of all the different object types in the table.
my question is: Is this possible to do this with a UItableView?
Is it better to fetch all the objects in a NSMutableArray, then sort the array and use it as an input for CellForRowAtIndexPath.
I was able to do this with a UIScrollView (without coredata). Inserting different views based on the object type; but i thought using a UITableView is better suited for data management.
Thanks a bunch for any help provided.
You generally only want to bother with fetches when you don't know which managed objects you are looking for. If you have a managed object but need other related objects, you just walk the relationship graph instead of fetching.
In this case the rootTableViewController had the Event object selected by the user. When it loads the detailTVC, it can pass it the Event object. The detailTVC can then ask the Event object for all its associated media objects. You can then sort them into an array anyway you wish.
To display each media type, create a custom tableview cell for each type and load that cell when the index points a managed object of that type.
An additional word of advice. This is wrong when you say:
I have a coreData model where I have a
Event table and video, text, audio,
image tables that have a many to one
relationship with the event table.
Core Data is not SQL. It does not have tables, rows, columns etc. Instead it has entities (abstract) and managed objects (concrete). Relationships connect entities in the model and managed objects in the actual live data. This is called an object graph and the main point of Core Data is to managed that graph. Unlike SQL, it really doesn't care how or even if the graph is ever persisted to disk.
Thinking of Core Data in terms of SQL always leads to grief.
What you could do is get the entities associated with a given Event with an NSFetchRequest and in the request, specify a sort descriptor for the date. Then, the array you get will be sorted the way you want.

Core Data - save existing managed object and show it in an another view

I'm working on an table drill-down style iPhone app that has prepopulated data. I use Core Data and NSFetchedResultsController to populate the table views. In the last level of the table view which shows an item (managed object) I want my user to be able to select that item which should eventualy be shown in another view. That other view would be a kind of a favorite list (implemented in a tab view). The user would then have a choice of deleting or adding other items to the favorite list.
My model has three entities each representing one level of table view. Higher level entity has a to-many relationship to lower level entity and inverse relationships are to-one
How do I use the existing managed object (object in the last level of table view) to save it and show it in favorite list view? Should I create new entity and establish relationship between the two?
My model has three entities each
representing one level of table view.
That is thinking backwards. What you have is three entities that exist logically in a hierarchy and the hierarchy of views reflects that logical structure. The views exist to display the data, the data does not exist to display the views. It's an important concept to grasp and if you fail to do so, your application design will always be overly complex, fragile and hard to extend and maintain. The data model always comes first and the logical relationships within the data model itself and the users interactions with that data ultimately control the UI structure of the app.
It's an easy trap to fall into because the instructional materials always start with the interface first. However, in real app design, you start with the data model first and work forward to the interface.
In this case, if you want to store favorites of some entity you have two choices. If the entity being a favorite is part of the core relationship between data and the user and you only have one set of favorites, then you could legitimately add a boolean "isFavorite" attribute to the entity and then just fetch al the entities where "isFavorite==YES"; If you have multiple list of favorites then the best method would to to create a FavoritesList entity and then relate each favorites entity to the objects it is supposed to list.
If the favorites are a minor and peripheral part of the user's interaction with the data you could store the objectIDs in the user defaults.
Yes, you could create a new entity and store the relationship. It's not necessarily the only way to do it -- you could store pointers to your NSManagedObjects in a container like an NSMutableArray -- but if you want to remember that list for later (i.e. save it between launches), it might make the most sense to also store it using Core Data.