ALCoreDataManager 0.2.3

ALCoreDataManager 0.2.3

TestsTested
LangLanguage Obj-CObjective C
License MIT
ReleasedLast Release Sep 2015

Maintained by Aziz U. Latypov.



  • By
  • Aziz U. Latypov

Usage

Import the header

#import <ALCoreDataManager/ALCoreData.h>

For saving the context on app termite add this code to your AppDelegate

- (void)applicationWillTerminate:(UIApplication *)application
{
    [[ALCoreDataManager defaultManager] saveContext];
}

To get the NSManagedObjectContext use

[ALCoreDataManager defaultManager].managedObjectContext

Create Objects

You can use simple create method to create managed object:

Product *a = [Product create];
Product *b = [Product createWithDictionary:@{ @"title" : @"best product" }];

// or using Factory class
NSManagedObjectContext *context = [ALCoreDataManager defaultManager].managedObjectContext;
ALManagedObjectFactory *factory =
[[ALManagedObjectFactory alloc] initWithManagedObjectContext:context];

Product *c = [Product createWithDictionary:nil 
                              usingFactory:factory];
c.title = @"best product 2";

Product *d = [Product createWithDictionary:@{ @"title" : @"best product 3", @"price" : @(100) } 
                              usingFactory:factory];

[d remove]; // remove an object

Query Builder

NSArray *allProducts = 
[[Product all] execute];

NSArray *productsFilteredWithPredicate = 
[[[Product all] where:predicate] execute];

NSArray *singleProduct = 
[[[[Product all] where:predicate] limit:1] execute];

NSArray *onlyDistinctProductTitles = 
[[[[Product all] properties:@[@"title"]] distinct] execute];

NSArray *countProducts =
[[[[Product all] where:predicate] count] execute];

NSArray *orderedItems = 
[[[Product all
] orderedBy:@[
              @[@"title", kOrderDESC],
              @[@"price", kOrderASC],
              @[@"amount"]]
] execute];

NSArray *aggregatedItems = 
[[[[[Product all
] aggregatedBy:@[
                 @[kAggregateSum, @"amount"],
                 @[kAggregateMedian, @"price"]]
] groupedBy:@[@"country"]
] having:predicate
] execute];

For orderedBy: you may omit the ordering ASC/DESC - default oreder is ASC.

Available aggreagations are:

  • kAggregateSum
  • kAggregateCount
  • kAggregateMin
  • kAggregateMax
  • kAggregateAverage
  • kAggregateMedian

You can also get request:

NSFetchRequest *request = [[[Product all] orderedBy:@[@"title", @"price"]] request];
NSManagedObjectContext *context = [ALCoreDataManager defaultManager].managedObjectContext;
NSFetchedResultsController *controller =
[[NSFetchedResultsController alloc] initWithFetchRequest:request
                                    managedObjectContext:context
                                      sectionNameKeyPath:nil
                                               cacheName:nil];
[controller performFetch:nil];

Concurrency

[[ALCoreDataManager defaultManager] saveAfterPerformingBlock:^(NSManagedObjectContext *localContext)
{
  NSArray *remoteUpdates = ...;

  ALManagedObjectFactory *factory = [[ALManagedObjectFactory alloc] initWithManagedObjectContext:localContext];

  for(NSDictionary *d in remoteUpdates){
    [Item createWithDictionary:d 
                  usingFactory:factory];
  }

} withCompletionHandler:^{
  [[NSNotificationCenter defaultCenter] postNotificationName:@"FetchingUpdatesDone" 
                                                      object:nil];
}];

This will automaticaly save changed into localContext and merge it with the defaultContext and emit the notification when done.

Limitations

As per the documentation:

  • (void)setIncludesPendingChanges:(BOOL)yesNo

A value of YES is not supported in conjunction with the result type NSDictionaryResultType, including calculation of aggregate results (such as max and min). For dictionaries, the array returned from the fetch reflects the current state in the persistent store, and does not take into account any pending changes, insertions, or deletions in the context. If you need to take pending changes into account for some simple aggregations like max and min, you can instead use a normal fetch request, sorted on the attribute you want, with a fetch limit of 1.

So using aggregatedBy/groupedBy/having will ignore data, which was not saved.

Requirements

You must overide method +entityName if your entitie's name differs from its class name

@implementation Item

+ (NSString*)entityName
{
    return @"AnItem";
}

@end

Installation

Author

Aziz U. Latypov, [email protected]

License

ALCoreDataManager is available under the MIT license. See the LICENSE file for more info.