Core Data Application design - macos

Hello everyone,
I have a question concerning an app I'm developing for Mac OS X right now that uses a simple sqlite database. My question is how should I handle the datasource component into my app ?
Is there a simple way of making one datasource available from within different view controllers other than by using delegates that send messages to the AppDelegate ?
This might seem an odd question but the fact is that I have been developping on IOS only before and you only had to pass the objectcontext to the viewController to make it available to the view controller. On MacosX, I cannot figure out how to do the same...
Any help would be much appreciated...

How to pass the context from one view controller to another:
newViewController.managedObjectContext = self.managedObjectContext;
Alternatively, you can keep the context in the app delegate and override initWithCoder which should be called when a view controller is initialised from storyboard or xib:
AppDelegate *delegate = (AppDelegate*) [[NSApplication sharedApplication] delegate];
self.managedObjectContext = delegate.managedObjectContext;

Related

delegate of view in UIPopoverPresentationController not reponding

I'm in a bit of a pickle here. I have an app written for ios7.1 and we are now trying to make the same app support ios 8.1.
In this app we have several popovers. I've gone through the fix of having them show up properly as a popover in iOS8 but when I click on the popover it doesn't respond as expected.
Here's how it is being presented (all hooked up in storyboard):
in DashboardViewController:
if ([segue.identifier isEqualToString:#"showRHSMenu"]) {
_rightNavController = segue.destinationViewController;
_rightNavController.preferredContentSize = CGSizeMake(220, (_rightNavController.tableView.rowHeight * _rightNavController.dataArray.count));
_rightNavController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popoverPresentationController = _rightNavController.popoverPresentationController;
popoverPresentationController.delegate = self;
}
in _rightNavController, a protocol is declared to communicate with DashboardViewController. this works and gets executed in ios7.1 using UIPopoverController but in iOS8.1 using UIPopoverPresentationController, it does not trigger.
I have confirmed that the user clicks register in the rightNavController but the protocol/delegate is not being executed.
Can anyone help please?
An old question, but hopefully this helps someone else.
I ran into the same problem today, and the solution was to declare the popover controller as an instance variable rather than a local variable. As a local variable, it gets garbage collected any time after the method returns, regardless of whether the popover view is still on screen. (Garbage collection seems to be a lot more aggressive/efficient in iOS8, so likely just exposed a bug that you already had.) Keep a handle to the view controller until the view is dismissed, and all the delegate methods should work fine.

Mac os x main window controller

When I create a cocoa based mac osx application in xcode. I get a default class AppDelegate which is sublcass of NSObject < NSApplicationDelegate >
The application is one main window which has some buttons , tableview etc,
My question is should I make this AppDelegate class to be the controller of my main window ? or should I create a new controller. Under what condition should I choose my delegate to be the controller and when should I not ?
If the application is not some throwaway test application you should create a new controller and put there logic for the view. If the application starts to grow you may need even more controllers and views e.g. Status bar could be separate view with a separate controller.
In the AppDelegate you should put only the things that are specific for the complete application like menu, starting, stopping etc.

How to force NSArrayController to reload MOC contents to reflect latest fresh data

I am working on a Mac & iOS App, with iCloud CoreData in between to synchronize the data.
When I update some thing from iOS App, and the updates are already migrated to the PersistentStore in Mac App while the Mac App is running. The problem is I cannot find an effective way to force the NSArrayController to reload all data from the store.
tried -(void) fetch:(id)sender; only can see the delete or added entity, but the updated model property not refreshed...
Please help. Thanks
If you see the latest data in the managed object context, but not in the array controller, you want:
[_yourManagedObjectContext processPendingChanges];
[_yourArrayController fetchWithRequest:nil merge:YES error:&error];
[_yourArrayController rearrangeObjects];
I use this in a Mac/iOS iCloud app to update the Mac app's data when the iCloud store changes.
Following is the reply from Apple's Developer Technical support. It worked for me. Thanks all for providing solutions.
For the OS X app, when reloadFetchResults is called, you can ask the NSManagedObjectContext to reset itself and perform the fetch again.
- (void)reloadFetchedResults:(NSNotification *)note
{
NSDictionary *userInfoDict = [note userInfo];
NSManagedObjectContext *moc = self.coreDataController.mainThreadContext;
// this only works if you used NSMainQueueConcurrencyType
// otherwise use a dispatch_async back to the main thread yourself
//
[moc performBlock:^{
[self mergeiCloudChanges:userInfoDict forContext:moc];
[moc reset];
[self.tableArrayController fetch:self];
}];
}
I've found that
[self.managedObjectContext reset];
[myArrayController fetch:self];
forces my NSTableView (with NSArrayController) to re-populate and display newly processed NSManagedObjects.
in case someone else finds this...
in my case, I was building the array from user interaction (not Core Data), and then trying to show the tableView when they were done (on the same window)... and of course... seeing nothing!
[arrayController rearrangeObjects];
just before I wanted to show the tableView fixed it for me.

Refactor the Application Delegate

I am a beginner to Obj-C and Xcode 4 and I am currently going through the "Your First Mac Application" on the Mac Dev website. I have managed to get through the main part but I'm struggling on the "Refactor the Application Delegate" section.
I have created a new class (to use as a controller), added an object set to this new class, made the connections from the class to the slider, mute button and textfield, and I have connected the new class object to the app delegate interface file.
Unfortunately an instance of the track class is never created, and therefore the program doesn't work, as the awakeFromNib function never gets called. I have tried placing it in both the app delegate file and the new controller class.
Where am I going wrong???
You have to either create an instance of your new class in IB, or you need to create it programmatically in your AppDelegate object (usually in init or awakeFromNib). You need to have a pointer to that object in your AppDelegate. If you create the new object in IB, you connect it to the Track* pointer in IB. If you do it in code, it's something like:
in .h file:
TrackClass *track;
in .m file:
track = [[Track alloc] init];
Which did you do?
I had the same issue while trying out the tutorial and found out the problem was with my implementation of awakeFromNib
Wrong Code:
- (void)awakeFromNib:(NSNotification *)aNotification
Right Code
- (void)awakeFromNib
There should be no argument passing the implementation of awakeFromNib.

Qutting a cocoa app after closing a window

I have a small osx cocoa app that brings up an IKPictureTaker at start up, I would like for my application to quit after this picture taker is closed. I read that I need to add this code to my NSWindowController class but I have no idea how to access this class (it shows up no where in my class list in XCode):`
-(BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
{
return YES;
}
You need to create a custom object that implements the NSApplicationDelegate protocol and implement the applicationShouldTerminateAfterLastWindowClosed method there.
If you already have an application delegate (you more than likely do), just add it there.
You have to add this method to your application delegate, whatever object that is.

Resources