rest_kat 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/model.h.erb +14 -4
- data/lib/model.m.erb +231 -30
- data/lib/rest_kat.rb +202 -56
- data/rest_kat.gemspec +2 -2
- data/src/MSRestSerializable.h +12 -50
- data/src/MSRestSerializable.m +15 -189
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.10
|
data/lib/model.h.erb
CHANGED
@@ -31,14 +31,17 @@
|
|
31
31
|
//// <%= klass.objc_class %>
|
32
32
|
//////////////////////////////////////////////////////////////////////////////
|
33
33
|
<%end%>
|
34
|
-
@interface <%= klass.objc_class %> :
|
34
|
+
@interface <%= klass.objc_class %> : NSObject<<%=klass.objc_protocols%>>
|
35
|
+
|
36
|
+
|
37
|
+
|
35
38
|
<%klass.properties.each do |property|%>
|
36
|
-
<%if property.klass.
|
37
|
-
// <%=property.name%> :
|
39
|
+
<%if property.klass.is_a? ObjCSequenceOfMap %>
|
40
|
+
// <%=property.name%> : sequence of <%=property.klass.item_class.objc_class%>
|
38
41
|
<%else%>
|
39
42
|
// <%=property.name%> : <%=property.klass.json_type%>
|
40
43
|
<%end%>
|
41
|
-
<%if property.klass.enum?%>
|
44
|
+
<%if property.klass.is_a? ObjCPrimitiveType and property.klass.enum?%>
|
42
45
|
// Enumeration of
|
43
46
|
<%property.klass.enum.each do |e|%>
|
44
47
|
// - <%=e%>
|
@@ -49,6 +52,9 @@
|
|
49
52
|
|
50
53
|
// Initialize all the methods. Called by +initialize ( don't call manually )
|
51
54
|
+ (void)initializeMapping;
|
55
|
+
<%if klass.cached?%>
|
56
|
+
+ (NSEntityDescription *)initializeCoreData;
|
57
|
+
<%end%>
|
52
58
|
|
53
59
|
// Static initializer ( don't call manually )
|
54
60
|
+ (void)initialize;
|
@@ -58,3 +64,7 @@
|
|
58
64
|
@end
|
59
65
|
|
60
66
|
<%end%>
|
67
|
+
|
68
|
+
extern NSMutableArray * entities();
|
69
|
+
|
70
|
+
extern NSManagedObjectModel * managedObjectModel();
|
data/lib/model.m.erb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
#import "<%=header%>"
|
2
|
+
#import <objc/runtime.h>
|
3
|
+
|
2
4
|
|
3
5
|
<%classes.each do |klass|%>
|
4
6
|
//////////////////////////////////////////////////////////////////////////////
|
@@ -6,41 +8,149 @@
|
|
6
8
|
//////////////////////////////////////////////////////////////////////////////
|
7
9
|
@implementation <%= klass.objc_class %>
|
8
10
|
|
11
|
+
+ (RKObjectMapping *) mapperForParsing
|
12
|
+
{
|
13
|
+
return [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:self];
|
14
|
+
}
|
15
|
+
|
16
|
+
+ (RKObjectMapping *) mapperForSerializing
|
17
|
+
{
|
18
|
+
return [[RKObjectManager sharedManager].mappingProvider serializationMappingForClass:self];
|
19
|
+
}
|
20
|
+
|
9
21
|
<%klass.properties.each do |property|%>
|
10
22
|
@synthesize <%= property.name %>;
|
11
23
|
<%end%>
|
12
24
|
|
13
25
|
+ (void)initialize{
|
26
|
+
[self initializeMapping];
|
14
27
|
<%if klass.resource%>
|
15
28
|
[self initializeRouting];
|
16
29
|
<%end%>
|
17
|
-
|
30
|
+
<%if klass.cached?%>
|
31
|
+
(void)[self initializeCoreData];
|
32
|
+
<%end%>
|
18
33
|
}
|
19
34
|
|
35
|
+
- (NSString*)description
|
36
|
+
{
|
37
|
+
RKObjectMapping * mapper = [[RKObjectManager sharedManager].mappingProvider serializationMappingForClass:[self class]];
|
38
|
+
RKObjectSerializer * serializer = [RKObjectSerializer serializerWithObject:self mapping:mapper];
|
39
|
+
|
40
|
+
NSError * error;
|
41
|
+
NSString * description = (NSString *)[serializer serializedObjectForMIMEType:RKMIMETypeJSON error: &error];
|
42
|
+
return [description stringByReplacingOccurrencesOfString:@"\"" withString:@"'"];
|
43
|
+
}
|
44
|
+
|
45
|
+
<%if klass.cached? %>
|
46
|
+
+ (NSEntityDescription * )initializeCoreData
|
47
|
+
{
|
48
|
+
static NSEntityDescription * entity;
|
49
|
+
if(entity){
|
50
|
+
return entity;
|
51
|
+
}
|
52
|
+
entity = [[NSEntityDescription alloc] init];
|
53
|
+
entity.name = @"<%=klass.objc_class%>";
|
54
|
+
entity.managedObjectClassName = @"<%=klass.objc_class%>";
|
55
|
+
|
56
|
+
// -------------------------------------------
|
57
|
+
// Define the properties mappings
|
58
|
+
NSMutableArray * properties = [NSMutableArray array];
|
59
|
+
<%klass.primitive_properties.each do |property|%>
|
60
|
+
{
|
61
|
+
// <%= property.name %>
|
62
|
+
NSAttributeDescription * attrDesc = [[NSAttributeDescription alloc] init];
|
63
|
+
attrDesc.name = @"<%= property.name %>";
|
64
|
+
[attrDesc setAttributeType:<%= property.ns_attribute_type %>];
|
65
|
+
[attrDesc setOptional:NO];
|
66
|
+
[properties addObject:attrDesc];
|
67
|
+
}
|
68
|
+
<%end%>
|
69
|
+
|
70
|
+
// ----------------------------------------------
|
71
|
+
// Define 'has one' relationships
|
72
|
+
// ----------------------------------------------
|
73
|
+
<%klass.has_one_properties.each do |property|%>
|
74
|
+
{
|
75
|
+
// <%= property.name %>
|
76
|
+
NSRelationshipDescription * relDesc = [[NSRelationshipDescription alloc] init];
|
77
|
+
[relDesc setDestinationEntity:[<%=property.klass.objc_class%> initializeCoreData]];
|
78
|
+
relDesc.name = @"<%= property.name %>";
|
79
|
+
relDesc.minCount = 1;
|
80
|
+
relDesc.maxCount = 1;
|
81
|
+
relDesc.deleteRule = NSCascadeDeleteRule;
|
82
|
+
[properties addObject:relDesc];
|
83
|
+
}
|
84
|
+
<%end%>
|
85
|
+
|
86
|
+
// ----------------------------------------------
|
87
|
+
// Define 'has many' objects relationships
|
88
|
+
// ----------------------------------------------
|
89
|
+
<%klass.has_many_maps_properties.each do |property|%>
|
90
|
+
{
|
91
|
+
// <%= property.name %>
|
92
|
+
NSRelationshipDescription * relDesc = [[NSRelationshipDescription alloc] init];
|
93
|
+
relDesc.name = @"<%= property.name %>";
|
94
|
+
// Sequence of core data objects
|
95
|
+
[relDesc setDestinationEntity:[<%=property.klass.item_class.objc_class%> initializeCoreData]];
|
96
|
+
relDesc.deleteRule = NSCascadeDeleteRule;
|
97
|
+
[properties addObject:relDesc];
|
98
|
+
}
|
99
|
+
<%end%>
|
100
|
+
|
101
|
+
// ----------------------------------------------
|
102
|
+
// Define 'has many' primitves relationships
|
103
|
+
// ----------------------------------------------
|
104
|
+
<%klass.has_many_maps_properties.each do |property|%>
|
105
|
+
{
|
106
|
+
// Sequence of primitives
|
107
|
+
// This is really a sequence of primitive
|
108
|
+
#warning <%= property.name %> is a sequence of primitive
|
109
|
+
}
|
110
|
+
<%end%>
|
111
|
+
|
112
|
+
[entity setProperties:properties];
|
113
|
+
return entity;
|
114
|
+
}
|
115
|
+
<%end%>
|
116
|
+
|
117
|
+
|
20
118
|
+ (void)initializeMapping{
|
21
119
|
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[<%=klass.objc_class%> class]];
|
22
120
|
|
23
121
|
// -------------------------------------------
|
24
|
-
// Define
|
25
|
-
|
122
|
+
// Define 'primitive' properties mappings
|
123
|
+
// ----------------------------------------------
|
124
|
+
<%klass.primitive_properties.each do |property|%>
|
26
125
|
[mapping mapKeyPath:@"<%=property.name%>" toAttribute:@"<%=property.name%>"];
|
27
|
-
|
126
|
+
<%end%>
|
127
|
+
<%klass.has_many_primitives_properties.each do |property|%>
|
128
|
+
// NSArray of <%= property.klass.item_class.objc_class %>
|
129
|
+
[mapping mapKeyPath:@"<%=property.name%>" toAttribute:@"<%=property.name%>"];
|
130
|
+
<%end%>
|
28
131
|
|
29
|
-
//
|
30
|
-
// Define
|
31
|
-
|
32
|
-
|
132
|
+
// ----------------------------------------------
|
133
|
+
// Define 'has one' relationships
|
134
|
+
// ----------------------------------------------
|
135
|
+
<%klass.has_one_properties.each do |property|%>
|
33
136
|
{
|
34
|
-
|
35
|
-
RKObjectMapping * mapper = [[RKObjectManager sharedManager].mappingProvider
|
137
|
+
// <%= property.name %>
|
138
|
+
RKObjectMapping * mapper = [[RKObjectManager sharedManager].mappingProvider
|
139
|
+
objectMappingForClass:[<%=property.klass.objc_class%> class]];
|
36
140
|
[mapping hasOne:@"<%=property.name%>" withMapping:mapper];
|
37
|
-
|
38
|
-
|
141
|
+
}
|
142
|
+
<%end%>
|
143
|
+
|
144
|
+
// ----------------------------------------------
|
145
|
+
// Define 'has many' relationships
|
146
|
+
// ----------------------------------------------
|
147
|
+
<%klass.has_many_maps_properties.each do |property|%>
|
148
|
+
{
|
149
|
+
RKObjectMapping * mapper = [[RKObjectManager sharedManager].mappingProvider
|
150
|
+
objectMappingForClass:[<%=property.klass.item_class.objc_class%> class]];
|
39
151
|
[mapping hasMany:@"<%=property.name%>" withMapping:mapper];
|
40
|
-
<%end%>
|
41
152
|
}
|
42
|
-
|
43
|
-
<%end%>
|
153
|
+
<%end%>
|
44
154
|
|
45
155
|
// -------------------------------------------
|
46
156
|
// Register the mapper for the class
|
@@ -56,34 +166,94 @@
|
|
56
166
|
return @"<%= klass.resource.hash[:resource] %>";
|
57
167
|
}
|
58
168
|
|
169
|
+
+ (void)initializeRouting{
|
170
|
+
RKObjectRouter * router = [RKObjectManager sharedManager].router;
|
171
|
+
|
172
|
+
NSString * collectionResource = [self resourcePath];
|
173
|
+
NSString * objectResource = [NSString stringWithFormat:@"%@/(id)", collectionResource];
|
174
|
+
|
175
|
+
<%if klass.resource.create?%>
|
176
|
+
[router routeClass:self toResourcePath:collectionResource forMethod:RKRequestMethodPOST];
|
177
|
+
<%end%>
|
178
|
+
<%if klass.resource.read?%>
|
179
|
+
[router routeClass:self toResourcePath:objectResource forMethod:RKRequestMethodGET];
|
180
|
+
<%end%>
|
181
|
+
<%if klass.resource.update?%>
|
182
|
+
[router routeClass:self toResourcePath:objectResource forMethod:RKRequestMethodPUT];
|
183
|
+
<%end%>
|
184
|
+
<%if klass.resource.delete?%>
|
185
|
+
[router routeClass:self toResourcePath:objectResource forMethod:RKRequestMethodDELETE];
|
186
|
+
<%end%>
|
59
187
|
|
60
|
-
+ (Class) classForResource{
|
61
|
-
return [ <%=klass.resource.objc_resource_type%> class];
|
62
188
|
}
|
63
189
|
|
64
|
-
|
190
|
+
- (BOOL)isNew
|
65
191
|
{
|
66
|
-
|
192
|
+
BOOL hasId = class_getProperty([self class], [@"id" UTF8String]) != NULL;
|
193
|
+
return ([self valueForKey:@"id"] == NULL || !hasId);
|
194
|
+
}
|
195
|
+
|
196
|
+
-(void) saveWithDelegate:(id<RKObjectLoaderDelegate>)delegate
|
197
|
+
{
|
198
|
+
RKObjectMapping * mapper = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[self class]];
|
199
|
+
|
200
|
+
if ([self isNew])
|
201
|
+
{
|
202
|
+
[[RKObjectManager sharedManager] postObject:self mapResponseWith:mapper delegate:delegate];
|
203
|
+
}else{
|
204
|
+
[[RKObjectManager sharedManager] putObject:self mapResponseWith:mapper delegate:delegate];
|
205
|
+
}
|
206
|
+
|
67
207
|
}
|
68
208
|
|
69
|
-
|
209
|
+
- (void)deleteWithDelegate:(id<RKObjectLoaderDelegate>)delegate
|
70
210
|
{
|
71
|
-
|
211
|
+
RKObjectMapping * mapper = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[self class]];
|
212
|
+
[[RKObjectManager sharedManager] deleteObject:self mapResponseWith:mapper delegate:delegate];
|
72
213
|
}
|
73
214
|
|
74
|
-
+ (
|
215
|
+
+ (void) loadItem:(NSNumber *)id
|
216
|
+
withDelegate:(id<RKObjectLoaderDelegate>)delegate;
|
75
217
|
{
|
76
|
-
|
218
|
+
RKObjectMapping * mapper = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[self class]];
|
219
|
+
|
220
|
+
<%= klass.objc_class%> * instance = [[self alloc] init];
|
221
|
+
[instance setValue:id forKey:@"id"];
|
222
|
+
[[RKObjectManager sharedManager] getObject:instance
|
223
|
+
mapResponseWith:mapper
|
224
|
+
delegate:delegate];
|
77
225
|
}
|
78
226
|
|
79
|
-
|
227
|
+
// Load collection
|
228
|
+
+ (void) loadCollectionWithDelegate:(id<RKObjectLoaderDelegate>)delegate
|
80
229
|
{
|
81
|
-
|
230
|
+
RKObjectManager * objectManager = [RKObjectManager sharedManager];
|
231
|
+
RKObjectMapping * mapping = [objectManager.mappingProvider
|
232
|
+
objectMappingForClass:self ];
|
233
|
+
|
234
|
+
[objectManager loadObjectsAtResourcePath:[self resourcePath]
|
235
|
+
objectMapping:mapping
|
236
|
+
delegate:delegate];
|
82
237
|
}
|
83
238
|
|
84
|
-
|
239
|
+
|
240
|
+
// Load collection with query
|
241
|
+
+ (void) loadCollectionThroughQuery:(NSObject *)mappableQueryObject
|
242
|
+
withDelegate:(id<RKObjectLoaderDelegate>)delegate
|
85
243
|
{
|
86
|
-
|
244
|
+
|
245
|
+
RKObjectManager * objectManager = [RKObjectManager sharedManager];
|
246
|
+
RKObjectMapping * mapping = [objectManager.mappingProvider
|
247
|
+
objectMappingForClass:self ];
|
248
|
+
|
249
|
+
|
250
|
+
// Append the dictionary to the resource as query parameters
|
251
|
+
NSString * resourcePath = RKPathAppendQueryParams([self resourcePath], convertToDictionary(mappableQueryObject));
|
252
|
+
|
253
|
+
// Load the objects at the query
|
254
|
+
[objectManager loadObjectsAtResourcePath:resourcePath
|
255
|
+
objectMapping:mapping
|
256
|
+
delegate:delegate];
|
87
257
|
}
|
88
258
|
<%end%>
|
89
259
|
|
@@ -104,12 +274,43 @@ return object;
|
|
104
274
|
- (id) copyWithZone : (NSZone * ) zone
|
105
275
|
{
|
106
276
|
<%=klass.objc_class%> * object = [[<%=klass.objc_class%> allocWithZone:zone] init];
|
107
|
-
|
108
|
-
|
109
|
-
|
277
|
+
<%klass.properties.each do |property|%>
|
278
|
+
object.<%=property.name%> = [self.<%=property.name%> copy];
|
279
|
+
<%end%>
|
110
280
|
return object;
|
111
281
|
}
|
112
282
|
|
283
|
+
|
113
284
|
@end
|
114
285
|
|
115
286
|
<%end%>
|
287
|
+
|
288
|
+
|
289
|
+
|
290
|
+
|
291
|
+
NSMutableArray * entities(){
|
292
|
+
static NSMutableArray * _entities = nil;
|
293
|
+
if(!_entities){
|
294
|
+
_entities = [[NSMutableArray alloc] init];
|
295
|
+
<%classes.each do |klass|%>
|
296
|
+
<%if klass.cached? %>
|
297
|
+
[_entities addObject:[<%=klass.objc_class%> initializeCoreData]];
|
298
|
+
<%end%>
|
299
|
+
<%end%>
|
300
|
+
}
|
301
|
+
return _entities;
|
302
|
+
}
|
303
|
+
|
304
|
+
NSManagedObjectModel * managedObjectModel(){
|
305
|
+
static NSManagedObjectModel *mom = nil;
|
306
|
+
|
307
|
+
if (mom != nil) {
|
308
|
+
return mom;
|
309
|
+
}
|
310
|
+
|
311
|
+
mom = [[NSManagedObjectModel alloc] init];
|
312
|
+
[mom setEntities:entities()];
|
313
|
+
|
314
|
+
return mom;
|
315
|
+
|
316
|
+
}
|
data/lib/rest_kat.rb
CHANGED
@@ -5,6 +5,10 @@ module RestKat
|
|
5
5
|
self.hash = resource
|
6
6
|
end
|
7
7
|
|
8
|
+
def cached?
|
9
|
+
self.hash[:cached]
|
10
|
+
end
|
11
|
+
|
8
12
|
def objc_resource_type
|
9
13
|
hash[:type][:name]
|
10
14
|
end
|
@@ -76,39 +80,115 @@ module RestKat
|
|
76
80
|
self.klass = klass
|
77
81
|
self.name = name
|
78
82
|
end
|
83
|
+
|
84
|
+
def ns_attribute_type
|
85
|
+
# typedef enum {
|
86
|
+
# NSUndefinedAttributeType = 0,
|
87
|
+
# NSInteger16AttributeType = 100,
|
88
|
+
# NSInteger32AttributeType = 200,
|
89
|
+
# NSInteger64AttributeType = 300,
|
90
|
+
# NSDecimalAttributeType = 400,
|
91
|
+
# NSDoubleAttributeType = 500,
|
92
|
+
# NSFloatAttributeType = 600,
|
93
|
+
# NSStringAttributeType = 700,
|
94
|
+
# NSBooleanAttributeType = 800,
|
95
|
+
# NSDateAttributeType = 900,
|
96
|
+
# NSBinaryDataAttributeType = 1000,
|
97
|
+
# NSTransformableAttributeType = 1800,
|
98
|
+
# NSObjectIDAttributeType = 2000
|
99
|
+
# } NSAttributeType;
|
100
|
+
case self.klass.objc_class
|
101
|
+
when "NSNumber"
|
102
|
+
case self.klass.json_type
|
103
|
+
when "int"
|
104
|
+
"NSInteger32AttributeType"
|
105
|
+
when "float"
|
106
|
+
"NSFloatAttributeType"
|
107
|
+
when "bool"
|
108
|
+
"NSBooleanAttributeType"
|
109
|
+
end
|
110
|
+
when "NSDate"
|
111
|
+
"NSDateAttributeType"
|
112
|
+
when "NSString"
|
113
|
+
"NSStringAttributeType"
|
114
|
+
else
|
115
|
+
raise Exception.new("Unknown type #{self.klass.objc_class} for NSAttributeType to be handled for property #{self.name}" )
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
79
119
|
end
|
80
120
|
|
81
|
-
class
|
82
|
-
|
83
|
-
attr_accessor :sequence_of
|
84
|
-
attr_accessor :type
|
85
|
-
attr_accessor :parent
|
86
|
-
attr_accessor :json_type
|
87
|
-
attr_accessor :node
|
88
|
-
attr_accessor :resource
|
121
|
+
class ObjCSequence
|
122
|
+
attr_accessor :item_class
|
89
123
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
124
|
+
def cached
|
125
|
+
item_class.cached
|
126
|
+
end
|
127
|
+
|
128
|
+
def cached=val
|
129
|
+
item_class.cached = val
|
130
|
+
end
|
131
|
+
|
132
|
+
def initialize klass
|
133
|
+
self.item_class = klass
|
134
|
+
end
|
135
|
+
|
136
|
+
def objc_property_decl name
|
137
|
+
"@property (nonatomic, strong) NSArray * #{name}"
|
138
|
+
end
|
139
|
+
|
140
|
+
def objc_property_arg_decl name
|
141
|
+
"#{name}: (NSArray *) #{name}"
|
95
142
|
end
|
143
|
+
|
144
|
+
def json_type
|
145
|
+
"seq"
|
146
|
+
end
|
147
|
+
|
148
|
+
def objc_class
|
149
|
+
"NSArray *"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
class ObjCSequenceOfMap < ObjCSequence
|
154
|
+
def initialize klass
|
155
|
+
super klass
|
96
156
|
end
|
157
|
+
end
|
158
|
+
|
159
|
+
class ObjCSequenceOfPrimitve < ObjCSequence
|
160
|
+
def initialize klass
|
161
|
+
super klass
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
class ObjCType
|
166
|
+
attr_accessor :objc_class
|
167
|
+
attr_accessor :json_type
|
168
|
+
attr_accessor :node
|
169
|
+
attr_accessor :cached
|
97
170
|
|
98
|
-
def
|
99
|
-
|
171
|
+
def objc_property_decl name
|
172
|
+
"@property (nonatomic, strong) #{objc_class} * #{name}"
|
100
173
|
end
|
101
174
|
|
102
|
-
def
|
103
|
-
|
175
|
+
def objc_property_arg_decl name
|
176
|
+
"#{name}: (#{objc_class} *) #{name}"
|
104
177
|
end
|
105
178
|
|
106
|
-
def
|
107
|
-
|
179
|
+
def initialize objc_class, json_type, node
|
180
|
+
self.objc_class = objc_class
|
181
|
+
self.json_type = json_type
|
182
|
+
self.node = node
|
108
183
|
end
|
184
|
+
end
|
109
185
|
|
110
|
-
|
111
|
-
|
186
|
+
class ObjCPrimitiveType < ObjCType
|
187
|
+
attr_accessor :objc_class
|
188
|
+
attr_accessor :json_type
|
189
|
+
attr_accessor :node
|
190
|
+
def initialize objc_class, json_type, node
|
191
|
+
super objc_class, json_type, node
|
112
192
|
end
|
113
193
|
|
114
194
|
def enum?
|
@@ -118,13 +198,68 @@ module RestKat
|
|
118
198
|
def enum
|
119
199
|
node["enum"]
|
120
200
|
end
|
201
|
+
end
|
121
202
|
|
122
|
-
|
123
|
-
|
203
|
+
class ObjCMapType < ObjCType
|
204
|
+
attr_accessor :properties
|
205
|
+
attr_accessor :sequence_of
|
206
|
+
attr_accessor :resource
|
207
|
+
|
208
|
+
def cached?
|
209
|
+
cached
|
124
210
|
end
|
125
211
|
|
126
|
-
def
|
127
|
-
|
212
|
+
def cached=val
|
213
|
+
@cached = val
|
214
|
+
if properties
|
215
|
+
properties.each do |property|
|
216
|
+
property.klass.cached = val
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def primitive_properties
|
222
|
+
properties.select do |p|
|
223
|
+
p.klass.is_a? ObjCPrimitiveType
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def has_one_properties
|
228
|
+
properties.select do |p|
|
229
|
+
p.klass.is_a? ObjCMapType
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def has_many_properties
|
234
|
+
properties.select do |p|
|
235
|
+
p.klass.is_a? ObjCSequence
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def has_many_primitives_properties
|
240
|
+
properties.select do |p|
|
241
|
+
p.klass.is_a? ObjCSequenceOfPrimitve
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def has_many_maps_properties
|
246
|
+
properties.select do |p|
|
247
|
+
p.klass.is_a? ObjCSequenceOfMap
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
def objc_super_class
|
252
|
+
if resource
|
253
|
+
"MSRestSerializableResource"
|
254
|
+
else
|
255
|
+
"MSRestSerializable"
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def objc_protocols
|
260
|
+
["NSCopying"].tap do |p|
|
261
|
+
p << "MSRestResource" if resource
|
262
|
+
end.join ', '
|
128
263
|
end
|
129
264
|
|
130
265
|
def objc_properites_arg_list_decl
|
@@ -133,11 +268,10 @@ module RestKat
|
|
133
268
|
end.join "\n "
|
134
269
|
end
|
135
270
|
|
136
|
-
def initialize
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
self.node = node
|
271
|
+
def initialize objc_class, json_type, node
|
272
|
+
super objc_class, json_type, node
|
273
|
+
self.properties = nil
|
274
|
+
self.cached = false
|
141
275
|
end
|
142
276
|
|
143
277
|
end
|
@@ -188,10 +322,11 @@ module RestKat
|
|
188
322
|
Resource.new(resource_hash).tap do |resource|
|
189
323
|
# Generate the query classes first
|
190
324
|
resource.queries.each do |query|
|
191
|
-
|
325
|
+
# Query objects do not get cached in core data
|
326
|
+
to_objective_c_class node:query["type"], cached:false
|
192
327
|
end
|
193
328
|
# Generate the resource classes next
|
194
|
-
klass = to_objective_c_class resource.hash[:type]
|
329
|
+
klass = to_objective_c_class node:resource.hash[:type], cached:resource.cached?
|
195
330
|
# Mark this class as being a REST resource
|
196
331
|
klass.resource = resource
|
197
332
|
end
|
@@ -218,7 +353,7 @@ module RestKat
|
|
218
353
|
end
|
219
354
|
|
220
355
|
def find_processed_class node
|
221
|
-
classes.find{|c| c.
|
356
|
+
classes.find{|c| c.objc_class == node[:name]}
|
222
357
|
end
|
223
358
|
|
224
359
|
# Perform a depth first traversal of the type tree. The resulting
|
@@ -226,49 +361,47 @@ module RestKat
|
|
226
361
|
# the code generation phase this classes will be injected last into
|
227
362
|
# the code making sure the dependencies are define in the correct
|
228
363
|
# order.
|
229
|
-
def to_objective_c_class
|
364
|
+
def to_objective_c_class options
|
365
|
+
|
366
|
+
node = options[:node]
|
367
|
+
cached = options[:cached]
|
368
|
+
|
230
369
|
unless node
|
231
|
-
raise Exception.new("node is nil
|
370
|
+
raise Exception.new("node is nil")
|
232
371
|
end
|
233
372
|
|
234
373
|
case node[:type]
|
235
374
|
when "map"
|
236
375
|
|
237
376
|
unless klass = find_processed_class(node)
|
238
|
-
klass =
|
377
|
+
klass = ObjCMapType.new(node[:name], node[:type], node)
|
239
378
|
|
240
379
|
klass.properties = node[:mapping].collect do |property_name, property_node|
|
241
380
|
if property_node[:type] == "map"
|
242
381
|
property_node[:name] ||= IosMapping.obj_c_type_for_property(node, property_name)
|
243
382
|
end
|
244
|
-
ObjCProperty.new(to_objective_c_class(property_node), property_name)
|
383
|
+
ObjCProperty.new(to_objective_c_class(node:property_node, cached:cached), property_name)
|
245
384
|
end
|
246
385
|
|
247
386
|
self.classes << klass
|
248
387
|
end
|
249
388
|
|
389
|
+
# Inherit caching from parent as the whole object graph
|
390
|
+
# of cached objects needs to go into Core Data
|
391
|
+
klass.cached = cached
|
392
|
+
|
250
393
|
when "seq"
|
251
|
-
klass =
|
252
|
-
if node[:sequence].length != 1
|
253
|
-
raise "Only support sequence of map with one map type"
|
254
|
-
end
|
255
|
-
sequence_node = node[:sequence].first
|
256
|
-
if sequence_node["type"] == "map"
|
257
|
-
if not sequence_node["name"]
|
258
|
-
raise Exception.new ("sequence of map nodes must have a :name to generate the objective C types")
|
259
|
-
end
|
260
|
-
klass.sequence_of = to_objective_c_class sequence_node
|
261
|
-
end
|
394
|
+
klass = create_sequence(node, cached)
|
262
395
|
when "str", "text"
|
263
|
-
klass =
|
396
|
+
klass = ObjCPrimitiveType.new(node[:name] || "NSString", node[:type], node)
|
264
397
|
when "int"
|
265
|
-
klass =
|
398
|
+
klass = ObjCPrimitiveType.new(node[:name] || "NSNumber", node[:type], node)
|
266
399
|
when "float"
|
267
|
-
klass =
|
400
|
+
klass = ObjCPrimitiveType.new(node[:name] || "NSNumber", node[:type], node)
|
268
401
|
when "bool"
|
269
|
-
klass =
|
402
|
+
klass = ObjCPrimitiveType.new(node[:name] || "NSNumber", node[:type], node)
|
270
403
|
when "any"
|
271
|
-
klass =
|
404
|
+
klass = ObjCPrimitiveType.new(node[:name] || "NSObject", node[:type], node)
|
272
405
|
else
|
273
406
|
raise Exception.new("Unhandled type '#{node[:type]} for node with name #{node[:name]}")
|
274
407
|
end
|
@@ -278,6 +411,20 @@ module RestKat
|
|
278
411
|
klass
|
279
412
|
|
280
413
|
end
|
414
|
+
|
415
|
+
def create_sequence node, cached
|
416
|
+
if node[:sequence].length != 1
|
417
|
+
raise "Only support sequence of map with one map type"
|
418
|
+
end
|
419
|
+
item_class = to_objective_c_class node:node[:sequence].first, cached:cached
|
420
|
+
if item_class.is_a? ObjCMapType
|
421
|
+
ObjCSequenceOfMap.new(item_class)
|
422
|
+
elsif item_class.is_a? ObjCPrimitiveType
|
423
|
+
ObjCSequenceOfPrimitve.new(item_class)
|
424
|
+
else
|
425
|
+
raise Exception.new "#{item_class.class} cannot be handled here"
|
426
|
+
end
|
427
|
+
end
|
281
428
|
end
|
282
429
|
end
|
283
430
|
|
@@ -296,7 +443,6 @@ module RestKat
|
|
296
443
|
model.h.erb
|
297
444
|
model.m.erb
|
298
445
|
rest_kat.rb
|
299
|
-
validator.rb
|
300
446
|
].collect do |d|
|
301
447
|
File.expand_path "../#{d}", __FILE__
|
302
448
|
end
|
@@ -328,11 +474,11 @@ module RestKat
|
|
328
474
|
tgt_m = File.join api_location, "MSRestSerializable.m"
|
329
475
|
|
330
476
|
|
331
|
-
t0 = file tgt_h
|
477
|
+
t0 = file tgt_h => src_h do
|
332
478
|
cp src_h, tgt_h, :verbose => true
|
333
479
|
end
|
334
480
|
|
335
|
-
t1 = file tgt_m
|
481
|
+
t1 = file tgt_m => src_m do
|
336
482
|
cp src_m, tgt_m, :verbose => true
|
337
483
|
end
|
338
484
|
|
data/rest_kat.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rest_kat}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.10"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = [%q{Brad Phelan}]
|
12
|
-
s.date = %q{2011-11-
|
12
|
+
s.date = %q{2011-11-28}
|
13
13
|
s.description = %q{The generated source code is a layer on top of the iOS REST framework http://restkit.org/}
|
14
14
|
s.email = %q{brad.phelan@mysugr.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/src/MSRestSerializable.h
CHANGED
@@ -10,73 +10,35 @@
|
|
10
10
|
#import "NSDate+APIDate.h"
|
11
11
|
#import <RestKit/RestKit.h>
|
12
12
|
|
13
|
-
|
14
|
-
// The mapper for this instance
|
15
|
-
- (RKObjectMapping *) _mapper;
|
13
|
+
extern NSDictionary * convertToDictionary( NSObject * object);
|
16
14
|
|
17
|
-
|
18
|
-
- (RKObjectMapping *) _serializer;
|
15
|
+
extern NSString * convertToFormURLEncoded( NSObject * object);
|
19
16
|
|
20
|
-
|
17
|
+
extern NSString * convertToJSON( NSObject * object);
|
21
18
|
|
22
|
-
- (NSString *)convertToFormURLEncoded;
|
23
19
|
|
24
|
-
|
20
|
+
@protocol MSRestResource
|
25
21
|
|
22
|
+
// Is the object new or not
|
26
23
|
- (BOOL)isNew;
|
27
|
-
@end
|
28
|
-
|
29
|
-
@interface MSRestSerializableResource : MSRestSerializable
|
30
|
-
|
31
|
-
#pragma mark methods to be overridden
|
32
|
-
|
33
|
-
+ (Class) classForResource;
|
34
|
-
|
35
|
-
// The resource path. If this
|
36
|
-
+ (NSString *) resourcePath;
|
37
|
-
|
38
|
-
// Is the resource a singleton or a collection
|
39
|
-
+ (bool) isSingleton;
|
40
|
-
|
41
|
-
// Can the client create resources
|
42
|
-
+ (bool) canCreate;
|
43
|
-
|
44
|
-
// Can the client read resources
|
45
|
-
+ (bool) canRead;
|
46
|
-
|
47
|
-
// Can the client update resources
|
48
|
-
+ (bool) canUpdate;
|
49
|
-
|
50
|
-
// Can the client delete resources
|
51
|
-
+ (bool) canDelete;
|
52
|
-
|
53
|
-
#pragma mark helpers
|
54
|
-
|
55
|
-
// The router for this class
|
56
|
-
+ (RKObjectRouter *) router;
|
57
|
-
|
58
|
-
// Intialize the routing module. Must
|
59
|
-
// be called from +initialize in a
|
60
|
-
// subclass or the logic will not
|
61
|
-
// work.
|
62
|
-
+ (void) initializeRouting;
|
63
24
|
|
25
|
+
+ (void)initializeRouting;
|
64
26
|
|
65
|
-
//
|
27
|
+
// Save a single record
|
66
28
|
-(void) saveWithDelegate:(id<RKObjectLoaderDelegate>)delegate;
|
67
29
|
|
68
|
-
//
|
30
|
+
// Delete a single record
|
69
31
|
- (void)deleteWithDelegate:(id<RKObjectLoaderDelegate>)delegate;
|
70
32
|
|
71
|
-
//
|
72
|
-
+ (void)
|
73
|
-
|
33
|
+
// Load a single record
|
34
|
+
+ (void) loadItem:(NSNumber *)id
|
35
|
+
withDelegate:(id<RKObjectLoaderDelegate>)delegate;
|
74
36
|
|
75
37
|
// Load collection
|
76
38
|
+ (void) loadCollectionWithDelegate:(id<RKObjectLoaderDelegate>)delegate;
|
77
39
|
|
78
40
|
// Load collection with query
|
79
|
-
+ (void) loadCollectionThroughQuery:(
|
41
|
+
+ (void) loadCollectionThroughQuery:(NSObject *)mappableQueryObject
|
80
42
|
withDelegate:(id<RKObjectLoaderDelegate>)delegate;
|
81
43
|
|
82
44
|
@end
|
data/src/MSRestSerializable.m
CHANGED
@@ -10,210 +10,36 @@
|
|
10
10
|
#import <RestKit/RestKit.h>
|
11
11
|
#import <objc/runtime.h>
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
- (RKObjectMapping *) _mapper
|
17
|
-
{
|
18
|
-
RKObjectMappingProvider * provider = [RKObjectManager sharedManager].mappingProvider;
|
19
|
-
RKObjectMapping * mapping = [provider objectMappingForClass:[self class]];
|
20
|
-
return mapping;
|
21
|
-
|
22
|
-
|
23
|
-
}
|
24
|
-
|
25
|
-
- (RKObjectMapping *) _serializer
|
13
|
+
static RKObjectSerializer * serializerFor(NSObject * serializable)
|
26
14
|
{
|
27
|
-
|
28
|
-
|
29
|
-
return mapping;
|
30
|
-
}
|
15
|
+
RKObjectMapping * mapper = [[RKObjectManager sharedManager].mappingProvider
|
16
|
+
serializationMappingForClass:serializable.class];
|
31
17
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
{
|
36
|
-
BOOL hasId = class_getProperty([self class], [@"id" UTF8String]) != NULL;
|
37
|
-
return ([self valueForKey:@"id"] == NULL || !hasId);
|
18
|
+
return [RKObjectSerializer
|
19
|
+
serializerWithObject:serializable
|
20
|
+
mapping:mapper];
|
38
21
|
}
|
39
22
|
|
40
|
-
|
41
|
-
- (NSDictionary *)convertToDictionary
|
23
|
+
NSDictionary * convertToDictionary(NSObject * serializable)
|
42
24
|
{
|
43
25
|
NSError * error;
|
44
|
-
|
45
|
-
|
46
|
-
return [querySerializer serializedObject:&error];
|
26
|
+
return [serializerFor(serializable)
|
27
|
+
serializedObject:&error];
|
47
28
|
}
|
48
29
|
|
49
30
|
|
50
|
-
|
31
|
+
NSString * convertToJSON(NSObject * serializable)
|
51
32
|
{
|
52
|
-
RKObjectSerializer * serializer = [RKObjectSerializer serializerWithObject:self mapping:[self _serializer]];
|
53
33
|
NSError * error;
|
54
|
-
|
55
|
-
|
34
|
+
return (NSString *)[serializerFor(serializable)
|
35
|
+
serializedObjectForMIMEType:RKMIMETypeJSON error:&error];
|
56
36
|
}
|
57
37
|
|
58
|
-
|
38
|
+
NSString * convertToFormURLEncoded(NSObject * serializable)
|
59
39
|
{
|
60
|
-
RKObjectSerializer * serializer = [RKObjectSerializer serializerWithObject:self mapping:[self _serializer]];
|
61
|
-
|
62
40
|
NSError * error;
|
63
|
-
|
64
|
-
|
65
|
-
}
|
66
|
-
|
67
|
-
- (NSString*)description
|
68
|
-
{
|
69
|
-
|
70
|
-
|
71
|
-
RKObjectSerializer * serializer = [RKObjectSerializer serializerWithObject:self mapping:[self _serializer]];
|
72
|
-
|
73
|
-
NSError * error;
|
74
|
-
NSString * description = (NSString *)[serializer serializedObjectForMIMEType:RKMIMETypeJSON error: &error];
|
75
|
-
return [description stringByReplacingOccurrencesOfString:@"\"" withString:@"'"];
|
76
|
-
}
|
77
|
-
|
78
|
-
- (id)copyWithZone:(NSZone *)zone
|
79
|
-
{
|
80
|
-
return [[MSRestSerializable allocWithZone:zone] init];
|
81
|
-
}
|
82
|
-
|
83
|
-
@end
|
84
|
-
|
85
|
-
@implementation MSRestSerializableResource
|
86
|
-
|
87
|
-
+ (RKObjectRouter *) router
|
88
|
-
{
|
89
|
-
return [RKObjectManager sharedManager].router;
|
90
|
-
}
|
91
|
-
|
92
|
-
+ (Class) classForResource
|
93
|
-
{
|
94
|
-
NSAssert(NO, @"Stub implementation. Must be implemented in subclass");
|
95
|
-
return NULL;
|
96
|
-
}
|
97
|
-
|
98
|
-
|
99
|
-
+ (void) initializeRouting
|
100
|
-
{
|
101
|
-
RKObjectRouter * router = [self router];
|
102
|
-
|
103
|
-
NSString * collectionResource = [self resourcePath];
|
104
|
-
NSString * objectResource = [NSString stringWithFormat:@"%@/:id", collectionResource];
|
105
|
-
|
106
|
-
if([self isSingleton])
|
107
|
-
{
|
108
|
-
objectResource = collectionResource;
|
109
|
-
}
|
110
|
-
|
111
|
-
if ([self canCreate]){
|
112
|
-
[router routeClass:self toResourcePath:collectionResource forMethod:RKRequestMethodPOST];
|
113
|
-
}
|
114
|
-
|
115
|
-
if ([self canRead]){
|
116
|
-
[router routeClass:self toResourcePath:objectResource forMethod:RKRequestMethodGET];
|
117
|
-
}
|
118
|
-
|
119
|
-
if ([self canUpdate])
|
120
|
-
{
|
121
|
-
[router routeClass:self toResourcePath:objectResource forMethod:RKRequestMethodPUT];
|
122
|
-
}
|
123
|
-
|
124
|
-
if ([self canDelete])
|
125
|
-
{
|
126
|
-
[router routeClass:self toResourcePath:objectResource forMethod:RKRequestMethodDELETE];
|
127
|
-
}
|
128
|
-
|
129
|
-
}
|
130
|
-
|
131
|
-
|
132
|
-
+ (NSString *) resourcePath{
|
133
|
-
NSAssert(NO, @"Not implemented");
|
134
|
-
return NULL;
|
135
|
-
}
|
136
|
-
|
137
|
-
+ (bool) isSingleton{
|
138
|
-
return true;
|
139
|
-
}
|
140
|
-
+ (bool) canCreate{
|
141
|
-
return true;
|
142
|
-
}
|
143
|
-
+ (bool) canRead{
|
144
|
-
return true;
|
145
|
-
}
|
146
|
-
+ (bool) canUpdate{
|
147
|
-
return true;
|
148
|
-
}
|
149
|
-
+ (bool) canDelete{
|
150
|
-
return true;
|
151
|
-
}
|
152
|
-
|
153
|
-
|
154
|
-
- (void) saveWithDelegate:(id<RKObjectLoaderDelegate>)delegate
|
155
|
-
{
|
156
|
-
if ([self isNew])
|
157
|
-
{
|
158
|
-
NSAssert(self.class.canCreate, @"Object must allow create to be created");
|
159
|
-
NSLog(@"Creating new object\n%@", self);
|
160
|
-
// Save a new object
|
161
|
-
[[RKObjectManager sharedManager] postObject:self mapResponseWith:[self _mapper] delegate:delegate];
|
162
|
-
}else{
|
163
|
-
NSAssert(self.class.canUpdate, @"Object must allow update to be updated");
|
164
|
-
NSLog(@"Updating object\n%@", self);
|
165
|
-
// Update the object as it allready has an id
|
166
|
-
[[RKObjectManager sharedManager] putObject:self mapResponseWith:[self _mapper] delegate:delegate];
|
167
|
-
}
|
168
|
-
}
|
169
|
-
|
170
|
-
- (void)deleteWithDelegate:(id<RKObjectLoaderDelegate>)delegate
|
171
|
-
{
|
172
|
-
NSAssert(self.class.canDelete, @"Object must allow delete to be deleted");
|
173
|
-
[[RKObjectManager sharedManager] deleteObject:self mapResponseWith:[self _mapper] delegate:delegate];
|
174
|
-
}
|
175
|
-
|
176
|
-
// Find an instance by id
|
177
|
-
+ (void) find:(NSNumber *)id withDelegate:(id<RKObjectLoaderDelegate>)delegate
|
178
|
-
{
|
179
|
-
MSRestSerializable * instance = [[self alloc] init];
|
180
|
-
[instance setValue:id forKey:@"id"];
|
181
|
-
[[RKObjectManager sharedManager] getObject:instance
|
182
|
-
mapResponseWith:[instance _mapper]
|
183
|
-
delegate:delegate];
|
184
|
-
}
|
185
|
-
|
186
|
-
// Load collection
|
187
|
-
+ (void) loadCollectionWithDelegate:(id<RKObjectLoaderDelegate>)delegate
|
188
|
-
{
|
189
|
-
RKObjectManager * objectManager = [RKObjectManager sharedManager];
|
190
|
-
RKObjectMapping * mapping = [objectManager.mappingProvider
|
191
|
-
objectMappingForClass:self ];
|
192
|
-
|
193
|
-
[objectManager loadObjectsAtResourcePath:[self resourcePath]
|
194
|
-
objectMapping:mapping
|
195
|
-
delegate:delegate];
|
196
|
-
}
|
197
|
-
|
198
|
-
|
199
|
-
// Load collection with query
|
200
|
-
+ (void) loadCollectionThroughQuery:(MSRestSerializable *)mappableQueryObject
|
201
|
-
withDelegate:(id<RKObjectLoaderDelegate>)delegate
|
202
|
-
{
|
203
|
-
|
204
|
-
RKObjectManager * objectManager = [RKObjectManager sharedManager];
|
205
|
-
RKObjectMapping * mapping = [objectManager.mappingProvider
|
206
|
-
objectMappingForClass:self ];
|
207
|
-
|
208
|
-
|
209
|
-
// Append the dictionary to the resource as query parameters
|
210
|
-
NSString * resourcePath = RKPathAppendQueryParams([self resourcePath], [mappableQueryObject convertToDictionary]);
|
211
|
-
|
212
|
-
// Load the objects at the query
|
213
|
-
[objectManager loadObjectsAtResourcePath:resourcePath
|
214
|
-
objectMapping:mapping
|
215
|
-
delegate:delegate];
|
41
|
+
return (NSString *)[serializerFor(serializable)
|
42
|
+
serializedObjectForMIMEType:RKMIMETypeFormURLEncoded error: &error];
|
216
43
|
}
|
217
44
|
|
218
45
|
|
219
|
-
@end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: rest_kat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.10
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Brad Phelan
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-11-
|
13
|
+
date: 2011-11-28 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: kwalify
|
@@ -110,7 +110,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
110
110
|
requirements:
|
111
111
|
- - ">="
|
112
112
|
- !ruby/object:Gem::Version
|
113
|
-
hash: -
|
113
|
+
hash: -4151209479782223092
|
114
114
|
segments:
|
115
115
|
- 0
|
116
116
|
version: "0"
|