Вставить управляемый объект в CoreData из XML
Я впервые пытаюсь получить базовые данные и у меня возникают проблемы с работой. У меня в приложении есть xml-анализатор, из которого я пытался добавить всю информацию в основные данные, но продолжаю падать при запуске. Мои основные данные настроены с 1 Entity как "Темы". В этой сущности у меня 15 атрибутов. Ниже приведен автоматический файл xcode, который может быть создан для ManagedObject после того, как я создал свой.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
Вот мои файлы парсера xml, где должно произойти вся магия. В целом все отлично работает с моим парсером, это только когда я делаю
"themesObjects = (Темы *) [NSEntityDescription
insertNewObjectForEntityForName: themesObjects.themeName"
inManagedObjectContext: managedObjectContext];"
Я полагаю, что произойдет сбой приложения, потому что я неправильно вставляю объект в 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]];
}
Это то, что регистрируется при сбое приложения
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
Если у кого-то есть какие-либо предложения или идеи, куда я могу пойти отсюда, это было бы здорово. Я прошу прощения, если кажется, что это большой код, но я чувствовал, что бессмысленно давать другим понять, что на самом деле происходит внутри кода... Спасибо, я ценю любую помощь, оказанную безмерно!
1 ответ
themesObjects = [[Themes alloc]init];
managedObjectContext = [[NSManagedObjectContext alloc] init];
Я вижу две вещи неправильно в этих двух строках. Во-первых, вы не используете назначенный инициализатор для NSManagedObject в вашем инициализаторе Тем. Я знаю это по двум причинам: а) это именно то, что говорится в сообщении об ошибке; б) инициализатор не может знать, какой контекст использовать, потому что вы еще не создали контекст в этот момент. Назначенный инициализатор для NSManagedObjectContext:
-initWithEntity:insertIntoManagedObjectContext:
Тем не менее, обычной практикой является использование NSEntityDescription + insertNewObjectForEntityForName:inManagedObjectContext:
удобный метод для создания и добавления новых объектов в контекст. В любом случае, вам нужно использовать один из них.
Вторая проблема заключается в том, что у вас нет контекста управляемого объекта при создании объекта Themes, и, похоже, вы неправильно настраиваете контекст при его создании. Вы должны установить постоянный координатор хранилища для контекста после его создания.
Обновление: третья проблема заключается в том, что когда вы пишете:
themesObjects = (Themes *)[NSEntityDescription insertNewObjectForEntityForName:themesObjects.themeName" inManagedObjectContext:managedObjectContext];
Вы должны убедиться, что модель имеет объект, который соответствует значению themeObjects.themeName
, Было бы необычно использовать данные, которые вы получаете из файла XML, для определения имени темы, потому что ошибка в файле XML может привести к ошибке, а также потому, что она сильно связывает структуру XML с вашей базовой моделью данных. Убедитесь, что вы не путаете концепцию сущности XML с сущностью Core Data - это две разные вещи. Базовые сущности данных - это различные типы объектов в вашей модели; у вас, вероятно, есть субъект для Темы, например.