ActiveResourceKit
v1.2 (498.0)
Main Page
Classes
Files
File List
File Members
All
Classes
Files
Functions
Variables
Typedefs
Enumerator
Properties
Macros
Pages
ActiveResourceKit
ActiveResourceKit.h
Go to the documentation of this file.
1
/* ActiveResourceKit ActiveResourceKit.h
2
*
3
* Copyright © 2011, 2012, Roy Ratcliffe, Pioneering Software, United Kingdom
4
*
5
* Permission is hereby granted, free of charge, to any person obtaining a copy
6
* of this software and associated documentation files (the “Software”), to deal
7
* in the Software without restriction, including without limitation the rights
8
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
* copies of the Software, and to permit persons to whom the Software is
10
* furnished to do so, subject to the following conditions:
11
*
12
* The above copyright notice and this permission notice shall be included in
13
* all copies or substantial portions of the Software.
14
*
15
* THE SOFTWARE IS PROVIDED “AS IS,” WITHOUT WARRANTY OF ANY KIND, EITHER
16
* EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO
18
* EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
19
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
* DEALINGS IN THE SOFTWARE.
22
*
23
******************************************************************************/
24
25
#import <
ActiveResourceKit/ARIncrementalStore.h
>
26
#import <
ActiveResourceKit/ARResource.h
>
27
#import <
ActiveResourceKit/ARService.h
>
28
#import <
ActiveResourceKit/ARConnection.h
>
29
#import <
ActiveResourceKit/ARURLConnection.h
>
30
#import <
ActiveResourceKit/ARSynchronousLoadingURLConnection.h
>
31
#import <
ActiveResourceKit/ARQueuedLoadingURLConnection.h
>
32
#import <
ActiveResourceKit/ARHTTPResponse.h
>
33
#import <
ActiveResourceKit/NSPersistentStore+ActiveResource.h
>
34
#import <
ActiveResourceKit/NSManagedObject+ActiveResource.h
>
35
#import <
ActiveResourceKit/NSEntityDescription+ActiveResource.h
>
36
#import <
ActiveResourceKit/NSAttributeDescription+ActiveResource.h
>
37
38
#import <
ActiveResourceKit/ARFormatMethods.h
>
39
#import <
ActiveResourceKit/ARJSONFormat.h
>
40
41
#import <
ActiveResourceKit/ARHTTPMethods.h
>
42
#import <
ActiveResourceKit/ARErrors.h
>
43
#import <
ActiveResourceKit/ARMacros.h
>
44
#import <
ActiveResourceKit/Versioning.h
>
45
46
/*!
47
* @mainpage Active Resource Kit
48
*
49
* What can you do with Active Resource Kit? Active Resource Kit is yet-another
50
* RESTful framework. There are others. But Active Resource Kit has a number of
51
* distinct features.
52
* 1. It mirrors the Rails Active Resource gem closely. The interface and
53
* implementation remain as faithful as an Objective-C implementation can
54
* reasonably be to the Ruby-based originals.
55
* 2. It offers a very high-level interface to RESTful resources using Core
56
* Data. You can access remote resources just as if they were in a local Core
57
* Data store. The implementation uses the new Core Data @c NSIncrementalStore
58
* API to merge the two dissimilar interfaces.
59
* 3. It only has Foundation and Core Data as underlying dependencies. Although
60
* it has two immediate dependencies, Active Model Kit and Active Support Kit
61
* which fall under the same umbrella framework, Apple's Foundation and Core
62
* Data kits form the only @em external dependencies. The implementation employs
63
* only the Foundation framework for network access.
64
* 4. The framework supports various concurrency models when interacting with
65
* remote resources: these are the same models offered by Apple's Foundation @c
66
* NSURLConnection class, i.e. delegated URL connections, synchronous loading or
67
* queued loading. You can configure according to your requirements on a
68
* resource-by-resource basis.
69
* 5. There are no swizzles or other non-standard Objective-C tricks. The
70
* framework makes extensive use of C blocks for handling completions for both
71
* asynchronous and synchronous interfaces; this simply follows the pattern set
72
* by Apple in their URL connection API.
73
*
74
* @section setting_up Setting Up an Active Resource-Based Core Data Stack
75
*
76
* This is easy to do. Just follow the usual Core Data-prescribed procedure:
77
* load the model, load the coordinator with the model, add the store to the
78
* coordinator, and finally attach the coordinator to the context.
79
*
80
* See example below. There are some things to especially notice. First, the
81
* persistent store type specifies the @c ARIncrementalStore type. The URL
82
* specifies the remote resource, its protocol, host and path. Protocol can be
83
* @c http, or @c https if you want secure transport. The path can specify the
84
* site root, i.e. an empty or single-slash path, or can also include a sub-path
85
* nested within the remote site. The client-side data model must correspond to
86
* the remote's RESTful interface. The Active Resource incremental store
87
* utilises the client-side data model in order to deduce the entities, their
88
* properties and relationships. Core Data itself requires a valid data model.
89
*
90
* @code
91
* NSBundle *bundle = [NSBundle bundleForClass:[self class]];
92
* NSURL *modelURL = [bundle URLForResource:@"MyCoreDataModel" withExtension:@"momd"];
93
* NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
94
* NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
95
*
96
* NSError *__autoreleasing error = nil;
97
* NSPersistentStore *store = [coordinator addPersistentStoreWithType:[ARIncrementalStore storeType]
98
* configuration:nil
99
* URL:[NSURL URLWithString:@"http://localhost:3000"]
100
* options:nil
101
* error:&error];
102
* // <-- error handling goes here
103
*
104
* NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
105
* [context setPersistentStoreCoordinator:coordinator];
106
* [self setContext:context];
107
* @endcode
108
*
109
* Note that this excerpt uses Automatic Reference Counting, hence the @c
110
* __autoreleasing specifier for the error pointer. Notice the blatant lack of
111
* manual auto-releasing.
112
*
113
* @section accessing_resources Accessing Resources
114
*
115
* You can then access resources using @em only Core Data.
116
*
117
* @code
118
* NSError *__autoreleasing error = nil;
119
* NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
120
* NSArray *people = [[self context] executeFetchRequest:request error:&error];
121
* for (NSManagedObject *person in people)
122
* {
123
* NSString *name = [person valueForKey:@"name"];
124
* NSLog(@"person named %@", name);
125
* }
126
* @endcode
127
*
128
* You ask Core Data for the Person entities. The answer is a collection of
129
* managed object representing each Person. You access attributes on the objects
130
* using standard Cocoa key-value coding. However, underneath the hood, the
131
* Active Resource incremental store has enacted a RESTful GET request at
132
* http://localhost:3000/people.json, decoding and caching the active resources
133
* at the client side.
134
*
135
* At the other side of the connection (assuming your server runs on Rails; it
136
* does not need to be Rails but can be any conforming RESTful interface) you
137
* will see a GET request in the server log, as follows. Some details elided.
138
* @code
139
* Started GET "/people.json" for 127.0.0.1 at …
140
* Processing by PeopleController#index as JSON
141
* Person Load (0.2ms) SELECT "people".* FROM "people"
142
* Completed 200 OK in 5ms (Views: 3.8ms | ActiveRecord: 0.2ms)
143
* @endcode
144
*
145
* @subsection inserting_resources Inserting Resources
146
*
147
* This just becomes fuss-free:
148
* @code
149
* NSError *__autoreleasing error = nil;
150
* NSManagedObject *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:[self context]];
151
* [person setValue:@"Roy Ratcliffe" forKey:@"name"];
152
* BOOL yes = [[self context] save:&error];
153
* @endcode
154
* And on the server side becomes a familiar POST request:
155
* @code
156
* Started POST "/people.json" for 127.0.0.1 at …
157
* Processing by PeopleController#create as JSON
158
* Parameters: {"person"=>{"name"=>"Roy Ratcliffe"}}
159
* (0.1ms) begin transaction
160
* SQL (0.4ms) INSERT INTO "people" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", …], ["name", "Roy Ratcliffe"], ["updated_at", …]]
161
* (2.3ms) commit transaction
162
* Completed 201 Created in 5ms (Views: 0.8ms | ActiveRecord: 2.8ms)
163
* @endcode
164
*
165
* @subsection deleting_resources Deleting Resources
166
*
167
* Again, just very simply:
168
* @code
169
* NSError *__autoreleasing error = nil;
170
* [[self context] deleteObject:person];
171
* BOOL yes = [[self context] save:&error];
172
* @endcode
173
* And the server responds:
174
* @code
175
* Started DELETE "/people/16.json" for 127.0.0.1 at …
176
* Processing by PeopleController#destroy as JSON
177
* Parameters: {"id"=>"16"}
178
* Person Load (0.1ms) SELECT "people".* FROM "people" WHERE "people"."id" = ? LIMIT 1 [["id", "16"]]
179
* …
180
* SQL (0.3ms) DELETE FROM "people" WHERE "people"."id" = ? [["id", 16]]
181
* …
182
* Completed 200 OK in 15ms (ActiveRecord: 12.7ms)
183
* @endcode
184
*
185
* @subsection forming_associations Forming Associations
186
*
187
* You can conveniently form associations between objects and their remote
188
* resources using only the Core Data interface.
189
*
190
* The following demonstrates what happens when you instantiate two entities and
191
* wire them up entirely at the client side first. Lets say you have a post and
192
* comment model; posts have many comments, a one post to many comments
193
* association. The following initially creates a post with one comment.
194
*
195
* @code
196
* NSManagedObject *post = [NSEntityDescription insertNewObjectForEntityForName:@"Post" inManagedObjectContext:[self context]];
197
* NSManagedObject *comment = [NSEntityDescription insertNewObjectForEntityForName:@"Comment" inManagedObjectContext:[self context]];
198
*
199
* // Set up attributes for the post and the comment.
200
* [post setValue:@"De finibus bonorum et malorum" forKey:@"title"];
201
* [post setValue:@"Non eram nescius…" forKey:@"body"];
202
* [comment setValue:@"Quae cum dixisset…" forKey:@"text"];
203
*
204
* // Form the one-post-to-many-comments association.
205
* [comment setValue:post forKey:@"post"];
206
*
207
* // Send it all to the server.
208
* NSError *__autoreleasing error = nil;
209
* [[self context] save:&error];
210
* @endcode
211
*
212
* It constructs a new post, a new comment and their relationship within the
213
* client at first. Then it saves the context in order to transfer the objects and
214
* their relationship to the remote server.
215
*
216
* Thereafter, you can throw away the comment and refetch it by dereferencing the
217
* post's "comments" relationship. The following extract pulls out each text field
218
* from the comments based on a given post.
219
*
220
* @code
221
* NSMutableArray *comments = [NSMutableArray array];
222
* for (NSManagedObject *comment in [post valueForKey:@"comments"])
223
* {
224
* [comments addObject:[comment valueForKey:@"text"]];
225
* }
226
* [[comments objectAtIndex:0] rangeOfString:@"Quae cum dixisset"].location != NSNotFound;
227
* @endcode
228
*/
Generated by
1.8.2