NSPersistentDocument and UIManagedDocument support #151

Open
tonyarnold opened this Issue Mar 13, 2012 · 33 comments

5 participants

@tonyarnold

I realise this is a large, sometime in the future request. It would be great to extract out the appropriate MagicalRecord features so that they could extend and simplify the function of working with NSManagedObjects inside NSPersistentDocument and UIManagedDocument.

@casademora
Magical Panda Software member

I don't have any experience working with those APIs at the moment. I'd love to get your ideas on how that could be accomplished.

@tonyarnold

Absolutely. I'll try to put some ideas down this weekend, otherwise I'll actually knuckle down after my next round of surgery when I have lots of time to spare. Thanks :)

@blackgold9 blackgold9 closed this Oct 9, 2012
@blackgold9 blackgold9 reopened this Oct 15, 2012
@tonyarnold tonyarnold was assigned Jan 11, 2013
@svallory

Hey guys, can you please give me a little guidance on how to do this manually?

@colasbd

Is it possible to use MagicalRecord in an document-based osx application ?
That is : is it possible to use MR within a NSPersistentDocument ?

@casademora
Magical Panda Software member
@colasbd

An NSPersistentDocument automatically creates a MOC at the init.
How can I tell MR to work with this MOC ?

Thanks ;)

@svallory

Hello? Anyone....

@casademora
Magical Panda Software member
@colasbd

Hi casademora and thanks for your reply :)

Indeed, I am only interested in the helper methods.

I tried, without any setting-up (the setting-up of the stack is done automatically by the NSPersistentDocument), the following :

[Exercise numberOfEntitiesWithContext:[self managedObjectContext]];

(Exercise is one of my entities)

I got the error (at the runtime)
+[Exercise numberOfEntitiesWithContext:]: unrecognized selector sent to class 0x10006d3b8

In my pch, I have :
//Magical record
#ifdef OBJC
#define MR_SHORTHAND
#import "CoreData+MagicalRecord.h"
#endif

@colasbd

But, If I do :

[MagicalRecord setupCoreDataStack];
[Exercise numberOfEntitiesWithContext:[self managedObjectContext]];

I dont have any error anymore !
I am just afraid to use [MagicalRecord setupCoreDataStack]; because as I told you, NSPersistentDocument is normally doing this job.

Anyway, thanks again !

@colasbd

The following log

 NSLog(@"Comparisons of the MOC : %@ vs %@ for document %@", [self managedObjectContext], [NSManagedObjectContext defaultContext], self);

gives :

   Comparisons of the MOC : <NSManagedObjectContext: 0x100179e00> vs <NSManagedObjectContext: 0x101bc9e00> for document <Document: 0x100189590>

The two MOCs are different.
I am a beginner so I am not sure, but I would say this proves there is a problem.

Thanks !

@colasbd
   [NSManagedObjectContext MR_setDefaultContext:<nspersistentdocument context>] 

is impossible : "No known class method for selector ' MR_setDefaultContext:' "

@casademora
Magical Panda Software member
@colasbd

That would be great indeed.

Do you have a guess why the following does not work ?


[Entity numberOfEntitiesWithContext:[self managedObjectContext]];
(Entity is one of my entities)

I got the error (at the runtime)
+[Entity numberOfEntitiesWithContext:]: unrecognized selector sent to class 0x10006d3b8

In my pch, I have :
//Magical record
#ifdef OBJC
#define MR_SHORTHAND
#import "CoreData+MagicalRecord.h"
#endif


@casademora
Magical Panda Software member
@colasbd

It works !!
I just add [MagicalRecord initialize] and that's all !

Thank you very much for your help.
I think this will help other people !

@casademora
Magical Panda Software member
@colasbd

OK, I didn't know !

It works with [MagicalRecord class] ;
We would prefer a more direct way to load the class, though ;)

@colasbd

Do you think [MagicalRecord cleanUp] would do any harm ?

@casademora
Magical Panda Software member
@svallory

A working sample wouldn't be hard to do for someone who already knows how to do it and certainly would easy the adoption. I gave up on using MR inside NSPersistentDocument because I had problems saving the document. Do anyone volunteer?

@colasbd

When doing a simple request, I got the following error :
Can only use -performBlockAndWait: on an NSManagedObjectContext that was created with a queue.

The same request "by hand" does not raise a error.

It's a pity one cannot use MR with NSPersistentDocument, which is IMHO, the simpliest case.

@colasbd

@casademora Would you be interested by a minimal example that does not work?

@casademora
Magical Panda Software member
@colasbd

@svallory @casademora OK, I managed to make it work ! I got the idea from there.

In the init method of your subclass of NSPersistentDocument, you should put

- (id)init
{
    [MagicalRecord cleanUp] ;

    self = [super init] ;

    if (self)
    {
        /*
         Thanks
         https://gist.github.com/smic/4632383
         */
        NSManagedObjectContext *Oldcontext = self.managedObjectContext;
        NSUndoManager *undoManager = Oldcontext.undoManager;

        [NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:Oldcontext.persistentStoreCoordinator] ;

        NSManagedObjectContext * newContext = [NSManagedObjectContext rootSavingContext] ;
        newContext.undoManager = undoManager ;

        self.managedObjectContext = newContext ;
    }

    return self ;
}

I think that merely everything is ready for a nice and cool instance method

- (void)MR_initialize

on NSPersistentDocument.

The only small issue remaining is that NSDocument does not like when one call save: on its "rootMOC" (the one connected with the store). It wants instead that one call [self saveDocument:sender]. Indeed, if you modify directly the store without telling the document, you will have an error message "The file has been modified by another application...".

So, (with a flag or something), one should take care of the special case of NSDocument.

For the issue of "The file has been modified by another application...", this discussion is quite interesting.

@casademora What do you think? Shall I fork and do a pull request?

PS: This might give ideas to users of UIPersistentDocument.

EDIT :

More docs : For the issue of "The file has been modified by another application..."

I might write a new subclass of NSDocument, inspired by this great project (fwd : @karelia)

@casademora
Magical Panda Software member
@colasbd

@casademora Thank you for your answer. What's the best way to show you all what I have? Forking, Forking+Request a pull or something else? Thank you for your attention.

@colasbd

I realized that what I want to do is not possible. Indeed, an app with NSDocument will have several CoreData stacks whereas MagicalRecord has only one.. Thanks for MR anyway!

@tonyarnold

MagicalRecord 3.0 better handles *Document support — I've been using it with an OS X app which utilises NSDocument, and when I have some time I'll contribute the basic code for that to MagicalRecord 3.

@colasbd

@tonyarnold is it subclassing NSDocumentˋ? Are you aware of [BSManagedDocument`](https://github.com/karelia/BSManagedDocument/)?

Which class should at look at to begin with?

@tonyarnold

Yes, it's subclassing NSDocument (not NSPersistentDocument, which made too many assumptions) and yes, I looked at BSManagedDocument while I was putting together TCBManagedDocument — it's inspired, but I handle a number of things like versions, autosave, etc that BSManagedDocument does not.

@colasbd

Ok, great to hear that! Is this repo still private? I couldn't find it. I think BSManagedDocument supports autosave, also (with a minor bug, see issues). When do you plan to release it? One week, one month, one year? Is it worth waiting for it or should I wait for it?

@tonyarnold

It was developed as part of a client project. I'll need to seek release of the code — I don't expect this to be a problem, but I can't give you an ETA. I work on MagicalRecord as I have time, and don't get paid for it so it doesn't tend to take priority next to work that pays the bills. Sorry!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment