Skip to content

Commit 41d6ada

Browse files
author
Josh Holtz
committed
Merge pull request #5 from joshdholtz/fun-changes
Fun changes
2 parents 7c00eff + 76d55f2 commit 41d6ada

File tree

16 files changed

+372
-177
lines changed

16 files changed

+372
-177
lines changed

Classes/JSONAPI.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#import <Foundation/Foundation.h>
1010

1111
#import "JSONAPIResource.h"
12+
#import "JSONAPIResourceFormatter.h"
1213
#import "JSONAPIResourceLinker.h"
1314
#import "JSONAPIResourceModeler.h"
1415

Classes/JSONAPIResource.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#import <Foundation/Foundation.h>
1010

11-
@interface JSONAPIResource : NSObject
11+
@interface JSONAPIResource : NSObject<NSCopying, NSCoding>
1212

1313
@property (nonatomic, strong) id ID;
1414
@property (nonatomic, strong) NSString *href;

Classes/JSONAPIResource.m

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@
88

99
#import "JSONAPIResource.h"
1010

11+
#import "JSONAPIResourceFormatter.h"
1112
#import "JSONAPIResourceLinker.h"
1213

14+
#import <objc/runtime.h>
15+
#import <objc/message.h>
16+
1317
#pragma mark - JSONAPIResource
1418

1519
@interface JSONAPIResource()
@@ -21,6 +25,9 @@ @interface JSONAPIResource()
2125

2226
@implementation JSONAPIResource
2327

28+
#pragma mark -
29+
#pragma mark - Class Methods
30+
2431
+ (NSArray*)jsonAPIResources:(NSArray*)array withLinked:(NSDictionary*)linked {
2532
return [JSONAPIResource jsonAPIResources:array withLinked:linked withClass:[self class]];
2633
}
@@ -50,6 +57,9 @@ + (id)jsonAPIResource:(NSDictionary*)dictionary withLinked:(NSDictionary*)linked
5057
return [[resourceObjectClass alloc] initWithDictionary:dictionary withLinked:linked];
5158
}
5259

