How to use Core Data without Storyboards? - iphone

I am trying to use Core Data without storyboarding in my app. I want to manage many relationships and I have a kind of singleton class to manage the access to the managedObjectContext, model, and persistentStoreCordinator I got it from this link Singleton datalayer without appdelegate
My problem is that I dont want to use StoryBoards but all the examples that I found use Storyboards. I have problems with UITableView because appDelegate doesnot found it.
I want to create a Single Application and then with a singleton to manage the context and everything, show the objects that I get in a JSON format with nsfetchedresultcontroller or with fetchrequests if I only need one item.
I am using this class. also I have another class called CoreDataTableViewController.h/m it is a subclass of UITableViewController and it has the methods of NSFetchedResultControllers. I got this of the Stanford IOS course. Then I have my MainViewController its a subclass of CoreDataTableViewController and there I get the data from the Json and put it in my ManagedObject and also I overwrite the method cellForRowAtIndexPath. But when I start the simulator I have an error. loaded the "ViewController" nib but didn't get a UITableView.

Core Data doesn't care whether you're using Storyboards or not. Just copy the Core Data related code that you need (you can create a singleton containing the relevant managedObjectModel/context, persistentStoreCoordinator objects and methods) and add it to your own project.

There are no relation between the two. If you need an example of core data that doesnot use storyboard, try Apple's. Good luck!

Related

How to tell your viewController to update and pass it an object with the update specifics?

I have a general working knowledge of object-oriented programming and I'm currently trying to create an interactive novel program in Objective C using Xcode 4.2 with storyboarding.
I have a storyController class that instantiates the page objects and a viewController class that needs to display the pages. My fundamental question is the best approach for my storyController to tell the viewController to update it's text to display that of the new page object. My instinct tells me that my storyController needs to call a method on the viewController and pass it a page object. However, I'm not sure how to reference the view controller since it seems to be automatically created and linked by the storyboard (I don't see the viewController instantiated in the appDelegate).
I've read this post: http://www.iphonedevsdk.com/forum/iphone-sdk-development/54859-sharing-data-between-view-controllers-other-objects.html and it seems to address the issue. I could make a shared object on my appDelegate and use KVN or NSNotification to tell the view controller to check it.
I've also been reading about delegates and protocols as possible solutions.
So considering these potentially different approaches, which would be best to tell my viewController to update itself and pass it an object that contains the updates?
I would suggest looking at the UIPageViewController class, which probably will do a lot of the heavy lifting work for you, depending on the specifics of your app. This class is essentially a controller class that contains multiple viewControllers. Each managed viewController becomes essentially a "page" in your book.
Here is a tutorial using UIPageViewController.
If this approach won't work for your app, I'd still suggest using a separate viewController instance for each "page" of your book and handle the transition between the pages with segues.

Saving data from ViewControllres (Core Data)

I looked through a core data tutorial which puts the core data code in the AppDelegate class that is created upon creating a Window project. I was able to successfully save and retrieve data from the premade AppDelegate class.
My question is, if i have a ViewController that saves data, how do i go about saving data from that specific class.
Do i need to redefine the persistent store and managedObjectModel in that class?
If that is the case, what is the programmatic way to do it (since previously it was generated for me) i.e what methods/instancevariables/properties do i need to declare.
Standing by for any clarifications there may be
No need to go through the app delegate or redefine persistent store etc. All you need is a reference to the managedObjectContext. Normally, this is a property (say, of a view controller) that you can set from the outside after creation and easily access from inside the view controller class (much easier than going through the app delegate!). You can pass this on easily to other view controllers, and read from and write to core data with the standard methods.
If you want to save your own objects, yes - you have to create your own managed object model (by modifying the one the template generated for you).
Why not just have a reference to your application delegate in the view controller you wish to save data in? You can then access the managed object context and call its save method as usual.
In the .h file of your view controller have a property of same type as you application delegate. Then in the viewDidLoad method in the .m file set the reference like this:
self.appDelegate = (MyApplicationDelegate*)[[UIApplication sharedApplication] delegate];
Then when you want to save you can access the application delegates managed object context like so:
[self.appDelegate.managedObjectContext save:&error];
Hope that helps, I wrote that off the top of my head so there might be some syntax errors but the compiler will let you know.

How best to structure my code for a basic iPhone table/navigation database app?

Having worked through some tutorials on some basics via the iPhone, I'm struggling to determine how best to structure my code. The book I'm using points out things like "you wouldn't normally put this here, but for expediency...". Well, I'd like to know what one would "normally" do.
My application is somewhat simple - there is a table view showing a list of objects and one can add, remove, edit these objects (I plan to provide a more sophisticated organizational scheme later, but I'm keeping it simple to get something working).
So, I have a RootViewController that extends UITableViewController. When the "add" button is clicked I push a subclass of UIViewController onto the stack (this class is the "add/edit" form for my objects). I have a simple data structure-style class to hold the fields of the objects.
The apps like this in the book basically put an array inside the RootViewController and use a reference to the model class to represent the "object being edited". Basically, the models are all wrapped up in the view controllers. This seems wrong.
So, my question is: where do the models and the objects for managing them normally live?
And, does the answer to this depend on how I'm storing my objects? I have not done much with CoreData, though my plan was to use it for persistence of my objects. Will the hooks and boilerplate provided by XCode make this a nonissue?
Best answers will be pointers to some best practices type stuff, which I wasn't able to easily find via Google or on Apple's Dev site.
First of all you are right about your intuition that it seems wrong. As you described the model is stored in the view controllers. That is a bad idea. By doing so you are violating the model-view-controller paradigm, which makes your code hard to maintain.
So what you need to do now is get your model in a separate object or tree of objects or even better use CoreData, which is also great in terms of memory management.
As you want to use CoreData you should have a look at the UIFetchedResultsController class which you will use to obtain the objects from the managedObjectContext which will be your model.
What you would do in your table view - detail edit example is:
Fetch the contents of the table view using a fetch request and setting it on the NSFetchedResultsController you hold as an instance variable in the rootViewController
Set this rootViewController as the delegate of that NSFetchedResultsController
If an item is checked or the add button is pressed push your detail view controller on the stack, pass the object to be edited with it, or nil if it is a new object. Also pass the managedObjectContext to the detailViewController. Update or create the object.
Implement the delegate methods of NSFetchedResultsController in your rootViewController and there you reload the contents of the table when necessary.
What you gain is a nice and clear separation of model (CoreData's managedObjectContext) the controller (rootViewController and detailViewController) and you views. If you now edit an entry by using the detail view, your rootViewController is notified via your NSFetchedResultsController and automatically updated. What you also gain is that you do not have a strong reference among the viewControllers in your application.
Btw, you set up your CoreData stuff in the application's delegate. There is a lot of boilerplate code around in Xcode and on the ADC. Check out the Recipies app [1] in which this approach I just descriped is used. There are also some videos about CoreData on Apple's developers site.
[1]: http://developer.apple.com/iphone/library/samplecode/iPhoneCoreDataRecipes/Introduction/Intro.html CoreDataRecipies

Design pattern for Core Data iPhone App

Im building an app that will use a Core Data model. I pretty new at Objective C and my usual design patterns does not really apply on Core Data and Objective C, at least I can't seem to find examples that confirms they will.
I have been through the Apple Developer examples and different sources on the intertubes.
It seems that to leverage Core Data I need to pass the managedObjectContext to each of my viewControllers, have the viewController implement the NSFetchedResultsControllerDelegate and then implement each of the methods for doing a fetch and subsequently implement
NSFetchedResultsChangeInsert
NSFetchedResultsChangeDelete
NSFetchedResultsChangeMove
NSFetchedResultsChangeUpdate
This adds approximately 100+ lines of code in each viewController and it is 90% the same code I write again and again. Plus I have to pass everything around and keep track of it's memory footprint.
In other languages I would build a singleton model of a few classes that held methods for maintaining and delivering data upon request, available from anywhere. It seems I can't take that approach in Objective C. If I where to build a static Class that took a managedObjectContext and returned me what I needed, I would still have to pass the managedObjectContext around to every view and it wouldn't be asynchronously like when I implement delegate methods that just gets called when a result is ready.
I hope this makes sense and that someone can either confirm that there is no other reasonable way to do it or help point me in a direction for wrapping this up in a good way.
Thanks:)
Core Data is not nearly as complicated as you describe.
Generally, an iPhone app has a "main" managed object context, which is generally owned by the app delegate. So long as you can get the app delegate (hint: [[UIApplication sharedApplication] delegate]) you have access to the managed object context. I like to define a static global variable to hold a reference to my app delegate to make life easier.
There's generally a one-to-one correspondence between NSFetchedResultsController instances and UITableView instances. Aside from populating table views, it's exceedingly rare that you would need an NSFetchedResultsController. If you have a number of similar views (e.g. a tab bar that lets you view the same data in different ways a la the iPod app), it would behoove you to create a single base class that configures the NSFetchedResultsController and derive your specific view controllers from that.
Now, when you create view controllers to edit an object, it's generally a good idea to do that in a separate managed object context. If the user cancels, you just discard the context and the changes go away. Again, you don't really need an NSFetchedResultsController for this because these views are only concerned with a single object.
When you're done editing, you save: the managed object context. The objects that manage your other managed object contexts should implement the NSFetchedResultsControllerDelegate methods to keep the table view in sync. Again, this can be implemented in a base class so you can generalize this functionality for related view controllers.
Do you absolutely have to use a CoreData model, or would something using a NSCoder (NSArchiver, NSKeyedArchiver, etc) work? I've found that CoreData is overkill for most applications.
Also, could you clarify why you can't take an approach using singletons? I've used singleton factories in a number of applications without issues. It's fairly easy to define class-level methods that operate on a shared (singleton) instance.

Can I make NSManagedObject into a singleton?

I have a NSManagedObject object filled with data I want to use in multiple view controllers.
Can I make this object into a singleton and use it in multiple view controllers? Or should I use a different approach?
As an alternative to a singleton, consider making it a property in your application delegate, initialized when the application finishes launching.
In your view controller, set a NSManagedObject reference to this property's value when the view is instantiated.
You are already passing around the NSManagedObjectContext. You can use that to fetch the data you want at any time.
I don't know how Core Data would react to you making a singleton instance of it. For one, NSmanagedObject doesn't use the same methods for initialization that NSObject does.
It uses -awakeFromInsert and -awakeFromFetch. So you already have a problem.
See this article from Marcus Zarra (Core Data Guru).
In short, just perform a new fetch to get the data you need, no need to work a singleton in there.
That depends on why you would want to make it a singleton, if you have trouble passing it to all the entities that need to access the data, using a singleton is not a good solution anyway. It usually introduces more problems rather than solving any.
If you are worried about multiple edits to the same object, Core Data has mechanisms to handle that, see the "Change Management" chapter in the "Core Data Programming Guide"