Load up entity from db rather than pulling data directly from db - ios

I created an iOS app that allowed me to enter data into database and then display in tableview (using NSFetchedResultsController & tableView cellForRowAtIndexPath). This worked. Now, I added 3 one-to-many relationships and another entity and I need to load up the entity (on the one side of the one-to-many) from the db instead of pulling it directly from the db so that the data can be used in the relationships. Do I still use NSFetchedResultsController?
relationshipEntity2 is the one-to-many relationship between Entity1 & Entity2. The many point to Entity2
I know I'm supposed to use:
Entity2 *entity2 = [[self.entity1.relationshipEntity2 allObjects]
objectAtIndex:indexPath.row];
I am new to iOS development and even newer to Core Data but I must learn it. Any bit of help or pointing to a book or tutorial I haven't come across yet would be greatly appreciated. I haven't had much luck finding anything that does what I'm supposed to be doing.
Thanks and have a great week!
-------added for more description on project-------
I'm given the task of having a View Controller with a 3-part segmented button. There is also an add UIButton that pops up a view (bringing subview to the front, not a popover segue) with a UITextField for input to add to the table view on the view controller. There are 2 entities and three 1-to-many relationships. There is 1 relationship for each button on the segmented button. If the user, has the first part of the segmented button selected, adding a value to the popup textbox, should only add it to the table view seen when the first segmented button is selected. I have the CoreDataGeneratedAccessors created. I had this project saving data to database and fetching data to present in the table view but that was before the segmented part was added. Now I have to figure out out to separate the data into "collections" and then show all of say the first collection when the first segment of the segmented button is chosen. I'm just learning and just figured it out without the segmented part and now it's changed on me. I've worked with relational databases but in iOS it seems like it's new again.

Your question is by no means clear. You are not describing any problem, nor do you explain intelligibly what you want to accomplish.
Trying to infer your meaning: yes, you would continue to use your fetchedResultsController. This controller gives you the right object for each indexPath. When building your cell contents, you can easily get to the relationship entities with entity.relationship.
The code above will not work because entity.relationship returns an NSSet which is an unordered group of objects. (The additional allObjects does nothing and is redundant.) Therefore, objectAtIndex will not work (this only works for NSArray objects).
Hope this helps.

Related

Moving attributes from one entity to another

I'm have a multi-list app that has an entity with several attributes for each list (i.e. List1 - item, description, qty...List2 - item, description, qty).
I have UITableView's for each list set to have two sections (section 0 "not checked" and section 1 "checked" with the didSelectRowAtIndexPath: method).
I want to use a button move the selected row's data to the second entity and remove it from the first.
I have put the button in a UIView in the footer of section 1 and made it segue to the destination viewController, just without any data transferred.
The only information I have found during google searching is on data migration and migrating assists of a business (fail), but I don't really think this is what I am looking for...is it? Or what is this process called? I am also using NSFetchedResultsController to manage the objectContext (I think I said that right).
Please keep in mind very new to coreData and that I'm still not able to convert Obj-c into Swift yet, so Swift is all I've been learning. Also, any explanation would be incredibly appreciated.

Reload view crash with 'index 0 beyond bounds for empty array' error

My app is based on core data using MR.
I have 3 views. The three views are -
a table view where I can select an entity, when tapped it open the second view with all the relatives data and there I have a button that open the third view where the user can modify the data.
My problem is that to open the second view I have to pass from the table the row number to get the exact entity to be displayed, and here everything fine.
But if the selected entity is the last one in the table and the user modify some data that remove the last row(for example if change the category attribute of the entity), when I go back my app crash, because the row number relative that I passed from the first view doesn't exist anymore in my database.
I hope I explained it well. I know the problem, but I don't have any idea of how to solve it.
My problem is that to open the second view I have to pass from the table the row number to get the exact entity to be displayed
You should not pass the index into the table, since you know that it can change.
Alternatively, you can pass the managed object itself, or its objectID (taking into account that objectID is expensive).
In Xcode, in the left pane there's a breakpoint section (the one with the shape of an arrow… more or less). Open that section. If you hit the + button in the bottom left corner of that pane you can add an Exceptions Breakpoint. This will store the your app and highlight the section where it's crashing. From there you might be able to solve your problem fairly easily: you only need to understand why you're still trying to access that row, instead of the new index of the object. If you still need help at that point, please post the section of your code that's crashing and any related code of that class.
I solved my issue by passing the identifier of the entity instead of the row index. So now in the detail view I get my entity using the identifier instead the index.

