How to Add AFIncrementalStore to an Existing Project
Add dependencies without Cocoapods
- Add Core Data
- Add Mobile Core Services
- Add System Configuration
- Add AFIncrementalStore
- Add AFNetworking
- Add InflectorKit
Add to Prefix
#import <CoreData/CoreData.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import <MobileCoreServices/MobileCoreServices.h>
Add Code to AppDelegate.h
#import "TESTAPPIncrementalStore.h"
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext;
Add to AppDelegate.m
#import "AFNetworkActivityIndicatorManager.h"
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
#pragma mark - Core Data
- (void)saveContext {
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
- (NSManagedObjectContext *)managedObjectContext {
if (_managedObjectContext) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator) {
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel {
if (_managedObjectModel) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"TESTAPP" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (_persistentStoreCoordinator) {
return _persistentStoreCoordinator;
}
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
AFIncrementalStore *incrementalStore = (AFIncrementalStore *)[_persistentStoreCoordinator addPersistentStoreWithType:[TESTAPPIncrementalStore type] configuration:nil URL:nil options:nil error:nil];
NSURL *applicationDocumentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *storeURL = [applicationDocumentsDirectory URLByAppendingPathComponent:@"TESTAPP.sqlite"];
NSDictionary *options = @{
NSInferMappingModelAutomaticallyOption : @(YES),
NSMigratePersistentStoresAutomaticallyOption: @(YES)
};
NSError *error = nil;
if (![incrementalStore.backingPersistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
Add to applicationDidFinishLaunching
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:8 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
Add to applicaitonWillTerminatie
[self saveContext];
Create APIClient.h
#import "AFIncrementalStore.h"
#import "AFRestClient.h"
@interface TESTAPPAPIClient : AFRESTClient <AFIncrementalStoreHTTPClient>
+ (TESTAPPAPIClient *)sharedClient;
@end
Create TESTAPPAPIClient.m
#import "TESTAPPAPIClient.h"
#import "AFJSONRequestOperation.h"
static NSString * const kTESTAPPAPIBaseURLString = @"<# API Base URL #>";
@implementation TESTAPPAPIClient
+ (TESTAPPAPIClient *)sharedClient {
static TESTAPPAPIClient *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[self alloc] initWithBaseURL:[NSURL URLWithString:kTESTAPPAPIBaseURLString]];
});
return _sharedClient;
}
- (id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (!self) {
return nil;
}
[self registerHTTPOperationClass:[AFJSONRequestOperation class]];
[self setDefaultHeader:@"Accept" value:@"application/json"];
return self;
}
#pragma mark - AFIncrementalStore
- (id)representationOrArrayOfRepresentationsFromResponseObject:(id)responseObject {
return responseObject;
}
- (NSDictionary *)attributesForRepresentation:(NSDictionary *)representation
ofEntity:(NSEntityDescription *)entity
fromResponse:(NSHTTPURLResponse *)response
{
NSMutableDictionary *mutablePropertyValues = [[super attributesForRepresentation:representation ofEntity:entity fromResponse:response] mutableCopy];
// Customize the response object to fit the expected attribute keys and values
return mutablePropertyValues;
}
- (BOOL)shouldFetchRemoteAttributeValuesForObjectWithID:(NSManagedObjectID *)objectID
inManagedObjectContext:(NSManagedObjectContext *)context
{
return NO;
}
- (BOOL)shouldFetchRemoteValuesForRelationship:(NSRelationshipDescription *)relationship
forObjectWithID:(NSManagedObjectID *)objectID
inManagedObjectContext:(NSManagedObjectContext *)context
{
return NO;
}
@end
Create TESTAPPIncrementalStore.h
#import "AFIncrementalStore.h"
@interface TESTAPPIncrementalStore : AFIncrementalStore
@end
Create TESTAPPIncrementalStore.m
#import "TESTAPPIncrementalStore.h"
#import "TESTAPPAPIClient.h"
@implementation TESTAPPIncrementalStore
+ (void)initialize {
[NSPersistentStoreCoordinator registerStoreClass:self forStoreType:[self type]];
}
+ (NSString *)type {
return NSStringFromClass(self);
}
+ (NSManagedObjectModel *)model {
return [[NSManagedObjectModel alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"TESTAPP" withExtension:@"xcdatamodeld"]];
}
- (id <AFIncrementalStoreHTTPClient>)HTTPClient {
return [TESTAPPAPIClient sharedClient];
}
@end
Create xcdatamodeld
if you dont' have one
Fill in BaseURL in APIClient
REPLACE TESTAPP with your APPNAME
Replace in App Delegate with xcDataModeld Filename
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"DataModel" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSURL *applicationDocumentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *storeURL = [applicationDocumentsDirectory URLByAppendingPathComponent:@"DataModel.sqlite"];
Tips
- Pretend you just have a Core Data Datasebase. The syncing and requests will take care of themselves.
- On launch, do a fetch to get everything from the server send to the client.
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Family" inManagedObjectContext:self.managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
NSError *error = nil;
NSArray *array = [self.managedObjectContext executeFetchRequest:request error:&error];
NSLog(@"RESULTS %@",array.description);
- Creating a New Object will send a POST