I'm just experimenting and trying to learn. I have a Simple view with 1 textbox, label and save button. When the button is pressed I want to save the data in the textbox to core data and update the label. Thanks
Inside DailyClinicalPerformanceRecord.m
- (IBAction)btnSave:(id)sender {
DailyClinicalPerformanceRecord* delegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext* managedObjectContext = delegate.managedObjectContext;
NSManagedObject* newForm;
newForm = [NSEntityDescription insertNewObjectForEntityForName:#"DCPR" inManagedObjectContext:managedObjectContext];
[newForm setValue:txtIncidentNum.text forKey:#"indidentNum"];
txtIncidentNum.text = #"";
NSError *error;
[managedObjectContext save:&error];
status.text = #"Form Saved";
}
Inside DailyClinicalPerformanceRecord.h
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#interface DailyClinicalPerformanceRecord : UIViewController<UIApplicationDelegate>{
UITextField *txtIncidentNum;
UILabel *status;
}
#property (nonatomic, retain) IBOutlet UITextField *txtIncidentNum;
#property (nonatomic, retain) IBOutlet UILabel *status;
- (IBAction)btnSave:(id)sender;
- (IBAction)btnBack:(id)sender;
- (void)dismissKeyboard;
#end
I get error:
/Users/specked/Programs/EMTDocs/EMTDocs/DailyClinicalPerformanceRecord.m:67: error: request for member 'managedObjectContext' in something not a structure or union
And Warning
/Users/specked/Programs/EMTDocs/EMTDocs/DailyClinicalPerformanceRecord.m:66: warning: type 'id <UIApplicationDelegate>' does not conform to the 'NSCoding' protocol
It's a little hard to give a definitive answer to your question as you didn't give any details on what the problem is. But here's a few things to check:
Check that you've made connections to the txtIncidentNum and status objects along with the btnSave method in Interface Builder
Make sure that btnSave is being called (NSLog is handy)
Make sure that managedObjectContext is not nil
Also, something is kind of fishy with this line:
DailyClinicalPerformanceRecord* delegate = [[UIApplication sharedApplication] delegate];
The fishy thing is that it's inside of DailyClinicalPerformanceRecord.m. If this code is in DailyClinicalPerformanceRecord.m and DailyClinicalPerformanceRecord is your delegate, you can get your managedObjectContext via self and not jump through these hoops. Or, it could be indicative of a larger problem and/or an organizational issue.
Hopefully one of those items will get you on track. If not, please expand your question with more details about what is and is not happening when you press the save button.
Related
I need to capture data in the viewController and stay stored during the execution of the app and you can use it in any other View that I have, try creating a NSString in AppDelegate as follows:
AppDelegate.h
property (Retain, nonatomic) NSString * token;
AppDelegate.m
synthesize token;
and then call it in the other class as follows
adding include
#include "AppDelegate"
creating an object
AppDelegate * theToken = [[AppDelegate allow] init];
label.text = theToken.token;
but not working me, in some ViewController appears nill
The problem is that you're creating a brand new instance of the AppDelegate instead of accessing the current one.
Instead of:
AppDelegate * theToken = [[AppDelegate alloc] init];
try this:
AppDelegate * theToken = (AppDelegate*)[[UIApplication sharedApplication] delegate];
Edit: As rmaddy and Louis Tur also pointed out in the comments, your use of retain and synthesize are pre-ARC relics.
"Strong" is the ARC equivalent of "retain" so you can update your property to the following in order to maintain a strong reference:
property (strong, nonatomic) NSString * token;
Furthermore, once upon a time (until some time post-ARC but pre-iOS6 if I remember correctly), synthesizing your .h properties in your .m was required. But in the modern era, it's generally good practice to leave out synthesize in your .m and instead access the property within AppDelegate.m using "self"; for example, self.token.
I would like to use a NSArray like property in whole class (self.array), but I don't know how. Now I have this code in my LoginVC:
LoginVC.h:
#import <UIKit/UIKit.h>
#interface LoginVC : UIViewController
#property (strong, nonatomic) IBOutlet UITextField *usernameTextField;
#property (strong, nonatomic) IBOutlet UITextField *passwordTextField;
#property (strong, nonatomic) IBOutlet UIScrollView *loginButton;
#property (nonatomic, strong) NSArray *allUsers;
#end
LoginVC.m:
- (void)viewDidLoad
{
if (debug == 1) {
NSLog(#"Running %# '%#'", self.class, NSStringFromSelector(_cmd));
}
[super viewDidLoad];
// Do any additional setup after loading the view.
UserController *userController = [[UserController alloc]init];
[userController getUsers];
self.allUsers = [NSArray new];
self.allUsers = [userController getUsers];
}
The method getUser return a NSArray, but this solution doesnt work. The llbd report an error: *Thread 1: EXC_BAD_ACCESS (code=2, address=0x38)*
I think the problem is with initialization the array and assignment.
Declaration of getUsers:
-(NSArray *)getUsers{
CoreDataHelper *cdh = [(AppDelegate *)[[UIApplication sharedApplication]delegate] cdh];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"User"];
NSArray *users = [cdh.context executeFetchRequest:request error:nil];
return users;
}
The method "getUsers" works correctly.
Here is a screen of the error. Its strenge, because self.allUsers contents one object with userName "admin" and its absolutely correct.
https://www.dropbox.com/s/ui5rtq9ov0p2xx9/Screenshot%202014-03-02%2019.24.53.png
I think the problem is in array, because when I delete the code with assignment to array. The error disappears.
The key here is you UserController object. Your log output says failed to call designated initialiser for NSManageObject Subclass UserController which makes me assume it is an NSManagedObject.
NSManagedObjects are autoreleased and in your case, it is not retained by an NSManagedObjectContext, which makes it cause the EXC_BAD_ACCESS. Try to run your app with zombies enabled, it should show you what object is being released, and causing the error.
EDIT: It may be that I'm wrong, but it could also be that the way your CoreDataHelper is initialised is relevant. See this answer for how to enable Zombies when you test your app: How to enable NSZombie in Xcode?
I'm now building up Core Data based iOS application and when I tried to insert new managed object by executing [NSEntityDescription insertNewObjectForEintityForName:#"myModel" inManagedObjectContext:_managedObjectContext]; within AppDelegate.m, I got the error described on the title.
Here's my AppDelegate.h file:
#import
#interface AppDelegate : UIResponder
#property (strong, nonatomic) UIWindow *window;
#property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
#property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
// maybe required?
//#property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
#end
And here's my AppDelegate.m file (only displaying the relevant part):
#import "AppDelegate.h"
#import "MyModel.h"
#import "listViewController.h"
#implementation AppDelegate
#synthesize managedObjectContext = _managedObjectContext;
#synthesize managedObjectModel = _managedObjectModel;
#synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//managed object context settings
UITabBarController *tabbarController = (UITabBarController *)self.window.rootViewController;
UINavigationController *navigationController = [[tabbarController viewControllers] objectAtIndex:0];
listViewController *listcontroller = [[navigationController viewControllers] objectAtIndex:0];
listcontroller.managedObjectContext = self.managedObjectContext;
NSLog(#"%#", _persistentStoreCoordinator.managedObjectModel);
MyModel *newMyModel = [NSEntityDescription insertNewObjectForEntityForName:#"MyModel" inManagedObjectContext:_managedObjectContext];
return YES;
}
in this application, I want to use tabbar controller as root view controller and when the app starts, I want to navigation controller as the tabbar controller's root view controller, and use tableview controller as the navigation controller's root view controller. And in the table view controller, I want to use Core Data functionality to display a lot of entities to users.
If I used breakpoint at the exact point of the NSLog() output, it didn't return any errors. And when I moved one line forward to output the log message, the following output returns:
() isEditable 0, entities {
}, fetch request templates {
}
which means I don't have entities for some reasons.
So why are there no entities in this situation? From this answer here over SO, I don't misspelled my entity name. Also, my objectModelContext is not set to nil. So did I set the wrong managed object? Am I doing something wrong in the first three lines in didFinishLaunchingWithOptions method?
Or is there something that is causing the issue here? Or what am I missing?
I use iOS 7 and Xcode 5 and I don't have any managed objects in my entity - after all, the error happened when I tried to instantiate those managed objects.
Thanks.
As discussed in the comments above, it looks like you probably needed to check how your ManagedObjectModel was being initialized.
I'd personally recommend avoiding placing Core Data code directly in your app delegate - I don't think Apple's templates do this very well. Check out this blog post as a great example of the minimal amount of code that's required to set up a Core Data stack, as well as a brief explanation of what each part does.
Regarding your extra comment question - the managedObjectContext method you have is called whenever your managedObjectContext property is accessed. So, when you do:
listcontroller.managedObjectContext = self.managedObjectContext;
This calls the managedObjectContext method on self, which (if I remember correctly) will initialize your context.
So I've declared this in my appDelegate.h
#property(nonatomic,strong) NSMutableArray *featured;
I've synthesized it like so in my appDelegate.m
#synthesize featured;
When I log that out in the appDelegate with the object stored in there, I get the value it's supposed to have
In a viewController.h file I have declared this
#property(nonatomic,strong) NSMutableArray *featured;
In the viewController.m file I've synthesized it like this
#synthesize featured;
I then print out this line and get a null value
NSLog(#"HERE %#", featured);
That same line prints out the correct value in my appDelegate.m file. I'm completely lost. I've set it up in the way I've done it for a previous class exercise. Thanks in advance!
Edit:
I created the array in appDelegate.m file like so in a method I called loadFeatured
featured = [NSMutableArray array];
for (id dict in tempArray)
{
//NSLog(#"dict=%#",dict);
NSString *shopName = [dict objectForKey:#"shopName"];
NSString *drinkName = [dict objectForKey:#"drinkName"];
NSNumber *likes = [dict objectForKey:#"likes"];
NSNumber *dislikes = [dict objectForKey:#"dislikes"];
NSString *review = [dict objectForKey:#"review"];
Featured *feat = [[Featured alloc] initWithName:shopName drinkName:drinkName likes:likes dislikes:dislikes review:review];
NSLog(#"feat=%#\n\n",feat);
[featured addObject:feat];
}
NSLog(#"there is %d featured",[featured count]);
NSLog(#"HERE %#", featured);
Here is the way, how to access the data stored in the app delegate from your viewcontroller.
You need not synthesize the object in the viewcontroller. Just import your appdelegate file and copy the following code wherever necessary.
NSMutableArray * nArray =[ (AppDelegate*) [[UIApplication sharedApplication] delegate] featured];
The above code gives you the required array from the app delegate.Now you can make use of the nArray object to display the details in the console.
NSLog(#"%#",nArray.description);
It's hard to say how to do this without knowing the structure of your app. You could pass a pointer to the array to your view controller, if you have access to that view controller from the app delegate. The other way is to get a reference to the app delegate in your view controller, and then access its array. That can be done like this:
AppDelegate *appDel = [UIApplication shared application].delegate;
NSArray *myControllerArray = appDel.featured;
You'll need to import your app delegate into your controller's .m file to use this approach.
Since you already declared a property in appDelegate.h you can access it in the other viewController like this:
#import "appDelegate.h"
and you can access the value it by using something like this:
((AppDelegate *)[[UIApplication sharedApplication]delegate]).featured
If you need to access an NSArray or any other object in any class, via AppDelegate, just create a property to access your ViewController, like so, in your AppDelegate class:
#import "ViewController.h"
#property (nonatomic, strong) AppDelegate *appDelegate;
#property (nonatomic, strong) ViewController *viewController;
In your ViewController class:
#import "AppDelegate.h"
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
ViewController *viewControllerREFERENCE = [appDelegate viewController];
Then you'll have access to any value on your ViewController, via AppDelegate.
I hope that helps you.
I'm trying to create an app based on Apple's example project TheElements, but using Core Data for the model. In Core Data I have 4 related DB tables. In the UI I have several tableViews, each showing rows from a different Db table. Clicking a row in a tableView drills down to items in a related table, shown in another TableView.
Everything is working but the app crashes unexpectedly at random times with the error: Program received signal: “EXC_BAD_ACCESS”. BTW this error only shows in the console when debugging on the device. No error shows when debugging on the simulator. This screen grab shows the contents of the debugger after a crash.
I have no idea how to decipher the debugger. All I can see is the crash seems to stem from the main() function and _PFManagedObjectReferenceQueue is also listed, which leads to guess that I'm doing something wrong with Core Data.
To implement Core Data I'm adding the following to my App Delegate header:
#private
NSManagedObjectContext *managedObjectContext_;
NSManagedObjectModel *managedObjectModel_;
NSPersistentStoreCoordinator *persistentStoreCoordinator_;
#property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
#property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator
and adding Apple's default methods for these to App Delegate implementation file.
Then to my Data Source Protocol header I've added:
#property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;`
and my Data Source header files are as follows:
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#import "TableViewDataSourceProtocol.h"
#interface MatchesAllDataSource : NSObject <UITableViewDataSource,TableViewDataSource, NSFetchedResultsControllerDelegate>
{
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
}
#end
When a table cell is clicked I pass the selectedObject as follows:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)newIndexPath
{
// deselect the new row using animation
[tableView deselectRowAtIndexPath:newIndexPath animated:YES];
// get the element that is represented by the selected row.
Match *selectedMatch = [dataSource objectForIndexPath:newIndexPath];
// create an AtomicElementViewController. This controller will display the full size tile for the element
MatchViewController *matchController = [[MatchViewController alloc] init];
// set the element for the controller
matchController.selectedMatch = selectedMatch;
// push the element view controller onto the navigation stack to display it
[[self navigationController] pushViewController:matchController animated:YES];
[matchController release];
}`
Does anyone have any idea what might be causing my crash?
Will someone please point me in the right direction to look for an answer?
Is there a better way to implement Core Data with multiple tableViews?
Will someone point me to a good example of Core Data with multiple tableViews?
I had this problem too with Marcus' code because I changed the UITableViewController to a regular UIViewController and forgot to put in the title. Here is his original code:
- (id)initWithStyle:(UITableViewStyle)style {
if (self = [super initWithStyle:style]) {
self.title = #"Australia";
}
return self;
}
So if you happened to have changed things make sure that you are setting the self.title somewhere so the custom NSArray+PerformSelector can see it when the app is initializing... like in init.
I had this a few days ago. In my case, I was accessing an object that had already been deallocated.
Also I passing the managedObjectContext object from view to view as the user navigates down the navigationController views like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)newIndexPath
{
matchSegmentedController.selectedMatch = selectedMatch;
matchSegmentedController.managedObjectContext = dataSource.managedObjectContext;