How to create NSFetchedresultController on cocoa using NSArraycontroller? - cocoa

i have to port existing iOS code (which is using NSFetchedResultController) to OS X, can u please give me some code snippets on how to get contentWillChange and contentDidChange events using NSArrayController.

You don't. NSArrayController does all that, and more, when you bind it to a tableview and set its entity type properly.
Using bindings you can remove all of the table data source code that you had for iOS.
If you want to recreate NSFetchedResultsController, you need to listen to managed object notifications and act on them in the same way, but bindings is much easier.

Related

What does exposeBinding do?

I have been using bindings without having ever heard of exposeBinding.
Is it only intended to plug-ins ?
What does exposeBinding do ?
Expose bindings are nothing special, it is just normal binding what you see in the Xcode. But why its named is expose binding becuase when you do any binding in the interface builder. It causes second binding automatically in the interface builder which is called expose binding.
For your understanding i have attached the screen shot in which inside binding inspector i have just bind file owner to the hidden in Availablity section and then you can see below automatically it created hidden2 inside Availablity section below. This new binding hidden2 is called exposed binding. And also the used of these binding values are then used together in returning the final value of the binding. Please follow the attached screen shot:-
From the doc.
exposeBinding:
Exposes the specified binding, advertising its availability.

Binding issue between Core Data and NSArrayController

I am trying to set up the binding between Core Data, NSArraycountroller and a NSTableView. To get a NSManagedObjectContext for the NSArrayController. I dragged an NSObject in the IB, and named it after the appDelegate and then set up the binding of objectContext between appDelegate and the arrayController.
However, whenever I tried to run the app. I get this error message:
The error message:
The managed object model version used to open the persistent store is incompatible with
the one that was used to create the persistent store
And then followed by another error message:
Failed to initialize store.
I googled around, most of the people can solve this issue by clean their project or delete the files under ~/Library/Application Support/AppName/.. But I don't have luck with those.
Another thing is that, I desperately want some good tutorial on this topic (CoreData+ArrayController+TableView). Can someone shed some light on this as well? I read through the chapter 11 of the book "Cocoa Programming for Mac OSX 4th version", but didn't find it really helpful.
Thanks.
Finally solved this issue. I think it has to do with Reskit. Reskit has its own managedObjectContext when bundle with CoreData. That's why it keeps telling me the two object model is incompatible. The NSArrayController should be binded to the managedObjectContext in RKManager instead of the one in appDelegate.
So I put this in the init method of view controller:
RKObjectManager *objectManager = [RKObjectManager sharedManager];
currentObjectContext = objectManager.objectStore.managedObjectContextForCurrentThread;
And point the managedObjectContext in the NSArrayController object to the currentObjectContext.
The error has to do with your managed object model; it's not related to your bindings or table view. If it happens when you run the app (vs. when you try to open a document) it's probably during restoration of autosaved documents.
Try deleting anything related from ~/Library/Autosave Information and seeing if that fixes the initial problem.

should I be creating my objects manually or with InterfaceBuilder?

I am relatively new to Cocoa/Xcode and am not sure if I am structuring my application in the most "correct" way possible. I have a number of objects which are active the while time that the application is running. Should I be creating these objects manually or with Interface Builder?
The type of objects I am referring to:
"downloader" which is responsible for downloading files to disk
user interface updater which is responsible for updating the user interface to show the results of the downloaded file
Should I create these objects in IB and set up the connections between them with code?
It's really a matter of personal preference.
In my opinion IB only really good at laying out views, so I tend to only use IB for my view and my view controller, and I create everything else in code in the view controller's viewDidLoad or init method.
In your example, connecting the "downloader" object directly to the interface seems like an MVC violation, so I would keep the downloader out of my xib.
The "interface updater" would be connected tightly to the interface, so it could be in the nib, although unless I had a good reason not to I would probably just put that code into my view controller class.
If you are creating things in code, note that viewDidLoad/viewDidUnload can potentially be called a number of times, as the os loads and un-loads your views when they are not visible to save memory. So only put transient objects there... things that must exist for the life of the view controller should be created in the init/dealloc methods. Part of why I like to do most of my object creation in code, is the finer level of control you have over memory.
I typically build as much as I can in IB, and then switch to code when I run into the limitations of IB. It sounds like you should be able to create the UI you described in interface builder.

NSArrayController and referring to a shared, static, Core Data based library

Using this guide I have created a static library (let's call it AppCore) that can be shared between the Mac OS X and iOS versions of one app. This static library uses Core Data and the point of it is to share the model part and schema versioning between different implementations.
I created a NSPersistentDocument based project that will depend on this AppCore. In this project I added a reference to the .xcdatamodel file. Then I created a simple table view with add/remove buttons to edit an array of one entity type with the assisted "new core data entity" item. This created an instance of NSArrayController and the required bindings for the add/remove behaviour.
Now, everything seems to work fine when I'm using the default class for the Core Data entities (NSManagedObject) and I'm able to add new rows using the +/- buttons. However, when I change the entity implementation class to a custom one, I'm getting an error
Failed to create new object
This seems to come from the NSArrayController and it seems to be unable to instantiate the required entity. I can, however, create one in the NSPersistentDocument subclass by:
[NSEntityDescription insertNewObjectForEntityForName:#"SomeEntity" inManagedObjectContext:[self managedObjectContext]]
What confuses me is why the instance of NSArrayController can't. If I understand correctly, the array controller is instructed to create an entity, not class and my guess is that the entities are created with the help of NSEntityDescription class. I could implement my own version of the array controller's add: but then again, it might be that here something is fundamentally wrong. I haven't touched the init:s and the custom entity class implementation is simply for convenience, to access the attributes directly.
I have tried changing the base SDK on the AppCore but without effect. Currently it uses the iOS version but I'm not sure how it should be. This is another question but if unrelated, I might ask it here on a separate question.
So, to summarize, why can't the NSArrayController create an instance of this entity?
Thanks in advance.
Update
This works if I add the SomeEntity class from the AppCore to the dependent project as a reference. This is not the most usable way since modifications to the AppCore has to be propagated to the dependatnt projects also.
Bingo. I missed the "-ObjC" flag for the dependant project's "other linker flags". Now everything works like a charm.

Cocoa Touch App Architecture - MVC controller?

I am quite new to Cocoa and to iPhone programming.
I am using the Xcode Utility Application template to implement a simple app that has:
a view with a text field to collect a username
a view with a connect button to start a connection to a remote site using the
username to get some data via HTTP. The data will be presented as a text string on the screen.
I think this represents my VIEW in the MVC pattern.
I created a simple class to store the username and to do all connection work that represents my MODEL and instantiated it inside the AppDelegate.
Here a really simplified sketch:
It is not really clear to me how can I get data nested deep into subviews (username) or how can I trigger actions in nested parent views (connect button).
My question is:
What is the best/cleanest way to implement this architecture?
How do I implement the CONTROLLER?
Thanks in advance for any help,
Paull
Updating my answer based on comment:
It's in most cases ok to have state in your controller. Like an array or an instance of whatever modelobject you are writing an application for.
I would keep the model object clean of any networking code and put that in the Controller instead though. In this case the ViewController where that connection action is triggered.
Original answer:
It is not really clear to me how can I
get data nested deep into
subviews(username) or how can I
trigger actions in nested parent
views(connect button).
With the utility application template you already have a couple of ViewControllers.
To get references to your UI inside your controllers you need to declare IBOutlets and connect them inside Interface Builder. To respond to actions you need to declare and implement IBActions in your ViewControllers and hook them up in Interface Builder as well. Which you do in Connections pane (2nd from left) in the inspector.

Resources