magicalpanda / MagicalRecord

Super Awesome Easy Fetching for Core Data!
Other
10.8k stars 1.79k forks source link

NSPersistentDocument and UIManagedDocument support #151

Open tonyarnold opened 12 years ago

tonyarnold commented 12 years ago

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 commented 12 years ago

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 commented 12 years ago

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 :)

svallory commented 11 years ago

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

colasbd commented 11 years ago

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

casademora commented 11 years ago

MagicalRecord is a collection of helper functions and methods to make using Core Data simpler. If you can use Core Data in NSPersistentDocument, you should be able to use MagicalRecord there.

Saul Mora @casademora saul@casademora.com

On Wednesday, May 1, 2013 at 8:54 AM, colasjojo wrote:

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

— Reply to this email directly or view it on GitHub (https://github.com/magicalpanda/MagicalRecord/issues/151#issuecomment-17285311).

colasbd commented 11 years ago

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

Thanks ;)

svallory commented 11 years ago

Hello? Anyone....

casademora commented 11 years ago

Try

[NSManagedObjectContext MR_setDefaultContext:]

Now, this will make that document's context the default context, and thus, if this context not on the main thread, this may not be a good thing. If you just want all the helper methods to work (and aren't worried about the stack management) then you can use use them on NSManagedObjects at will, but you must then always specify the context using the inContext: parameter that is available on all request, find and fetch helper methods.

Hope this helps, Saul

Saul Mora @casademora saul@casademora.com

On Friday, May 3, 2013 at 7:10 AM, Saulo Vallory wrote:

Hello? Anyone....

— Reply to this email directly or view it on GitHub (https://github.com/magicalpanda/MagicalRecord/issues/151#issuecomment-17393127).

colasbd commented 11 years ago

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 commented 11 years ago

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 commented 11 years ago

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 commented 11 years ago
   [NSManagedObjectContext MR_setDefaultContext:<nspersistentdocument context>] 

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

casademora commented 11 years ago

Then you can still us the finder methods with any object. Just specify the context to which they apply with the inContext: parameter. You don't have to use the core data stack setup if you already have a stack...

Saul Mora saul@casademora.com (mailto:saul@casademora.com) http://about.me/saulmora

On Friday, May 3, 2013 at 10:27 AM, colasjojo wrote:

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

— Reply to this email directly or view it on GitHub (https://github.com/magicalpanda/MagicalRecord/issues/151#issuecomment-17404009).

colasbd commented 11 years ago

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 commented 11 years ago

Possibly the MagicalRecord class hasn't loaded. It is on the +initialize call the the runtime method swizzling happens.

Saul Mora @casademora saul@casademora.com

On Friday, May 3, 2013 at 12:29 PM, colasjojo wrote:

That would be great indeed. Do you have a guess why the following does not work ? [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

— Reply to this email directly or view it on GitHub (https://github.com/magicalpanda/MagicalRecord/issues/151#issuecomment-17410488).

colasbd commented 11 years ago

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 commented 11 years ago

uh…you don't want to call +initialize directly…that's an Objective C API type method… maybe call [MagicalRecord class] to load the class...

Saul Mora @casademora saul@casademora.com

On Friday, May 3, 2013 at 12:44 PM, colasjojo wrote:

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 !

— Reply to this email directly or view it on GitHub (https://github.com/magicalpanda/MagicalRecord/issues/151#issuecomment-17411318).

colasbd commented 11 years ago

OK, I didn't know !

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

colasbd commented 11 years ago

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

casademora commented 11 years ago

Cleanup is meant to tear down the stack and release any background queues, operations and stray objects once you are done with core data. Only use this method when you're done with things.

Saul Mora @casademora saul@casademora.com

On Friday, May 3, 2013 at 12:56 PM, colasjojo wrote:

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

— Reply to this email directly or view it on GitHub (https://github.com/magicalpanda/MagicalRecord/issues/151#issuecomment-17411970).

svallory commented 11 years ago

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 commented 11 years ago

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 commented 10 years ago

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

casademora commented 10 years ago

Sure. Send it on over.

colasbd commented 10 years ago

@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 commented 10 years ago

If you have some document support for both mac and iOS, they’d be great additions to MagicalRecord. I don’t use them myself at this time, so I don’t have quite enough experience to evaluate your code. @tonyarnold does, but he’s got quite a lot of things going too. The bottom line is, it’d be great to see what you’ve got, and we’ll carve out some time to review it.

colasbd commented 10 years ago

@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 commented 10 years ago

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 commented 10 years ago

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 commented 10 years ago

@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 commented 10 years ago

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 commented 10 years ago

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 commented 10 years ago

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!

colman01 commented 8 years ago

Hi,

I'm attempting to get a project which uses MR going in XCode 7.
I'm often running into the following errors: No visible @interface for 'CustomObject' declares the selector 'deleteEntity' and No known class method for selector 'createInContext:' No known class method for selector $SHORTHAND_METHODS

I've tried calling: [MagicalRecord class]; to no avail...

what else may be possible?

Cheers, Colman