iOS - Core Data model Conflict With Mail Framework?
-
03-07-2021 - |
Question
I have a Core Data object, Account
, represented as a subclass of NSManagedObject
:
@interface Account : NSManagedObject
My entire app has been developing just fine, however, when I add the MessageUI.framework
so I can get a compose email view controller, all hell breaks loose. The app links and compiles fine, and runs just fine. Until, that is, I start interfacing with my previously working Account
objects. Then, I start getting these:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: '"Account" is not a subclass of NSManagedObject.'
*** First throw call stack:
(0x202b012 ... 0x2385)
libc++abi.dylib: terminate called throwing an exception
This particular one of which was caused by:
// we need to insert a new account
Account *newAccount = [NSEntityDescription
insertNewObjectForEntityForName:[Account entityName]
inManagedObjectContext:self.managedObjectContext];
Now, I'm guessing that there is some class in the MessageUI.framework
causing the conflict, but I have a few questions:
- The app compiles and runs just fine, no compile-time name conflicts
- The other components in the framework seem to be prefix-namespaced (ie:
MFMailComposeViewController
), so should the theoretical account not beMFAccount
? - I'm not even doing an
#import <MessageUI/MessageUI.h>
or the slightly tighter#import <MessageUI/MFMailComposeViewController.h>
, the latter of which I inspected and saw no definition ofAccount
, so I'm not sure why the possible conflicts would even be loaded. - Just to be certain, I re-generated my Core Data classes, and reset all simulator settings, still no dice.
- Removing the Framework from the project and build settings immediately fixes the issue.
Solution
I've had this happen to me, with this is exact framework (the class was called Broadcaster
). In this case, the private Message
framework is linked by MessageUI
, and this framework provides the Account
implementation.
You can verify that the MessageUI framework loads an Account
class by making a new project, and in the app delegate's application:didFinishLaunchingWithOptions:
method, add the following code:
NSString *account = @"Account";
Class accountClass = NSClassFromString(account);
NSLog(@"accountClass = %@",accountClass);
On a fresh project this will print accountClass = (null)
but after adding MessageUI it will print accountClass = Account
.
Furthermore, if you use class-dump
on the private Message
framework, you'll see the interface declaration for Account
.
Now, you list 5 items in your post as questions, I'll try to address them
- I don't know enough about the link-time process for working with
Frameworks to say for sure, but I suspect the
Message
framework is weakly linked and thus won't cause a duplicate symbol error at link time. - The public facing ones are named correctly but some undocumented
ones aren't. Also, the conflicting class is in the private
Message
framework. - That doesn't matter at all. The compiler will use
#import
, but at run time, all the classes are loaded with your application and there is no "visibility" or anything like that enforced in the runtime. - N/A
- Consistent with other evidence
As far as a course of action, I just renamed my model class to have a prefix. I'm not aware of any other solution.
OTHER TIPS
It's possible that the message framework is not the problem at all. Stuff like this can happen unexpectedly with core data, such as when you change the model somehow. Try cleaning the build, deleting your simulator / hardware installed test apps, and running again. The reason geraldWilliam suggested renaming it, I think, is to fix this problem, but it might not be necessary to rename anything
Check out this thread: Could not locate NSManagedObjectModel for Entity