60+
#pragma mark -
61+
#pragma mark - Instance Methods
62+
5363
- (id)init {
5464
self = [super init];
5565
if (self) {
@@ -107,7 +117,10 @@ - (void)setWithDictionary:(NSDictionary*)dict {
107117
if (inflateRange.location != NSNotFound) {
108118

109119
} else if (formatRange.location != NSNotFound) {
110-
120+
NSString *formatFunction = [property substringToIndex:formatRange.location];
121+
property = [property substringFromIndex:(formatRange.location+1)];
122+
123+
[self setValue:[JSONAPIResourceFormatter performFormatBlock:[dict objectForKey:key] withName:formatFunction] forKey:property ];
111124
} else {
112125
[self setValue:[dict objectForKey:key] forKey:property ];
113126
}
@@ -164,6 +177,7 @@ - (void)linkLinks:(NSDictionary*)linked {
164177

165178
id resource = [self linkedResourceForKey:linkedResource];
166179
if (resource != nil) {
180+
167181
@try {
168182
[self setValue:resource forKey:propertyName];
169183
}
@@ -176,4 +190,102 @@ - (void)linkLinks:(NSDictionary*)linked {
176190
}
177191
}
178192

193+
#pragma mark - NSCopying
194+
195+
- (id)copyWithZone:(NSZone *)zone {
196+
id copy = [[[self class] alloc] initWithDictionary:[self.__dictionary copyWithZone:zone] withLinked:nil];
197+
198+
if (copy) {
199+
// Copy NSObject subclasses
200+
NSLog(@"__resourceLinks - %@", self.__resourceLinks);
201+
[copy set__resourceLinks:[self.__resourceLinks copyWithZone:zone]];
202+
203+
// Link links for mapped key to properties
204+
for (NSString *key in [copy __resourceLinks]) {
205+
@try {
206+
[copy setValue:[[copy __resourceLinks] objectForKey:key] forKey:key];
207+
}
208+
@catch (NSException *exception) {
209+
NSLog(@"JSONAPIResource Warning - %@", [exception description]);
210+
}
211+
}
212+
213+
}
214+
215+
return copy;
216+
}
217+
218+
#pragma mark - NSCoding
219+
220+
- (NSArray *)propertyKeys
221+
{
222+
NSMutableArray *array = [NSMutableArray array];
223+
Class class = [self class];
224+
while (class != [NSObject class])
225+
{
226+
unsigned int propertyCount;
227+
objc_property_t *properties = class_copyPropertyList(class, &propertyCount);
228+
for (int i = 0; i < propertyCount; i++)
229+
{
230+
//get property
231+
objc_property_t property = properties[i];
232+
const char *propertyName = property_getName(property);
233+
NSString *key = [NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding];
234+
235+
//check if read-only
236+
BOOL readonly = NO;
237+
const char *attributes = property_getAttributes(property);
238+
NSString *encoding = [NSString stringWithCString:attributes encoding:NSUTF8StringEncoding];
239+
if ([[encoding componentsSeparatedByString:@","] containsObject:@"R"])
240+
{
241+
readonly = YES;
242+
243+
//see if there is a backing ivar with a KVC-compliant name
244+
NSRange iVarRange = [encoding rangeOfString:@",V"];
245+
if (iVarRange.location != NSNotFound)
246+
{
247+
NSString *iVarName = [encoding substringFromIndex:iVarRange.location + 2];
248+
if ([iVarName isEqualToString:key] ||
249+
[iVarName isEqualToString:[@"_" stringByAppendingString:key]])
250+
{
251+
//setValue:forKey: will still work
252+
readonly = NO;
253+
}
254+
}
255+
}
256+
257+
if (!readonly)
258+
{
259+
//exclude read-only properties
260+
[array addObject:key];
261+
}
262+
}
263+
free(properties);
264+
class = [class superclass];
265+
}
266+
return array;
267+
}
268+
269+
- (id)initWithCoder:(NSCoder *)aDecoder
270+
{
271+
if ((self = [self init]))
272+
{
273+
for (NSString *key in [self propertyKeys])
274+
{
275+
id value = [aDecoder decodeObjectForKey:key];
276+
[self setValue:value forKey:key];
277+
}
278+
}
279+
return self;
280+
}
281+
282+
- (void)encodeWithCoder:(NSCoder *)aCoder
283+
{
284+
for (NSString *key in [self propertyKeys])
285+
{
286+
id value = [self valueForKey:key];
287+
[aCoder encodeObject:value forKey:key];
288+
}
289+
}
290+
179291
@end

Classes/JSONAPIResourceFormatter.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// JSONAPIResourceFormatter.h
3+
// JSONAPI
4+
//
5+
// Created by Josh Holtz on 7/9/14.
6+
// Copyright (c) 2014 Josh Holtz. All rights reserved.
7+
//
8+
9+
#import <Foundation/Foundation.h>
10+
11+
@interface JSONAPIResourceFormatter : NSObject
12+
13+
+ (void)registerFormat:(NSString*)name withBlock:(id(^)(id jsonValue))block;
14+
+ (id)performFormatBlock:(NSString*)value withName:(NSString*)name;
15+
16+
@end

Classes/JSONAPIResourceFormatter.m

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//
2+
// JSONAPIResourceFormatter.m
3+
// JSONAPI
4+
//
5+
// Created by Josh Holtz on 7/9/14.
6+
// Copyright (c) 2014 Josh Holtz. All rights reserved.
7+
//
8+
9+
#import "JSONAPIResourceFormatter.h"
10+
11+
@interface JSONAPIResourceFormatter()
12+
13+
@property (nonatomic, strong) NSMutableDictionary *formatBlocks;
14+
15+
@end
16+
17+
@implementation JSONAPIResourceFormatter
18+
19+
+ (instancetype)sharedFormatter {
20+
static JSONAPIResourceFormatter *_sharedFormatter = nil;
21+
static dispatch_once_t onceToken;
22+
dispatch_once(&onceToken, ^{
23+
_sharedFormatter = [[JSONAPIResourceFormatter alloc] init];
24+
});
25+
26+
return _sharedFormatter;
27+
}
28+
29+
- (id)init {
30+
self = [super init];
31+
if (self) {
32+
self.formatBlocks = @{}.mutableCopy;
33+
}
34+
return self;
35+
}
36+
37+
+ (void)registerFormat:(NSString*)name withBlock:(id(^)(id jsonValue))block {
38+
[[JSONAPIResourceFormatter sharedFormatter].formatBlocks setObject:[block copy] forKey:name];
39+
}
40+
41+
+ (id)performFormatBlock:(NSString*)value withName:(NSString*)name {
42+
id(^block)(NSString *);
43+
block = [[JSONAPIResourceFormatter sharedFormatter].formatBlocks objectForKey:name];
44+
if (block != nil) {
45+
return block(value);
46+
} else {
47+
return nil;
48+
}
49+
}
50+
51+
@end

Project/JSONAPI.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
03A055E61868E038004807F0 /* JSONAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 03A055E51868E038004807F0 /* JSONAPITests.m */; };
3131
03A055F71868E08A004807F0 /* JSONAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = 03A055F41868E08A004807F0 /* JSONAPI.m */; };
3232
03A055F81868E08A004807F0 /* JSONAPI.podspec in Resources */ = {isa = PBXBuildFile; fileRef = 03A055F51868E08A004807F0 /* JSONAPI.podspec */; };
33+
03A9ED58196DEF9B00E61E2E /* JSONAPIResourceFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 03A9ED57196DEF9B00E61E2E /* JSONAPIResourceFormatter.m */; };
3334
/* End PBXBuildFile section */
3435

3536
/* Begin PBXContainerItemProxy section */
@@ -78,6 +79,8 @@
7879
03A055F31868E08A004807F0 /* JSONAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONAPI.h; sourceTree = "<group>"; };
7980
03A055F41868E08A004807F0 /* JSONAPI.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSONAPI.m; sourceTree = "<group>"; };
8081
03A055F51868E08A004807F0 /* JSONAPI.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = JSONAPI.podspec; path = ../JSONAPI.podspec; sourceTree = "<group>"; };
82+
03A9ED56196DEF9B00E61E2E /* JSONAPIResourceFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONAPIResourceFormatter.h; sourceTree = "<group>"; };
83+
03A9ED57196DEF9B00E61E2E /* JSONAPIResourceFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSONAPIResourceFormatter.m; sourceTree = "<group>"; };
8184
/* End PBXFileReference section */
8285

8386
/* Begin PBXFrameworksBuildPhase section */
@@ -201,6 +204,8 @@
201204
03A055F41868E08A004807F0 /* JSONAPI.m */,
202205
033A6C5D18695CD2001CF9FA /* JSONAPIResource.h */,
203206
033A6C5E18695CD2001CF9FA /* JSONAPIResource.m */,
207+
03A9ED56196DEF9B00E61E2E /* JSONAPIResourceFormatter.h */,
208+
03A9ED57196DEF9B00E61E2E /* JSONAPIResourceFormatter.m */,
204209
0386643B186A0DAD00985CEC /* JSONAPIResourceLinker.h */,
205210
0386643C186A0DAD00985CEC /* JSONAPIResourceLinker.m */,
206211
0386644C186A8DA000985CEC /* JSONAPIResourceModeler.h */,
@@ -316,6 +321,7 @@
316321
03A055F71868E08A004807F0 /* JSONAPI.m in Sources */,
317322
033A6C5F18695CD2001CF9FA /* JSONAPIResource.m in Sources */,
318323
03866454186A94B700985CEC /* CommentResource.m in Sources */,
324+
03A9ED58196DEF9B00E61E2E /* JSONAPIResourceFormatter.m in Sources */,
319325
03A055CB1868E038004807F0 /* AppDelegate.m in Sources */,
320326
0386644E186A8DA000985CEC /* JSONAPIResourceModeler.m in Sources */,
321327
03A055C71868E038004807F0 /* main.m in Sources */,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
6+
<false/>
7+
<key>IDESourceControlProjectIdentifier</key>
8+
<string>DA49755E-FD70-48BA-8E28-2C90B0ABED83</string>
9+
<key>IDESourceControlProjectName</key>
10+
<string>JSONAPI</string>
11+
<key>IDESourceControlProjectOriginsDictionary</key>
12+
<dict>
13+
<key>7EE6692C-FAB2-484E-B1C6-2C33369BAE38</key>
14+
<string>ssh://github.com/joshdholtz/jsonapi-ios.git</string>
15+
</dict>
16+
<key>IDESourceControlProjectPath</key>
17+
<string>Project/JSONAPI.xcworkspace</string>
18+
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
19+
<dict>
20+
<key>7EE6692C-FAB2-484E-B1C6-2C33369BAE38</key>
21+
<string>../..</string>
22+
</dict>
23+
<key>IDESourceControlProjectURL</key>
24+
<string>ssh://github.com/joshdholtz/jsonapi-ios.git</string>
25+
<key>IDESourceControlProjectVersion</key>
26+
<integer>110</integer>
27+
<key>IDESourceControlProjectWCCIdentifier</key>
28+
<string>7EE6692C-FAB2-484E-B1C6-2C33369BAE38</string>
29+
<key>IDESourceControlProjectWCConfigurations</key>
30+
<array>
31+
<dict>
32+
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
33+
<string>public.vcs.git</string>
34+
<key>IDESourceControlWCCIdentifierKey</key>
35+
<string>7EE6692C-FAB2-484E-B1C6-2C33369BAE38</string>
36+
<key>IDESourceControlWCCName</key>
37+
<string>JSONAPI</string>
38+
</dict>
39+
</array>
40+
</dict>
41+
</plist>

Project/JSONAPI/CommentResource.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
@interface CommentResource : JSONAPIResource
1212

13-
@property (nonatomic, strong) NSString *mapText;
14-
15-
- (NSString*)text;
13+
@property (nonatomic, strong) NSString *text;
1614

1715
@end

Project/JSONAPI/CommentResource.m

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,9 @@
1010

1111
@implementation CommentResource
1212

13-
- (NSString *)text {
14-
return [self objectForKey:@"text"];
15-
}
16-
1713
- (NSDictionary *)mapKeysToProperties {
1814
return @{
19-
@"text" : @"mapText"
15+
@"text" : @"text"
2016
};
2117
}
2218

Project/JSONAPI/PeopleResource.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
@interface PeopleResource : JSONAPIResource
1212

13-
@property (nonatomic, strong) NSString *mapName;
14-
15-
- (NSString*)name;
13+
@property (nonatomic, strong) NSString *name;
1614

1715
@end

0 commit comments

Comments
 (0)