Coredata integration into existing application problem iphone - iphone

I'm integrating coredata into my existing application as given in http://wiresareobsolete.com/wordpress/2009/12/adding-core-data-existing-iphone-projects/.
I'm facing a problem in insertion of data. My data isn't getting inserted into the following entity.
I'm importing coredata framework into the class Editorial.
#interface Editorial : NSManagedObject {
NSInteger id;
NSString *type;
}
#property (nonatomic, assign) NSInteger id;
#property (nonatomic, retain) NSString *type;
And in Editorial.m I'm writing:
#implementation Editorial
#synthesize id, type;
In my .xcmodel also, Editorial is subclassing NSManagedObject and having the mentioned variables with corresponding types.
I think I'm missing something very obvious. But I'm not getting it. Generally while using coredata, if created at the beginning of the project, it automatically inserts attributes and they are not declared in interface and are synthesized with #dynamic. But while integrating coredata at later time, should the corresponding classes be created the way coredata creates them for us?
EDIT: This is how I'm inserting values for Editorial object.
self.managedObjectContext = appDelegate.managedObjectContext;
newEditorial = (Editorial *)[NSEntityDescription
insertNewObjectForEntityForName:#"Editorial"
inManagedObjectContext:self.managedObjectContext];
strTitle = [NSString stringWithFormat:#"%#",[object valueForKey:#"eletitle"]];
[newEditorial setEletitle:[NSString stringWithFormat:#"%#", strTitle]];
[newEditorial setElecompany:[NSString stringWithFormat:#"%#", strTitle]]; // CRASHING HERE
[self saveAction];
One more thing that it's crashing at the 2nd string insertion at shown line. I'm getting
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSManagedObject setElecompany:]: unrecognized selector sent to instance 0x4658800' at this line.
NSString *eleCompany exists in the specified coredata entity as well as the class. Also strTitle is containing string and not assigning it to eleTitle as well as eleCompany both of which are strings and exist in class as well as in coredata entity.
Can anybody please help?
This' really urgent.
Thanx in advance.

NSManagedObject instances probably do not contain NSInteger attributes — you probably meant to use NSNumber instead, which is a Core Foundation object type that can be serialized in Core Data.
id is a keyword and very likely reserved. Try naming your NSNumber attribute differently.
After updating your model with new attribute and relationship changes, you will always need to modify or recreate header and implementation files for your managed objects.

Related

How to add an object to a NSMutableArray that is stored in a CoreData iOS database?

I have an NSManagedObject subclass where absences is an NSMutableArray
#interface Record : NSManagedObject
#property (nonatomic, retain) id absences;
#end
I want to be able to add items to the absences array; however, if I do [myRecord.absences addObject:SomeObj the record does not save properly. It almost appears that the NSManagedObject does not know that I updated the absences array.
Nevertheless, if I add SomeObj to some localAray, then set myRecord.absences = localArray, the NSManagedObject saves correctly.
Can someone explain this behaviour and how I might avoid it...thanks
You're exactly right, in the first case you're changing an object outside of NSManagedObject field of view. To solve this, Apple doc says the following
For mutable values, you should either transfer ownership of the value to Core Data, or implement custom accessor methods to always perform a copy.
So declaring your property with (copy) should suffice.

Objective-C property access: unrecognized selector sent to instance

I am new to objective-c, but coding for many years now. Somehow I don't get warm with Objective-C. I searched google and stackoverflow, but I think my problem is just to simple and stupid that no one has asked this yet.
My Code is based on DateSelectionTitles Example. http://developer.apple.com/library/ios/#samplecode/DateSectionTitles/Introduction/Intro.html
I have an NSManagedObject
#interface Event : NSManagedObject
#property (nonatomic, retain) NSDate * date;
...
// Cache
#property (nonatomic, retain) NSString * primitiveSectionIdentifier;
All prperties are defined in my datamodel, except the primitiveSectionIdentifier (as in the apple example)
But when I call
NSString *tmp = [self primitiveSectionIdentifier];
I get the Exception
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Event primitiveSectionIdentifier]: unrecognized selector sent to instance 0x74850c0'
To put it simple:
Event *foo = [[Event alloc] init];
if (foo.primitiveSectionIdentifier) {
NSLog(#"YEAH");
}
throws the same exception. So I basically want to check if primitiveSectionIdentifier is nil. But when I access the property, it throws an exception? Do I need to alloc each property before I can check if it has a value?!
Which of the Objective-C basics am I not getting here?
Thanks a lot for responses!
There is only one way how this can happen without compiler warnings - you must have written #dynamic primitiveSectionIdentifier; in your implementation file. This means that you don't want to define the method because you believe it is already defined somewhere else.
You are using a NSManagedObject, do you know how it works? You declare methods without implementation (putting #dynamic in the implementation) and when the method is called, it is not found and a special handler [NSObject doesNotRecognizeSelector:] is called instead. This handler checks the Core Data model whether an attribute for the given selector exists and if it doesn't, it throws the exception you are seeing.
So, the problem might the caused by the fact that primitiveSectionIdentifier is not declared in your model.
You are using an older example program, which uses a different style of memory management; if you are compiling under the iOS 5 or 6, that may be causing the problem.
Try
NSLog(#"primitiveSectionIdentifier = %#", self.primitiveSectionIdentifier);
If it doesn't give you the string you are looking for then the problem is likely in that the string object was never initialized and is still set to nil. In that situation, the code would compile, but sending a selector to a nil pointer would throw up an exception.

Programmatically add attributes to Core Data

I am developing a application that uses core data. In my application i would like every user to have the same database. So i want all of the devices to share the same core data objects.
In order to do that 'synchronization' I found a presentation on this answer that discussed this matter. In the presentation, it is suggested that I add attributes such as 'creationDate' and 'modificationDate' to every object in Core Data.
So to do that, i tried to subclass NSManagedObject (MyManagedObject) in order to add those properties to every object in core data. I also made every NSManagedObject subclass I had (generated automatically by the model) subclass MyManagedObject.
The problem is that the properties I added to the NSManagedObject subclass do not persist in the database. So when I close and reopen the application, 'creationDate' becomes (null).
Here's some of my code (header):
#interface MyManagedObject : NSManagedObject
#property (nonatomic, retain) NSDate * modificationDate;
#property (nonatomic, retain) NSDate * creationDate;
#end
And here's the .m file:
#implementation MyManagedObject
#synthesize modificationDate, creationDate;
-(void)willSave {
[super willSave];
self.modificationDate = [NSDate date];
}
-(void)awakeFromInsert {
[super awakeFromInsert];
[self setCreationDate:[NSDate date]];
[self setModificationDate:[NSDate date]];
}
Any help, directions or reading would be greatly appreciated. I have been struggling with this for a while now. I need a better way than adding these attributes to EVERY single entity in the model. Thanks in advance
PS: i intend to have a 'truth database' (a .sqlite file) in a server. The synchronization will be between the server and the iPhone. Such as suggested in the presentation
If you create MyManagedObject in the data model design tool and also register it as the parent of other entities inside that tool, this should almost work. (I suspect you didn't do that because of the #synthesize statement...those would usually be #dynamic.)
The one other problem to fix is that you have to test whether you've already changed an object's property (self.modificationDate in your case) before changing it again or else willSave continues to get called. A BOOL value that gets set after the first change and cleared in didSave is a simple thing to test.

Property not found on object of type

I have a simple question:
I have a NSManagedObject subclass that I've been using for some time and it was working perfectly fine.
Today I added a new property to it with the corresponding iVar. The property is a simple (nonatomic,retain) NSString *.
And as normal i added #synthesize to the property to generate setter and getter functions.
However, there is no way i can use the newly defined property!!! I keep getting "property not found on object of type" error and my build fails.
Here are a few chunks of code that will clear things out:
//import the core data header first CoreData/CoreData.h
#interface Contact : NSManagedObject
{
NSString *contactID;
NSString *firstName;
NSString *myDevMod;
}
#property (nonatomic,retain) NSString *contactID;
#property (nonatomic,retain) NSString *firstName;
#property (nonatomic,retain) NSString *myDevMod;
#end
and the corresponding .m implementation:
#import "Contact.h"
#implementation Contact
#synthesize contactID, firstName, myDevMod;
and the code that uses the Contact class:
#import "Contact.h" //at the start
Contact *aContact = [[Contact alloc] init];
aContact.contactID = someId; //works perfectly fine
aContact.firstName = someName; //works perfectly fine
aContact.myDevMod = #""; //THIS IS WHERE THE ERROR OCCURS!!
[aContact doSomethingHere];
[aContact release];
What do you think could be the error??
Thanks in advance for your support.
Weirdly the site won't let me add a comment so :
comment:
Sounds odd. First thing I'd try is removing the #property lines and #synthesize line - so the getters and setters are created automagically. Also try: aContact.myDevMod = someName; to see if that actually works - might shed some light.
I had exact the same problem last night. It took me about 5 hours to fix that. My first attempts were to create the model classes again with menue Editor -> Create NSManagedObject Subclass...
But that didn´t help. Even if i had deleted the classes beforehand Xcode did not recognize the properties. I´ve deleted the model as well and rebuild it with same name. And created the NSManagedObject Subclasses again. Didn't help. Then i´ve deleted the model and the MOS again and build it up from scratch! But with different names! Took me again a long time to change my code but after that everthing seemed to be normal. Now i can add, change and delete attributes in the model and the properties NSManagedObject Subclasses and Xcode recognizes them again.
But boy, it almost drove me nuts!!! And i still don't know what happend!
My experience is that it isn't the model or the objects that need to be recreated.
Most of the time you can recreate the file you are working in. Make a new NSView of what every .h and .m file and copy the info over to the new file, and it will work.

Implementing Transient Properties

I am adding a transient property to my Core Data-based app, and I think I am missing something. In the Data Model Editor, I added a optional, transient, BOOL property called isUnderwater.
In my model's header file, I added: #property (nonatomic) BOOL isUnderwater;, then I implemented these methods in the implementation file:
- (BOOL)isUnderwater {
... implementation ...
return (ret);
}
- (void)setIsUnderwater:(BOOL)isUnderwater {}
But when I try to use isUnderwater as a condition in a NSPredicate, I get this error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath isUnderwater not found in entity <NSSQLEntity Wheel id=2>'.
Any ideas?
Thanks!
First, you can't use a transient property in a NSFetchRequest that is going against a SQLite store. When you are using SQLite the NSFetchRequest is translated into sql and run against the database, long before your transient is ever touched.
Also, you should not be implementing the accessors, you should be using #synthesize instead.
Next, if you are wanting to set the transient property then you should be setting it in the -awakeFromFetch and/or -awakeFromInsert instead of overriding the getter.
Next, your property should be called underwater and the #property definition should be:
#property (nonatomic, retain, getter=isUnderwater) NSNumber *underwater;
Note: even though you are declaring it a boolean in your model, it is still a NSNumber in code.
Lastly, setting the optional flag on a transient property has no value since it will be thrown away anyway.
Update
You can apply additional filters (even against transient properties) once the entities are in memory. The only limitation is that you can't use transient properties when you are going out to the SQLite file.
For example, you could perform a NSFetchRequest that loads in all of the entities. You could then immediately apply a second NSPredicate against the returned NSArray and further filter the objects down.