0

There seems to be a very weird bug in my app in which I'm using Core Data.

I handled everything required already, and it was working for like past recent weeks.

I closed the project yesterday, and started development today ( with no modifications in code ) and now every time I wanna add a row to my database, I get an exception saying the following class is not a subclass of NSManagedObject, which I'm ridiculously sure is not true, first because it was working for days, and second because I generated them automatically as NSManagedObject subclasses. I tried regenerating classes using Editor->Create NSManagedObject Subclasses in my data model, but it didn't help me at all.

It's really weird that I get this exception out of blue and all of a sudden WITHOUT EVEN A LINE OF MODIFICATION in my code :(

Anybody got any idea ? I really appreciate any help. Thanks

BTW, Here're some code that may help :

The Error :

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '"Message" is not a subclass of NSManagedObject.

Message Class Header File (Auto-Generated) :

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class File;

@interface Message : NSManagedObject

@property (nonatomic, retain) NSString * data;
@property (nonatomic, retain) NSDate * date;
@property (nonatomic, retain) NSString * fileId;
@property (nonatomic, retain) NSString * number;
@property (nonatomic, retain) NSString * status;
@property (nonatomic, retain) NSString * type;
@property (nonatomic, retain) NSString * xmppId;
@property (nonatomic, retain) File *contains;

@end

The method in which I try to create a new message object :

+ (void)sendXMPPMessage:(NSString *)messageStr containingFile:(NSData *)fileData toNumber:(NSString *)number
{
    if(fileData == nil)
    {
        NSString *newID = [self generateNewXMPPMessageID];

        SunBirdAppDelegate *appDelegate = (SunBirdAppDelegate *)[[UIApplication sharedApplication] delegate];
        [appDelegate sendXMPPMessage:messageStr withID:newID toNumber:number];

        NSMutableDictionary *messageDataDic = [[NSMutableDictionary alloc] init];

        [messageDataDic setObject:messageStr forKey:@"body"];
        [messageDataDic setObject:@"Outgoing" forKey:@"type"];
        [messageDataDic setObject:newID forKey:@"xmppId"];
        [messageDataDic setObject:@"Sending" forKey:@"status"];
        [messageDataDic setObject:[NSDate date] forKey:@"date"];
        [messageDataDic setObject:number forKey:@"number"];

        [Message messageWithMessageInfo:messageDataDic inManagedObjectContext:[appDelegate managedObjectContext]];
    }
    else
    {
        //Handle Database With File Data
    }
}

Creating a New Message Object -> The Create Category On Message Class (Message+Create.m) :

+ (Message *)messageWithMessageInfo:(NSDictionary *)messageInfo inManagedObjectContext:(NSManagedObjectContext *)context
{
    SunBirdAppDelegate *appDelegate = (SunBirdAppDelegate *)[[UIApplication sharedApplication] delegate];

    Message *newMessage = nil;

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Message"];
    request.predicate = [NSPredicate predicateWithFormat:@"xmppId = %@", [messageInfo objectForKey:@"msgId"]];
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"xmppId" ascending:YES];
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

    NSError *error = nil;
    NSArray *matches = [context executeFetchRequest:request error:&error];

    if (!matches || ([matches count] > 1))
    {
        // handle error
    }
    else if ([matches count] == 0)
    {
        newMessage = [NSEntityDescription insertNewObjectForEntityForName:@"Message" inManagedObjectContext:context];
        newMessage.data = [messageInfo objectForKey:@"body"];
        newMessage.type = [messageInfo objectForKey:@"type"];
        newMessage.date = [messageInfo objectForKey:@"date"];
        newMessage.xmppId = [messageInfo objectForKey:@"xmppId"];
        newMessage.status = [messageInfo objectForKey:@"status"];
        newMessage.number = [messageInfo objectForKey:@"number"];

        if ( [[messageInfo allKeys] containsObject:@"fileId"] )
        {
            newMessage.fileId = [messageInfo objectForKey:@"fileId"];
            newMessage.contains = [messageInfo objectForKey:@"fileData"];
        }
        else
        {
            newMessage.fileId = NULL;
            newMessage.contains = NULL;
        }
    }
    else
    {
        newMessage = [matches lastObject];
        NSLog(@"WARNING : NO NEW MESSAGE STORED IN DB ! MESSAGE WITH SAME XMPPID RETURNED");
    }
    [appDelegate saveContext];
    return newMessage;
}

And this is the line on which I'm being informed Message is not a subclass of NSManagedObject :

newMessage = [NSEntityDescription insertNewObjectForEntityForName:@"Message" inManagedObjectContext:context];

Sepehrom
  • 1,335
  • 2
  • 16
  • 33

1 Answers1

4

This is a bug i stumbled on in a project I worked on.

Message cannot be used an an entity name ... why? ... Apple ... ???

Don't really know.

Rename to something else and this usually solve the problem.

Dan Shelly
  • 5,991
  • 2
  • 22
  • 26
  • Yeah, According to first suggestion in comments on my question, I did that too. But it sucks. Wasted me 5 hours of time. – Sepehrom Feb 27 '14 at 08:44
  • Just formulated it as an answer so if someone look at this at some point it would be clearer – Dan Shelly Feb 27 '14 at 08:47
  • 2
    It cannot be used as an entity name because some genius at Apple named a class "Message" without using a namespace prefix (such as "UI", "NS", "AB", etc). **Make sure to open a bug report with Apple at https://bugreport.apple.com.** – Léo Natan Feb 27 '14 at 22:20