Moving cells from one table to another in iOS

I am trying to create an application with multiple table views that uses and implements Core Data. I would like the user to be able to select cells in one table and move them to another (like in Apple's mail application) using either a check accessory or a selectedCell method with an action sheet. I'm stuck because I don't know if you are actually moving the cell to another table or if you are adding a copy to the new table and deleting the original. Basically, I'm asking for a basic example of cell movement to give me a push in the right direction.
You won't be moving cells. The model for a table view is an array. Move things between the arrays and tell the tables that their model has changed.
id somePartOfMyModel = [self.arrayA objectAtIndex:someIndexPath.row];
[self.arrayA removeObject:somePartOfMyModel];
[self.arrayB addObject:somePartOfMyModel];
// the simplest, non-animated way to update the tables.
// I'd advise getting this working first, then later trying fancier UI to indicate changes
[self.tableViewA reloadData];
[self.tableViewB reloadData];
You would not be technically moving the cell to the other table. The way I would go about doing this would be to pass the NSManagedObjectContextID of the item between the tables, depending on how large your entities are and if the tables are in the same view controller.

Existing solutions to edit NSManagedObjects via a UITableView?

In my iOS app, there are various Core Data entities that represent things like Appointments, Notes and Contacts.
I'd like the user to be able to edit selected attributes of each entity via a UITableView. Similar to the iOS Calendar app, when you click 'Edit', you're presented with a UITableView with editable values for Start Time, End Time, etc.
It's occurred to me that there could be a large amount of code re-use going on here, so I'm now considering creating a generic class, ManagedObjectEditorViewController that takes a managed object, displays selected attribute values within a table view, formatted according to their type, and allows them to be edited.
I can think of several neat ways of doing this, but before I spend a long time on this, I'm wondering if there's already something out there to accomplish this task? It seems like such a frequently used approach that I can't believe there isn't already some open source code out there.
Anyone heard of, or used anything similar?
I am about to do the same thing. Just started and works so far. A table that represents an NSManagedObject (Detail to a master view controller, has aspects of a master view controller itself.).
The whole table represents one NSManagedOjbect. There are fields and other controls that correspond with the simple properties.
There are to-one references where the referenced object is just displayed but can be changed.
There are to-one references which are editable NSObjects itself where 1 and exactly 1 of them exists.
There are to-many references which can be added, deleted and edited. Pretty similar to the calendar app or the address book app. (from a functional point of view. It looks different though).
For that I establish a delegate between the table cells and the view controller. This is mainly because I try to stick on the MVC pattern.
E.G. the cell serves as delegate for UITextViews, UITextFields or as target for Buttons etc.
The (Detail-) View controller which owns the NSManagedObject and all related objects serves as my delegate for the cells. It provides methods similar to IBActions to the cells so that the cell can 1) inform about the event and 2) hand over a related view, if required (I need that to display some popups accordingly) and 3) the object itself e.g. the object that is to be deleted or a person-object for which the data is to be fetched from the address book etc.
The View controller can then does its very own duties which is invoking other view controllers (Send Mail, select from Address Book, present a popover with options for the user to choose from, ...).
I just built that up yesterday evening. (It is a free-time project of mine).
I am happy so far but the concept is not really proven yet :) .
What is your current favorite approach?

Core Data: Deleting Views Stored in Core Data

