I have my custom Managed Object class:
#interface NDAEntity : NSManagedObject
#property (nonatomic, retain) NSString * text;
+(id) entityWithText:(NSString *)text;
-(void) setText:(NSString *)text;
- (void)setPrimitiveName:(NSString *)text;
#end
#implementation NDAEntity
#dynamic text;
+(id) entityWithText:(NSString *)text{
return [[NDAEntity alloc] initWithText:text];
}
-(id) initWithText:(NSString *)text{
if(self = [super init]){
[self setText:text];
}
return self;
}
-(void) setText:(NSString *)text{
[self willChangeValueForKey:#"text"];
[self setPrimitiveName:text];
[self didChangeValueForKey:#"text"];
}
#end
And when I push button execute next code:
NDAEntity *entity = [NDAEntity entityWithText: #"smth"];
I have error:
CoreData: error: Failed to call designated initializer on
NSManagedObject class 'NDAEntity'
How can I solve this?
You can't just alloc init a managed object subclass. You must create the managed object instance from the entity and with reference to a context.
Generally you should be using insertNewObjectForEntityForName:inManagedObjectContext: to do this.
Related
https://github.com/lokming/QuestionBank
I have entities: Bank,Section,Subsection,Set,Question.
I am having problems accessing relationship "NSSet Subsection" in entity Section and getting the message "[UITableViewCell thesubsection]: unrecognized selector sent to instance" from this code
in CRSectionVC.m which fills a tableview cell
- (NSArray *)allQuestions
{
NSSortDescriptor *division = [NSSortDescriptor sortDescriptorWithKey:#"subdivision" ascending:YES];
return [_section2.thesubsection sortedArrayUsingDescriptors:#[division]];
}
I can however access the "NNSet section" relationship in Bank entity using this code
NSSortDescriptor *division2 = [NSSortDescriptor sortDescriptorWithKey:#"division" ascending:YES];
return [self.detailItem2.thesection sortedArrayUsingDescriptors:#[division2]];
_section2 is declared in CRSubsectionVC.h
#property (strong, nonatomic) Section *section2;
The storyboard is
1. CRMasterViewController which displays ‘category’ attribute from Bank entity into a tableview,
Bank.h
#class Section;
#interface Bank : NSManagedObject
#property (nonatomic, retain) NSString * category;
#property (nonatomic, retain) NSSet *thesection;
#end
Bank.m
#implementation Bank
#dynamic category;
#dynamic thesection;
#end
When I tap a ‘category’ I segue and pass a Bank object to CRDetailViewController. I use following code:
NSSortDescriptor *division2 = [NSSortDescriptor sortDescriptorWithKey:#"division" ascending:YES];
return [self.detailItem2.thesection sortedArrayUsingDescriptors:#[division2]];
to fetch section relationship (NSSet *thesection) ‘division’ attribute from Bank into tableview.
Section.h
#class Bank, Subsection;
#interface Section : NSManagedObject
#property (nonatomic, retain) NSString * division;
#property (nonatomic, retain) Bank *bank;
#property (nonatomic, retain) NSSet *thesubsection;
#end
Section.m
#implementation Section
#dynamic division;
#dynamic bank;
#dynamic thesubsection;
#end
If I tap a ‘section’ ’ I segue and pass a Section object to CRSubsectionVC named _section2. When I try to access NSSet *thesubsection to get ‘subdivision’ attribute using code
NSSortDescriptor *division = [NSSortDescriptor sortDescriptorWithKey:#"subdivision"ascending:YES];
return [_section2.thesubsection sortedArrayUsingDescriptors:#[division]];
I get the error [UITableViewCell thesubsection]: unrecognized selector sent to instance. I cannot figure out why automated accessor ‘thesection’ works OK but not ‘thesubsection’ .
Subsection.h
#class Section, Set;
#interface Subsection : NSManagedObject
#property (nonatomic, retain) NSString * subdivision;
#property (nonatomic, retain) Section *section2;
#property (nonatomic, retain) NSSet *set;
#end
Subsection.m
#implementation Subsection
#dynamic subdivision;
#dynamic section2;
#dynamic set;
#end
Fixed the problem. A case of not copying code exactly from working template and understanding core data and table views.
I have a project that include a combined tabbarController and navigation controller.
sorry,becauce i can't post image, the link of image here:
http://s12.postimage.org/58lbzzxm5/Screen_Shot_2012_11_10_at_9_56_07_AM.png
Code Of NAppDelegate.h:
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#interface NAppDelegate : UIResponder <UIApplicationDelegate>
#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;
#end
Code Of NAppDelegate.m:
#import "NAppDelegate.h"
#import "TVC_TabProvince.h"
#implementation NAppDelegate
#synthesize managedObjectContext = _managedObjectContext;
#synthesize managedObjectModel = _managedObjectModel;
#synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
NSArray *arrController = [tabBarController viewControllers];
TVC_TabProvince *controller = (TVC_TabProvince*) [arrController objectAtIndex:0];
controller.managedObjectContext = self.managedObjectContext;
return YES;
}
Before adding the navigation controller, it run without any problem. But when I add this, an error appear:
error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-
[UINavigationController setManagedObjectContext:]: unrecognized selector sent to
instance 0x74b26b0'
The problem is in this line:
TVC_TabProvince *controller = (TVC_TabProvince*) [arrController objectAtIndex:0];
[arrController objectAtIndex:0] is the first view controller of the tab bar controller, so this is the navigation controller and not the TVC_TabProvince controller. The type cast (TVC_TabProvince *) does not change the object, it is still a navigation controller.
So you have to add one step:
NSArray *arrController = [tabBarController viewControllers];
UINavigationController *navController = [arrController objectAtIndex:0];
TVC_TabProvince *controller = [navController. viewControllers objectAtIndex:0];
controller.managedObjectContext = self.managedObjectContext;
It might be more flexible to go the other way around: Instead of "pushing" the managed object context from the application delegate to the table view controller, you "pull" it from the table view controller when needed. So somewhere in "TVC_TabProvince.m" you do
NAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
self.context = [appDelegate managedObjectContext];
Then it does not matter anymore where the table view controller is in the view controller hierarchy. (But that is only a suggestion.)
I have this crash error : * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'JourneeDeTravail''
My AppDelegate.h :
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate> {
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;
NSPersistentStoreCoordinator *persistentStoreCoordinator;
UIWindow *window;
UINavigationController *navigationController;
}
#property (strong, nonatomic) UIWindow *window;
#property (nonatomic, retain) UINavigationController *navigationController;
#property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
#property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (NSURL *)applicationDocumentsDirectory;
- (void)saveContext;
#end
My AppDelegate.m :
#import "AppDelegate.h"
#import "TableViewController.h"
#import "ViewController.h"
#implementation AppDelegate
#synthesize window;
#synthesize navigationController;
#synthesize managedObjectContext =_managedObjectContext;
#synthesize managedObjectModel =_managedObjectModel;
#synthesize persistentStoreCoordinator=_persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
ViewController *viewController = [[ViewController alloc] init];
viewController.managedObjectContext = [self managedObjectContext];
NSLog(#"AppDelegate VC: %#", managedObjectContext);
return YES;
}
- (void)dealloc {
[super dealloc];
}
#end
And a ViewController.h :
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#import "AppDelegate.h"
#interface ViewController : UIViewController{
NSManagedObjectContext *managedObjectContext;
}
#property (retain, nonatomic) IBOutlet UILabel *displayStart;
#property (retain, nonatomic) IBOutlet UILabel *displayEnd;
#property (retain, nonatomic) IBOutlet UITextField *displayResult;
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
- (IBAction)SaveTest:(id)sender;
#end
And ViewController.m :
#import "ViewController.h"
#implementation ViewController
#synthesize managedObjectContext;
- (void)viewDidLoad {
if (managedObjectContext == nil) {
managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate]managedObjectContext];
NSLog(#"After managedObjectContext VC: %#", managedObjectContext);
}
}
- (IBAction)SaveTest:(id)sender {
NSLog(#"Dans SaveTest : %#", managedObjectContext);
NSLog(#"Context: %#",managedObjectContext);
NSLog(#"PS Coord : %#",managedObjectContext.persistentStoreCoordinator);
NSLog(#"MOM : %#", managedObjectContext.persistentStoreCoordinator.managedObjectModel);
NSLog(#"Entities : %#", [[managedObjectContext.persistentStoreCoordinator.managedObjectModel entities] valueForKey:#"JourneeDeTravail"]);
JourneeDeTravail *journee = (JourneeDeTravail *)[NSEntityDescription insertNewObjectForEntityForName:#"JourneeDeTravail" inManagedObjectContext:managedObjectContext];
}
But when I press SaveTest button it crashes with error log saying all my log lines are (null).
Of course I have an Entity called JourneeDeTravail...
Any idea ? Looks like I don't have a managedObjectContext but I don't know what to do to fix that. Thanks for your help !
Just for those of you who have the same problem : I found the solution when I did this tutorial : http://www.techotopia.com/index.php/An_iOS_5_iPhone_Core_Data_Tutorial
The debugger says all. It can't find the entity. The entity is in your case the storage. No Core Data, no Memory.
In AppDelegate.m in time of applicationDidFinishLaunching try to instantiate a storage class. Thats the entitiy the ManageObjectModel search for.
like: myMainThreadStorage = [[StorageClass alloc] init];
Or I have completely misunderstood the last 6 hours of studying my problem and solved it with a later [super viewDidLoad]
I have a rootViewController like so:
Header:
#interface ParkingRootViewController : UIViewController {
UINavigationController *navigationController;
UIToolbar *toolbar;
UIBarButtonItem *lastUpdateLabel;
NSPersistentStoreCoordinator *persistentStoreCoordinator;
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;
}
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#property (nonatomic, retain) IBOutlet UIToolbar *toolbar;
#property (nonatomic, retain) IBOutlet UIBarButtonItem *lastUpdateLabel;
#property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
#property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
#property (nonatomic, readonly) NSString *applicationDocumentsDirectory;
-(IBAction)selectHome:(id)sender;
//-(void)loadOverlays;
-(void)testCoreData;
#end
Implementation:
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
//...
[self testCoreData];
//creating label in tool bar
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 150.0f, 20.0f)];
label.text = #"last updated...";
label.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentCenter;
//label.highlightedTextColor = [UIColor colorWithWhite:0.5 alpha:1.0];
//label.highlighted = YES;
label.font = [UIFont systemFontOfSize:13.0];
label.userInteractionEnabled = NO;
[lastUpdateLabel initWithCustomView:label];
[label release];
[self.view addSubview:self.navigationController.view];
[self.navigationController.view setFrame:self.view.frame];
}
But I need to transfer my managedObjectModel to my table view and then to a map view so that the map view can make queries depending on what the user wants to see. I was consulting some apple sample code which looks like(from Recipes):
- (void)applicationDidFinishLaunching:(UIApplication *)application {
recipeListController.managedObjectContext = self.managedObjectContext;
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
}
I know that is in the appDelegate, but I figure that I can do the same when a row is selected or another view is pushed onto the stack, right? The problem is that I have configured most of my view with a nib which looks like so:
Due to this, I am unable to use a similar strategy that Apple employs to transfer a managedObjectModel to an alternate viewController(in this case PermitListViewController) because I don't access PermitListViewController directly when adding a subview. If anyone has any idea of how I would go about getting my managedObjectModel to my PermitListViewController. Please share! Thanks in advance!
EDIT: I am thinking of placing the managedObjectModel in a singleton class. What are your guys' thoughts on that? Good programming practice? Anything I should be aware of? Thanks.
Why not have the NSManagedObjectContext on the app delegate? Then it would be easily accessible from all your view controllers, and as they are UI they execute on the main thread, and can therefore share the same MOC.
I ended up creating a singleton class for the managedObjectModel using this as a reference (scroll down to "Creating a Singleton Instance").
Almost all the examples I see are done with IB but I don't want to use IB.
What I want to do is, when a user selects a row in the table a UIWebView will be pushed onto the stack and load that particular page while keeping the tab bar and navigation bar. I don't want all the features of a browser rather just be able to scroll through a page beacause the rest of my app controls how a person can navigate through the website through tables.
So I've been able to push other viewcontrollers but pushing a UIWebView with the same method doesn't work.
Here is what I have so far..
This is the Threads.h file
#import "ThreadContent.h"
#import <UIKit/UIKit.h>
#interface Threads : UITableViewController {
NSMutableArray *threadName;
NSMutableArray *threadTitle;
UIActivityIndicatorView *spinner;
NSOperationQueue *operationQueue;
UILabel *loadingLabel;
NSMutableDictionary *cachedForum;
NSMutableArray *forumID;
NSInteger *indexPathRowNumber;
NSMutableArray *threadID;
ThreadContent *threadContent;
}
#property (nonatomic, assign) NSMutableArray *forumID;
#property (nonatomic, assign) NSInteger *indexPathRowNumber;
#end
Part of my Threads.m file where I am trying to push the UIWebView
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"%i",indexPath.row);//get row number
NSLog(#"%#", [threadID objectAtIndex:indexPath.row]);//thread id
//forums.whirlpool.net.au/forum-replies.cfm?t=
//NSString *urlString = [NSString stringWithFormat:#"forums.whirlpool.net.au/forum-replies.cfm?t=%#", [threadID objectAtIndex:indexPath.row]];
threadContent = [[ThreadContent alloc] init];
[self.navigationController pushViewController:threadContent animated:YES];
}
My WebView files.. well i'm not sure how to do that? I did make it a "UIWebView" subclass but if i try to push it on to the stack i get a crash saying it needs it to be a "UIViewController" subclass.
UIWebView is a subclass of UIView not UIViewController.
You need to subclass UIViewController (call it for example WebViewController)
And in the viewDidLoad method create a UIWebView and add it to the view, using addSubview:
You can pass the URL to load in the webView as a property of the WebViewController
-(void)viewDidLoad {
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
[self.view addSubView:webView];
[webView loadRequest:[NSURLRequest requestWithURL:self.urlToLoad]];
[webView release];
}
and in Threads
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"%i",indexPath.row);//get row number
NSLog(#"%#", [threadID objectAtIndex:indexPath.row]);//thread id
//forums.whirlpool.net.au/forum-replies.cfm?t=
//NSString *urlString = [NSString stringWithFormat:#"forums.whirlpool.net.au/forum-replies.cfm?t=%#", [threadID objectAtIndex:indexPath.row]];
threadContent = [[ThreadContent alloc] init];
threadContent.urlToLoad = [NSURL URLWithString:urlString];
[self.navigationController pushViewController:threadContent animated:YES];
}
(or make the webView a property and call the load method in just before or after you push the WebViewController in Threads, I'm not 100% sure if this way would work)