This is my first time trying to accomplish core data and been having some issues getting things working. I have a xml parser in my app that I have been trying to add all the info into core data from but keep crashing on start. I have my core data set up with 1 Entity as “Themes”. In that entity I have 15 attributes. Below is the automatic file xcode can created for a ManagedObject after I created my .CoreData.
Themes.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface Themes : NSManagedObject
@property (nonatomic, retain) NSString * themeName;
@property (nonatomic, retain) NSString * themeArtist;
@property (nonatomic, retain) NSString * themeImage;
@property (nonatomic, retain) NSString * themeDescription;
@property (nonatomic, retain) NSString * twitterName;
@property (nonatomic, retain) NSString * themePrice;
@property (nonatomic, retain) NSString * screenshots;
@property (nonatomic, retain) NSString * cydiaLink;
@property (nonatomic, retain) NSString * themeVersion;
@property (nonatomic, retain) NSString * deciption;
@property (nonatomic, retain) NSString * repo;
@property (nonatomic, retain) NSString * hd;
@property (nonatomic, retain) NSString * sd;
@property (nonatomic, retain) NSString * ipad;
@end
#import "Themes.h"
@implementation Themes
@dynamic themeName;
@dynamic themeArtist;
@dynamic themeImage;
@dynamic themeDescription;
@dynamic twitterName;
@dynamic themePrice;
@dynamic screenshots;
@dynamic cydiaLink;
@dynamic themeVersion;
@dynamic deciption;
@dynamic repo;
@dynamic hd;
@dynamic sd;
@dynamic ipad;
-(void)setThemeName:(NSString *)themeName{
self.themeName = [themeName copy];
}
@end
Here is my xml Parser files where all the magic is supposed to happen. Overall everything works great with my parser it is just when I do
“themesObjects = (Themes *)[NSEntityDescription
insertNewObjectForEntityForName:themesObjects.themeName”
inManagedObjectContext:managedObjectContext];”
the app will crash I assume because I am not correctly inserting the object into the coredata.
#import <Foundation/Foundation.h>
#import "ThemeParseObject.h"
#import "Themes.h"
@class ThemeParseObject;
@interface ThemeXMLParser : NSObject <NSXMLParserDelegate> {
NSMutableData *recivedData;
NSMutableArray *themes;
NSMutableString *currentNodeContent;
NSXMLParser *parser;
Themes *themesObjects;
NSManagedObjectContext *managedObjectContext;
NSMutableArray *themeArray;
ThemeParseObject *currentTheme;
}
@property (readonly, retain) NSMutableArray *themes;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) NSMutableArray *themeArray;
-(id) loadXMLByURL:(NSString *)urlString;
@end
#import "ThemeXMLParser.h"
@implementation ThemeXMLParser
@synthesize themes;
@synthesize managedObjectContext;
@synthesize themeArray;
-(id) loadXMLByURL:(NSString *)urlString{
themesObjects = [[Themes alloc]init];
managedObjectContext = [[NSManagedObjectContext alloc] init];
themes = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
[parser parse];
return self;
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
if ([elementname isEqualToString:@"theme"])
{
currentTheme = [ThemeParseObject alloc];
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *ObjectsToInsert = [NSEntityDescription
insertNewObjectForEntityForName:@"Themes"
inManagedObjectContext:context];
if ([elementName isEqualToString:@"name"]) {
currentTheme.themeNameString = currentNodeContent;
themesObjects.themeName = currentTheme.themeNameString;
[ObjectsToInsert setValue:themesObjects.themeName forKey:@"themeName"];
}
if ([elementName isEqualToString:@"creator"]) {
currentTheme.themeCreator = currentNodeContent;
// themesObjects = (Themes *)[NSEntityDescription
insertNewObjectForEntityForName:@"themeArtist"
inManagedObjectContext:managedObjectContext];
}
if ([elementName isEqualToString:@"price"]) {
currentTheme.themePrice = currentNodeContent;
//themesObjects = (Themes *)[NSEntityDescription
insertNewObjectForEntityForName:@"themePrice"
inManagedObjectContext:managedObjectContext];
}
if ([elementName isEqualToString:@"twitter"]) {
currentTheme.creatorTwitterName = currentNodeContent;
//themesObjects = (Themes *)[NSEntityDescription
insertNewObjectForEntityForName:@"twitterName"
inManagedObjectContext:managedObjectContext];
}
if ([elementName isEqualToString:@"link"]) {
currentTheme.cydiaLink = currentNodeContent;
//themesObjects = (Themes *)[NSEntityDescription
insertNewObjectForEntityForName:@"cydiaLink"
inManagedObjectContext:managedObjectContext];
}
if ([elementName isEqualToString:@"deciption"]) {
currentTheme.deciption = currentNodeContent;
//themesObjects = (Themes *)[NSEntityDescription
insertNewObjectForEntityForName:@"deciption"
inManagedObjectContext:managedObjectContext];
}
if ([elementName isEqualToString:@"screenshots"]) {
currentTheme.screenShots = currentNodeContent;
}
if ([elementName isEqualToString:@"promo"]) {
currentTheme.tblViewImage = currentNodeContent;
}
if ([elementName isEqualToString:@"description"]) {
currentTheme.themeDescription = currentNodeContent;
}
if ([elementName isEqualToString:@"version"]) {
currentTheme.themeVersion = currentNodeContent;
// NSLog(@"version: %@", currentNodeContent);
}
if ([elementName isEqualToString:@"repo"]) {
currentTheme.themeRepo = currentNodeContent;
// NSLog(@"repo: %@", currentNodeContent);
}
if ([elementName isEqualToString:@"HD"]) {
currentTheme.HD = currentNodeContent;
// NSLog(@"HD: %@", currentNodeContent);
}
if ([elementName isEqualToString:@"SD"]) {
currentTheme.SD = currentNodeContent;
// NSLog(@"SD: %@", currentNodeContent);
}
if ([elementName isEqualToString:@"iPad"]) {
currentTheme.ipad = currentNodeContent;
//NSLog(@"iPad: %@", currentNodeContent);
}
if ([elementName isEqualToString:@"iPhoneScreenshots"]) {
currentTheme.fullScreenShots = currentNodeContent;
// themesObjects = (Themes *)[NSEntityDescription
insertNewObjectForEntityForName:@"screenshots"
inManagedObjectContext:managedObjectContext];
// NSLog(@"fullScreenShots: %@", currentNodeContent);
}
if ([elementName isEqualToString:@"theme"])
{
[themes addObject:currentTheme];
[currentTheme release];
currentTheme = nil;
[currentNodeContent release];
currentNodeContent = nil;
}
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentNodeContent = (NSMutableString *) [string
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
This is what gets logged when the app crashes
2012-01-06 08:02:18.619 ThemeCatcher[2667:207] CoreData: error: Failed to call
designated initializer on NSManagedObject class 'Themes'
2012-01-06 08:02:19.000 ThemeCatcher[2667:207] -[Themes themeName]: unrecognized
selector sent to instance 0x87072d0
If anyone has any suggestion or ideas where I can go from here that would be awesome. I apologize if this seems like a lot of code to look at but I felt it was nessicarry to give others an idea what really is going on inside the code… Thank you I appreciate any help given immensely!
I see two things wrong in these two lines. First, you’re not using the designated initializer for NSManagedObject in your Themes initializer. I know that for two reasons: a) that’s exactly what the error message says; b) the initializer can’t know what context to use because you haven’t created the context at that point. The designated initializer for NSManagedObjectContext is:
However, it’s common practice to use NSEntityDescription’s
+ insertNewObjectForEntityForName:inManagedObjectContext:convenience method to create and add new objects to a context instead. Either way, you need to use one of these.The second problem is that you don’t have a managed object context when you create your Themes object, and it looks like you’re not setting up the context correctly when you do create it. You should be setting a persistent store coordinator for the context after you create it.
Update: A third problem is that when you write:
you need to make sure that the model has an entity that matches the value of
themeObjects.themeName. It’d be unusual to use data that you get from an XML file to determine the theme name, because a mistake in the XML file would cause an error, and also because it strongly ties the structure of the XML to your Core Data model. Be sure that you’re not confusing the concept of XML entity with Core Data entity — those are two different things. Core Data entities are the different types of objects in your model; you probably have an entity for Themes, for example.