I am trying to delete views that have a yellow shadow from my main viewcontroller.
It registers the number correctly but it doesn't delete. (It doesn't update the view I have tried to call setNeedsDisplay and all of those lines but the don't work. It only updates when you quit out of the app an reload it. It isn't in the managedobjectcontext but it stays in the view. Am I not releasing something?) If I had it so it only passed one item .. if you clicked on it to delete.. it would have worked but this isn't working with the shadows. Can you see why???
Update:
I have views that are stored in core data (pages) and I want to delete the pages when they are selected and have a yellow shadow. If I need to how to I add the view to an array or something when it adds the shadow and then finds them when it needs to delete.
-(void)trashitems{
for (NSString *itemKey in [itemViews allKeys]){
UIView<CollectionViewItemView> *itemview = [itemViews objectForKey:itemKey];
if ([itemview layer].shadowColor == [UIColor yellowColor].CGColor){
NSLog(#"remove %i",[[NSDecimalNumber decimalNumberWithString:itemKey] unsignedIntegerValue]);
if ([dataDelegate respondsToSelector:#selector(collectionView:canDeleteItemAtIndex:)]
&& [dataDelegate collectionView:self canDeleteItemAtIndex:[[NSDecimalNumber decimalNumberWithString:itemKey] unsignedIntegerValue]]
&& [dataDelegate respondsToSelector:#selector(collectionView:didDeleteItemAtIndex:)])
{
[itemViews release];
NSUInteger itemsCountBeforeDeletion = [dataDelegate countOfItemsInCollectionView:self];
[dataDelegate collectionView:self didDeleteItemAtIndex:[[NSDecimalNumber decimalNumberWithString:itemKey] unsignedIntegerValue]];
NSUInteger itemsCountAfterDeletion = [dataDelegate countOfItemsInCollectionView:self];
if (itemsCountBeforeDeletion - 1 != itemsCountAfterDeletion){
[NSException raise:#"Collection View Deletion Exception" format:#"Count of items in collection view before deletion (%u) must equal one more than count of items in collection view after deletion (%u) but did not.", itemsCountBeforeDeletion, itemsCountAfterDeletion];
}
}
}
}
}
Like Tom said, storing a view in Core Data is bizarre. To make a view disappear, it needs to be removed from the view hierarchy. The data should be separate from the view. I highly suggest reading up on the MVC (Model-View-Controller) design pattern.
You've got a serious design problem here. This simply isn't going to work and you need to start over.
The Apple API uses the Model-View-Controller design pattern. It should have been called the Model-Controller-Interface design pattern because that better captures the true relationships. The model holds the data and data-behaviors, the controller connects the model to the interface and the interface provides the data to an external observer such as human looking at a command-line/GUI, another process or a remote server process.
You say that:
I am trying to delete views that have
a yellow shadow from my main
viewcontroller.
... but you are really not. The subviews themselves display some kind of data e.g. an image while the yellow shadow conveys to the user some kind of information about the state of that data e.g. a yellow shadow indicates that the image is older than some date. What you are really trying to do (in this example) is delete images that are older than a certain date and then you want the views of the user interface to reflect that change in the data.
Now the data of the image and its state of being older than a certain date belong in the Model. The controller reads the data from the model and configures the view and subviews according to the data provided. The controller doesn't know the logic of why the view should look like it does for any piece of represented data and the views don't know about the data at all, they just know what image they will display and what color their shadow is.
When you are using Core Data, you use it to create the model layer. You don't use it create the controllers, views or to store any state information directly related to the operation of the controllers or views. Ideally, a data model should be perfectly functional regardless of what kind of interface you eventually use i.e. it should work equally well with a command-line, a GUI, a webpage or an interprocess communication. It simply doesn't know or care about anything not directly related to the data and the associated logic (e.g. images older than a certain date need to be deleted) of how the data fits together.
So, you need to figure out what is data and data-logic and put that in Core Data while keeping the details of the UI in that displays that data in the controllers and views.
I can't really tell you exactly what you need to do because I don't know what data your app uses or what its data-logic is but I do know that you need to take all information concerning the actual views and their configuration out of Core Data.

Resources