MMRecord
Seamless Web Service Integration and Core Data Model Population
Install / Use
/learn @mutualmobile/MMRecordREADME
MMRecord is a block-based seamless web service integration library for iOS and Mac OS X. It leverages the Core Data model configuration to automatically create and populate a complete object graph from an API response. It works with any networking library, is simple to setup, and includes many popular features that make working with web services even easier. Here's how to make a request for App.net Post records:
NSManagedObjectContext *context = [[MMDataManager sharedDataManager] managedObjectContext];
[Post
startPagedRequestWithURN:@"stream/0/posts/stream/global"
data:nil
context:context
domain:self
resultBlock:^(NSArray *posts, ADNPageManager *pageManager, BOOL *requestNextPage) {
NSLog(@"Posts: %@", posts);
}
failureBlock:^(NSError *error) {
NSLog(@"%@", error);
}];
Keep reading to learn more about how to start using MMRecord in your project!
Getting Started
- Download MMRecord and try out the included example apps.
- Continue reading the integration instructions below.
- Check out the documentation for all the rest of the details.
- Review the examples below for inspiration on specific usage.
- Read about MMRecord's support for Swift and Tweaks.
- If you run into any issues, check out some useful debugging tips.
##Installing MMRecord <img src="https://cocoapod-badges.herokuapp.com/v/MMRecord/badge.png"/><br/> You can install MMRecord in your project by using CocoaPods:
pod 'MMRecord', '~> 1.4.1'
Overview
MMRecord is designed to make it as easy and fast as possible to obtain native objects from a new web service request. It handles all of the fetching, creation, and population of NSManagedObjects for you in the background so that when you make a request, all you get back is the native objects that you can use immediately. No parsing required.
The library is architected to be as simple and lightweight as possible. Here's a breakdown of the core classes in MMRecord.
<table> <tr><th colspan="2" style="text-align:center;">Core</th></tr> <tr> <td><a href="http://mutualmobile.github.com/MMRecord/Documentation/Classes/MMRecord.html">MMRecord</a></td> <td> A subclass of <tt>NSManagedObject</tt> that defines the <tt>MMRecord</tt> interface and initiates the object graph population process. <ul>
<li>Entry point for making requests</li>
<li>Uses a registered <tt>MMServer</tt> class for making requests</li>
<li>Initiaties the population process using the <tt>MMRecordResponse</tt> class</li>
<li>Returns objects via a block based interface</li>
</ul>
</td>
</tr>
<tr>
<td><a href="http://mutualmobile.github.com/MMRecord/Documentation/Classes/MMServer.html">MMServer</a></td>
<td>
An abstract class that defines the request interface used by <tt>MMRecord</tt>.
<ul>
<li>Designed to be subclassed</li>
<li>Supports any networking framework, including local files and servers</li>
</ul>
</td>
</tr>
</table>
<p align="center">
<img src="https://www.github.com/mutualmobile/MMRecord/raw/gh-pages/Images/MMRecord-architecture-diagram.png") alt="MMRecord Architecture Diagram"/>
</p>
<table>
<tr><th colspan="2" style="text-align:center;">Population</th></tr>
<tr>
<td><a href="http://mutualmobile.github.com/MMRecord/Documentation/Classes/MMRecordResponse.html">MMRecordResponse</a></td>
<td>A class that handles the process of turning a response into native <tt>MMRecord</tt> objects.</td>
</tr>
<tr>
<td><a href="http://mutualmobile.github.com/MMRecord/Documentation/Classes/MMRecordProtoRecord.html">MMRecordProtoRecord</a></td>
<td>A container class used as a placeholder for the object graph during the population process.</td>
</tr>
<tr>
<td><a href="http://mutualmobile.github.com/MMRecord/Documentation/Classes/MMRecordRepresentation.html">MMRecordRepresentation</a></td>
<td>A class that defines the mapping between a dictionary and a Core Data <tt>NSEntityDescription</tt>.</td>
</tr>
<tr>
<td><a href="http://mutualmobile.github.com/MMRecord/Documentation/Classes/MMRecordMarshaler.html">MMRecordMarshaler</a></td>
<td>A class responsible for populating an instance of <tt>MMRecord</tt> based on the <tt>MMRecordRepresentation</tt>.</td>
</tr>
<tr><th colspan="2" style="text-align:center;">Pagination</th></tr>
<tr>
<td><a href="http://mutualmobile.github.com/MMRecord/Documentation/Classes/MMServerPageManager.html">MMServerPageManager</a></td>
<td>An abstract class that defines the interface for handling pagination.</td>
</tr>
<tr><th colspan="2" style="text-align:center;">Caching</th></tr>
<tr>
<td><a href="http://mutualmobile.github.com/MMRecord/Documentation/Classes/MMRecordCache.html">MMRecordCache</a></td>
<td>A class that maps <tt>NSManagedObject</tt> ObjectIDs to an <tt>NSCachedURLResponse</tt>.</td>
</tr>
<tr><th colspan="2" style="text-align:center;">Debugging</th></tr>
<tr>
<td><a href="http://mutualmobile.github.com/MMRecord/Documentation/Classes/MMRecordDebugger.html">MMRecordDebugger</a></td>
<td>A class that manages <tt>NSError</tt> objects to provide debugging feedback.</td>
</tr>
</table>
<p align="center">
<img src="https://www.github.com/mutualmobile/MMRecord/raw/gh-pages/Images/MMRecord-parsing.png") alt="MMRecord Population Architecture"/>
</p>
<table>
<tr><th colspan="2" style="text-align:center;">Subspecs</th></tr>
<tr>
<td><a href="https://github.com/mutualmobile/MMRecord/tree/master/Source/MMRecordAFServer">AFServer</a></td>
<td>An example <tt>MMServer</tt> subclass that implements <tt>AFNetworking</tt> 1.0.</td>
</tr>
<tr>
<td><a href="https://github.com/mutualmobile/MMRecord/tree/master/Source/AFMMRecordSessionManagerServer">SessionManagerServer</a></td>
<td>An example <tt>MMServer</tt> subclass that implements <tt>AFNetworking</tt> 2.0.</td>
</tr>
<tr>
<td><a href="https://github.com/mutualmobile/MMRecord/tree/master/Source/MMRecordJSONServer">JSONServer</a></td>
<td>An example <tt>MMServer</tt> subclass that can read local JSON files.</td>
</tr>
<tr>
<td><a href="https://github.com/mutualmobile/MMRecord/tree/master/Source/MMRecordDynamicModel">DynamicModel</a></td>
<td>A custom <tt>MMRecordRepresentation</tt> and <tt>MMRecordMarshaler</tt> subclass pair that stores the original object dictionary as a transformable attribute.</td>
</tr>
<tr>
<td><a href="https://github.com/mutualmobile/MMRecord/tree/master/Source/AFMMRecordResponseSerializer">ResponseSerializer</a></td>
<td>A custom <tt>AFHTTPResponseSerializer</tt> that creates and returns <tt>MMRecord</tt> instances in an <tt>AFNetworking</tt> 2.0 success block.</td>
</tr>
<tr>
<td><a href="https://github.com/mutualmobile/MMRecord/tree/master/Source/FBMMRecordTweakModel">TweakModel</a></td>
<td>An <tt>MMRecord</tt> subspec that implements support for Facebook Tweaks to tweak <tt>MMRecord</tt> response handling behavior.</td>
</tr>
</table>
Integration Guide
MMRecord does require some basic setup before you can use it to make requests. This guide will go take you through the steps in that configuration process.
Server Class Configuration
MMRecord requires a registered server class to make requests. The server class should know how to make a request to the API you are integrating with. The only requirement of a server implementation is that it return a response object (array or dictionary) that contains the objects you are requesting. A server might use AFNetworking to perform a GET request to a specific API. Or it might load and return local JSON files. There are two subspecs which provide pre-built servers that use AFNetworking and local JSON files. Generally speaking though, you are encouraged to implement your own server to talk to the API you are using.
Once you have defined your server class, you must register it with MMRecord:
[Post registerServerClass:[ADNServer class]];
Note that you can register different server classes on different subclasses of MMRecord.
[Tweet registerServerClass:[TWSocialServer class]];
[User registerServerClass:[MMJSONServer class]];
This is helpful if one endpoint you are working with is complete, but another is not, or is located on another API.
AFNetworking
While you are encouraged to create your own specific server subclass for your own integration, MMRecord does provide base server implementations as subspec examples for AFNetworking 1.0 and AFNetworking 2.0. You can consult the AFServer subspec for AFNetworking 1.0, or the AFMMRecordSessionManagerServer subspec for AFNetworking 2.0. You can check out the new AFNetworking 2.0 server in the Foursquare example app.
In addition, we provide the AFMMRecordResponseSerializer subspec specially for AFNetworking 2.0. This response serializer can be used for AFNetworking 2.0 in order to provide parsed and populated MMRecord instances to you in an AFNetworking success block. For more information please check out this [blog post](http://mutualmobile.github.io/blog/2014/01/14/afnetworking-res
