Giter Club home page Giter Club logo

ssdatakit's Introduction

SSDataKit

There is a lot of boilerplate code required to write a Core Data application. This is annoying. In pretty much everything I've written since Core Data came to iOS, I have used the following class.

What's Included

SSManagedObject

  • Manages main context, persistent store, etc
  • Accessing entity descriptions
  • Reflection
  • Easy creating and deleting

SSRemoteManagedObject

  • Easily find or create objects by a remote ID
  • Unpack NSDictionary's into your Core Data object's attributes

Example

This is very simple example of how to use SSRemoteManagedObject.

Post.m

- (void)unpackDictionary:(NSDictionary *)dictionary {
  [super unpackDictionary:dictionary];
  self.title = dictionary[@"title"];
}

Now you can create and find posts easily.

Post *post = [Post objectWithDictionary:@{@"id": @(1), @"title": @"Hello World"}];
Post *anotherPost = [Post objectWithRemoteID:@(1)];
NSLog(@"Equal: %i", [post isEqual:anotherPost]); // Equal: 1

For a more complete example, see CheddarKit which is used in Cheddar for iOS and Cheddar for Mac.

ssdatakit's People

Contributors

aaronwasserman avatar calebd avatar davidogren avatar devinfoley avatar jstart avatar kvnsmth avatar rastersize avatar rdougan avatar rsmoz avatar soffes avatar stevemoser avatar yimingtang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ssdatakit's Issues

Issue with cocoapods

So here's how to reproduce the bug.

  1. In my podfile, I have ~> 0.3.0.
  2. If I run pod update nothing gets updated. I still have the old code.
  3. Tried deleting the Pod-SSDataKit directory and re-run pod install and pod update
  4. Still gets the same, old version.

I have cocoapods 0.29 BTW. Tried sudo gem install/update cocoapods without any luck.

Should I just do git pull origin master in the pod directory ?

Thanks a lot.

License?

Would you mind adding a license to this wonderful library so that I can make a pod for it?

Thanks for all of your great work!

SSManagedTableViewController Filtering

I know you mention in several spots that your filtering classes are still a WIP. Are you planning on providing filtering support to SSDataKit? Are you planning on creating a new SSManagedFilterableTableViewController or adding filtering support to the existing SSManagedTableViewController?

I'd like to take a shot at implementing that functionality in my fork. Lemme know! Love the project beeteedubs.

doesn't work with OCTests

Hi,
my app works fine with SSDataKit but when I try to run some Unit Tests, I get the exception

An NSManagedObject of class 'XXXX' must have a valid NSEntityDescription.

when instantiating a new managed object. My model definition is included in the test target.

any idea what is wrong?

cheers

__privateQueueContext save causing deadlock

I'm not totally sure of this, but I have big problems with deadlocks (together with NSFetchedResultsController) when saving the privateQueueContext via the NSManagedObjectContextDidSaveNotification block. The only way I have found to solve this problem is to force the performBlock: to be called on the main queue. The save is still executed on another queue but the deadlock seems to be gone.

Am I doing something terribly wrong here or might this solution be good enough for a pull request?

Demo Project

Sam,

I'd love a demo project if possible to demonstrate how to use the classes. That would be awesome.

Why does SSManagedViewController needs mainQueueContext to init?

I ran against this nasty bug in my app.

- (NSFetchedResultsController *)fetchedResultsController always returns nil.

If I removed the [SSManagedObject hasMainQueueContext] check here everything works fine and the mainQueueContext gets created when the fetchRequest gets created.

Any ideas why ? Should I just called [SSManagedObject mainQueueContext] in my app delegate ?

SSDataKit 1.0

I want to make several larger changes to SSDataKit. Here's the list:

  • Rename to DataKit or SAMDataKit
  • Make the primary key (currently remoteID) configurable #20
  • Automatic unpacking by default (can override to customize)
  • Figure out a better nested context solution #11
  • Proper demo #1
  • Full documentation
  • Test SSManagedObject
  • Test SSRemoteManagedObject
  • Test fetched results controller craziness

Changes in privateQueueContext are not automatically propagated to mainQueueContext

I'm using SSDataKit along with AFIncrementalStore and discover interesting behavior.

Seems like when NSFetchedResultController performing fetch, implicitly uses topmost PSC of parent/child MOC chain. I swizzle -executeRequest:withContext:error: method of NSPersistentStoreCoordinator, and it is called with privateQueueContext as context parameter, while NSFetchedResultController is initialized with mainQueueContext.

AFIncrementalStore can intercept fetch requests and change context before (or after in async manner) returning any results back to caller. In my case NSIncrementalStore method -executeRequest:withContext:error: is also called with privateQueueContext as parameter. Then AFIncrementalStore getting data from remote server and update privateQueueContext asynchronously. But this changes never automatically pulled by mainQueueContext.

Now I just override -mainQueueContext method to not use private moc as parent, but looking for more appropriate solution to pull changes back to main moc in case of async update in private moc.

Crash in managed table and collection view controllers

I have a collection view with a section that appears before all content fed by the fetched results controller.

I overrode viewIndexPathForFetchedIndexPath: and viewIndexPathForFetchedIndexPath: to return adjusted index paths, but neither of those methods are called in controllerDidChangeContent:. This results in invalid index paths being updated if the call was triggered by controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:.

