commit | 74217fa873c72cc398db603d92549e13397055be | [log] [tgz] |
---|---|---|
author | Igor Sarkisov <isarkisov@google.com> | Thu Oct 01 12:45:05 2020 -0700 |
committer | Igor Sarkisov <isarkisov@google.com> | Thu Oct 01 12:45:05 2020 -0700 |
tree | d035e9b94223db000bd416de824f20ed99c50460 |
Project import
Broker maps remote resources to local Core Data resources via JSON responses. Using a few simple design standards, you can automatically map JSON attributes to NSManagedObject
attributes with little effort.
All this fun stuff is done with a few rules.
NSManagedObject
Employee attribute “first_name”. If you want, Broker has the flexibility to map remote names to local ones, but why add the extra code?Broker follows standard patterns for iOS static library design.
Broker.xcodeproj
file to your project.Broker
as a target dependency in your targets Build Phase
tab.libBroker.a
to your targets Link Binary With Libraries
build phase.Now you should be able to import Broker headers following this pattern.
#import <Broker/Broker.h>
Create and configure a new BKController. This should be a long lived object, perhaps stored on your App Delegate or an otherwise appropriate location.
BKController *controller = [BKController controller];
Register your NSManagedObject
with the controller in your main Core Data context. What this does is temporarily creates an Employee
object in your context, traverses all it's properties and relationships, and builds an internal description of what makes an Employee
object based on NSEntityDescription
and NSAttributeDescription
. These descriptions are used to transform JSON into the registered entity. This example assumes you have an Emoloyee
object in your Core Data model with at least an employeeId
attribute.
[controller.entityMap registerEntityNamed:@"Employee" withPrimaryKey:@"employeeId" andMapNetworkProperties:@"id" toLocalProperties:@"employeeId" inContext:context];
Note that we are mapping a network property, id
, to a local property, employeeId
. Sometimes your API may use different attribute names than what you have in your Core Data. Broker allows you to map between the two.
Now you are ready to process some JSON. By passing in the main NSManagedObjectContext
into the BKController
, you are spinning up a child context in which all the work will be done. After the work is done, the context pushes it's changes to the main context. From there, you can choose to either save or not, but this example includes a proper save pattern.
- (void)processEmployeeJSON:(id)json withController:(BKController *)controller inContext:(NSManagedObjectContext *)context { __weak NSManagedObjectContext *weakContext = context; [controller processJSONObject:json asEntityNamed:@"Employee" inContext:context completionBlock:^{ [weakContext performBlock:^{ [context save:nil]; }]; }]; }
Broker is built to handle specific styles of JSON responses.
Broker can process a list of similar things. For example, a JSON response containing a list of Employee objects.
[ { "name": "Andrew", "department": "Engineering", "employeeId": 1 }, { "name": "Sarah", "department": "Engineering", "employeeId": 2 }, { "name": "Steve", "department": "Marketing", "employeeId": 3 } ]
Broker cannot process a mixed list of things, like Employee's and Departments.
[ { "name": "Andrew", "department": "Engineering", "employeeId": 1 }, { "name": "Engineering", "departmentId": 2 }, ]
Instead, you should return similar objects it as nested lists, which you can process separately.
[ { "employees": [ { "name": "Andrew", "department": "Engineering", "employeeId": 1 } ] }, { "departments": [ { "name": "Engineering", "departmentId": 2 } ] } ]
Broker can process a single thing. For example, a single Employee.
{ "name": "Andrew", "department": "Engineering", "employeeId": 1 }
Broker can process a nested thing. For example, an Employee with a Department.
{ "name": "Andrew", "employeeId": 1, "department": { "name": "Engineering", "departmentId": 1 } }
Broker can process a nested list of things on a thing. For example, a Department with a list of Employees.
{ "name": "Engineering", "departmentId": 1, "employees": [ { "name": "Andrew", "departmentId": 1 }, { "name": "Sarah", "employeeId": 2 } ] }
Broker uses a “primary key” convention to enforce object uniqueness. NSManagedObjects must have a primary key to be registered with Broker. For example, an Employee could have a unique employeeId
attribute. Once we have a primary key, we can use a simple find or create pattern to guarantee uniqueness. Without specifying a primary key, you could end up with duplicate objects.
DISCLAIMER: If you are working with JSON where you might have more than a few thousand entities at once, the find-or-create pattern in it‘s current form will be slow. I’m working on a faster pattern.