Additionally, both collection and table view controllers will update invalid index paths for changes triggered by controller:didChangeSection:atIndex:forChangeType: since the value for sectionIndex is not normalized by running it through viewIndexPathForFetchedIndexPath:. This affects all collection view controllers, and only table view controllers that return YES from useChangeAnimations.

[NSManagedObject shouldUnpackDictionary:]: unrecognized selector sent to instance

I'm experiencing a crash in my app whenever I hit
https://github.com/soffes/ssdatakit/blob/master/SSDataKit/SSRemoteManagedObject.m#L104

When I set a breakpoint on line 104 ( if ([object shouldUnpackDictionary:dictionary]) {)
the application crashes ( log below ).

object is an instance of the class I would expect it to be.
That class is a subclass of an APIClass, which inherits from SSRemoteManagedObject.
I am surprised by the problem because when I log [self class] during execution,
I see the class I'm expecting. But the crash mentions [NSManagedObject shouldUnpackDictionary:]. I understand my class is a sub-sub-sub-class of
NSManagedObject, but it should try to send the message at least to SSRemoteManagedObject.

I would appreciate it if someone could give me a tip on how to debug this bug,
which is probably in my implementation, not a bug in SSDatakit.

+ (id)objectWithDictionary:(NSDictionary *)dictionary context:(NSManagedObjectContext *)context {

    // Make sure we have a dictionary
    if (![dictionary isKindOfClass:[NSDictionary class]]) {
        return nil;
    }

    // Extract the remoteID from the dictionary
    NSNumber *remoteID = @([[dictionary objectForKey:@"id"] integerValue]);

    // Find object by remoteID
    SSRemoteManagedObject *object = [[self class] objectWithRemoteID:remoteID context:context];

    // Only unpack if necessary
    if ([object shouldUnpackDictionary:dictionary]) {
        [object unpackDictionary:dictionary];
    }

    // Return the new or updated object
    return object;
}

Output:

-[NSManagedObject shouldUnpackDictionary:]: unrecognized selector sent to instance 0x986dec0
2013-06-26 11:42:54.076 Plinx Client[18275:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSManagedObject shouldUnpackDictionary:]: unrecognized selector sent to instance 0x986dec0'
*** First throw call stack:
(0x25ae012 0x20a3e7e 0x26394bd 0x259dbbc 0x259d94e 0x189ffa 0x189e2a 0x3250 0x25a7e7c 0x25a7a16 0x25a7925 0x318c 0x8b598f 0x8b58ae 0x3078 0xcd9fa 0x8f728 0xccd4c 0xbd4dd 0xcccaf 0x926b3 0x5830 0x41839 0x232353f 0x2335014 0x23257d5 0x2554af5 0x2553f44 0x2553e1b 0x2ac17e3 0x2ac1668 0x15efffc 0x2b5d 0x2315)
libc++abi.dylib: terminate called throwing an exception

WAL and SHM files not cleaned up during reset

While running unit tests on my SSDataKit enabled project I was hitting some SQLite 522 'not an error' errors. Those unit tests were on iOS7 (which has WAL enabled by default) and the tests frequently run SSManagedObject +resetPersistentStore during setup.

Some Googling and StackExchange searching led me to a theory that this might be caused by WAL mode, and particularly by the inconsistent state caused by having a new sqlite database file created, but still having an old WAL journal. As part of exploring that theory, I modified SSDataKit to clean up those -shm -wal files used by WAL when SSDataKit resets the persistent store or is cleaning up after a failed lightweight migration.

That theory didn't pan out, but I wanted to offer those changes back to you regardless. (I'll send a pull request right after I submit this issue.) Feel free to reject the request if you know that SQLite will always do the right thing with just the sqlite file removed. (Which, in theory, it should be able to do.)

Migration failure not caught by automaticallyResetsPersistentStore

I'm in early dev and not worrying about migration, what I think would be a perfect use case for the automaticallyResetsPersistentStore option. I changed some attributes to not be optional anymore (which would obviously cause problems with migration) and ran my app, expecting my automaticallyResetsPersisentStore to catch the failure and rebuild my database from scratch. It didn't, instead just failing to create the persistent store.

I ran it through the debugger and see that SSDataKit specifically checks for error 134130 in order to reset the specific store, and my particular migration failure was raising 134140. I fixed this problem by modifying the relevant part of +(NSPersistentStoreCoordinator *)persistentStoreCoordinator to:

        if (error) {
            // Reset the persistent store
            BOOL fixableError = (error.code == 134130 || error.code == 134140);
            if (__automaticallyResetsPersistentStore && fixableError) {
                [[NSFileManager defaultManager] removeItemAtURL:url error:nil];
                [persistentStoreCoordinator addPersistentStoreWithType:[self persistentStoreType] configuration:nil URL:url options:storeOptions error:&error];
            } else {
                NSLog(@"[SSDataKit] Failed to add persistent store: %@ %@", error, error.userInfo);
            }
        }

If you agree, and would prefer a pull request or patch, let me know.

UIKit on cocoa apps

I can't make it work in my cocoa app because UIKit library, errors located at: SSFilteredResultsFilter.m and SSFilterableFetchedResultsController.h

How should I handle this?

.../SSDataKit/SSFilterableFetchedResultsController.h:10:9: fatal error: 'UIKit/UIKit.h' file not found
#import <UIKit/UIKit.h>
        ^
1 error generated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.