Skip to content

Commit 19adc80

Browse files
author
Ricardo Pramana Suranta
committed
Merge remote-tracking branch 'upstream-josh/master'
2 parents 2dc5187 + 4b858e4 commit 19adc80

22 files changed

+418
-717
lines changed

Classes/JSONAPI.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,28 @@
1010

1111
#import "JSONAPIResource.h"
1212
#import "JSONAPIResourceFormatter.h"
13-
#import "JSONAPIResourceLinker.h"
1413
#import "JSONAPIResourceModeler.h"
14+
#import "JSONAPIErrorResource.h"
1515

1616
@interface JSONAPI : NSObject
1717

18-
@property (nonatomic, strong) NSDictionary *meta;
19-
@property (nonatomic, strong) NSDictionary *linked;
20-
@property (nonatomic, strong) NSError *error;
18+
@property (nonatomic, strong, readonly) NSDictionary *meta;
19+
@property (nonatomic, strong, readonly) id data;
20+
@property (nonatomic, strong, readonly) NSArray *errors;
2121

22-
+ (id)JSONAPIWithString:(NSString*)string;
23-
+ (id)JSONAPIWithDictionary:(NSDictionary*)dictionary;
22+
@property (readonly) id resource;
23+
@property (nonatomic, strong, readonly) NSArray *resources;
24+
@property (nonatomic, strong, readonly) NSDictionary *includedResources;
2425

25-
- (id)initWithString:(NSString*)string;
26-
- (id)initWithDictionary:(NSDictionary*)dictionary;
26+
@property (nonatomic, strong, readonly) NSError *internalError;
2727

28-
- (id)objectForKey:(NSString*)key;
29-
- (id)resourceForKey:(NSString*)key;
30-
- (NSArray*)resourcesForKey:(NSString*)key;
28+
// Initializers
29+
+ (instancetype)jsonAPIWithDictionary:(NSDictionary *)dictionary;
30+
+ (instancetype)jsonAPIWithString:(NSString *)string;
31+
- (instancetype)initWithDictionary:(NSDictionary*)dictionary;
32+
- (instancetype)initWithString:(NSString*)string;
33+
34+
- (id)includedResource:(id)ID withType:(NSString*)type;
35+
- (BOOL)hasErrors;
3136

3237
@end

Classes/JSONAPI.m

Lines changed: 79 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#import "JSONAPI.h"
1010

11+
#import "JSONAPIErrorResource.h"
12+
1113
@interface JSONAPI()
1214

1315
@property (nonatomic, strong) NSDictionary *dictionary;
@@ -16,28 +18,30 @@ @interface JSONAPI()
1618

1719
@implementation JSONAPI
1820

19-
#pragma mark - Init
21+
#pragma mark - Class
2022

21-
+ (id)JSONAPIWithString:(NSString*)string {
22-
return [[JSONAPI alloc] initWithString:string];
23+
+ (instancetype)jsonAPIWithDictionary:(NSDictionary *)dictionary {
24+
return [[JSONAPI alloc] initWithDictionary:dictionary];
2325
}
2426

25-
+ (id)JSONAPIWithDictionary:(NSDictionary*)dictionary {
26-
return [[JSONAPI alloc] initWithDictionary:dictionary];
27+
+ (instancetype)jsonAPIWithString:(NSString *)string {
28+
return [[JSONAPI alloc] initWithString:string];
2729
}
2830

29-
- (id)initWithString:(NSString*)string {
31+
#pragma mark - Instance
32+
33+
- (instancetype)initWithDictionary:(NSDictionary*)dictionary {
3034
self = [super init];
3135
if (self) {
32-
[self inflateWithString:string];
36+
[self inflateWithDictionary:dictionary];
3337
}
3438
return self;
3539
}
3640

37-
- (id)initWithDictionary:(NSDictionary*)dictionary {
41+
- (instancetype)initWithString:(NSString*)string {
3842
self = [super init];
3943
if (self) {
40-
[self inflateWithDictionary:dictionary];
44+
[self inflateWithString:string];
4145
}
4246
return self;
4347
}
@@ -48,53 +52,24 @@ - (void)inflateWithString:(NSString*)string {
4852
if ([json isKindOfClass:[NSDictionary class]] == YES) {
4953
[self inflateWithDictionary:json];
5054
} else {
51-
_error = [NSError errorWithDomain:@"Could not parse JSON" code:0 userInfo:nil];
55+
_internalError = [NSError errorWithDomain:@"Could not parse JSON" code:0 userInfo:nil];
5256
}
5357
}
5458

5559
#pragma mark - Resources
5660

57-
- (id)objectForKey:(NSString*)key {
58-
return [_dictionary objectForKey:key];
61+
- (id)resource {
62+
return _resources.firstObject;
5963
}
6064

61-
- (id)resourceForKey:(NSString*)key {
62-
if ([key isEqualToString:@"meta"] == YES || [key isEqualToString:@"linked"] == YES) {
63-
return nil;
64-
}
65-
66-
NSDictionary *rawResource = [_dictionary objectForKey:key];
67-
JSONAPIResource *resource = nil;
68-
if ([rawResource isKindOfClass:[NSDictionary class]] == YES) {
69-
Class c = [JSONAPIResourceModeler resourceForLinkedType:[JSONAPIResourceLinker linkedType:key]];
70-
resource = [JSONAPIResource jsonAPIResource:rawResource withLinked:self.linked withClass:c];
71-
}
72-
73-
// Fall back to first element in array
74-
if (resource == nil) {
75-
id resources = [self resourcesForKey:key];
76-
if ([resources isKindOfClass:[NSArray class]] == YES) {
77-
return [resources firstObject];
78-
}
79-
}
80-
81-
return resource;
82-
65+
- (id)includedResource:(id)ID withType:(NSString *)type {
66+
if (ID == nil) return nil;
67+
if (type == nil) return nil;
68+
return _includedResources[type][ID];
8369
}
8470

85-
- (NSArray*)resourcesForKey:(NSString*)key {
86-
if ([key isEqualToString:@"meta"] == YES || [key isEqualToString:@"linked"] == YES) {
87-
return nil;
88-
}
89-
90-
NSArray *rawResources = [_dictionary objectForKey:key];
91-
NSArray *resources = nil;
92-
if ([rawResources isKindOfClass:[NSArray class]] == YES) {
93-
Class c = [JSONAPIResourceModeler resourceForLinkedType:[JSONAPIResourceLinker linkedType:key]];
94-
resources = [JSONAPIResource jsonAPIResources:rawResources withLinked:self.linked withClass:c];
95-
}
96-
97-
return resources;
71+
- (BOOL)hasErrors {
72+
return _errors.count > 0;
9873
}
9974

10075
- (NSMutableArray *)arrayFromDictionary:(NSDictionary *)dictionary withKey:(NSString *)key
@@ -114,50 +89,77 @@ - (NSMutableArray *)arrayFromDictionary:(NSDictionary *)dictionary withKey:(NSSt
11489
#pragma mark - Private
11590

11691
- (void)inflateWithDictionary:(NSDictionary*)dictionary {
117-
// Sets dictionary
92+
93+
// Sets internal dictionary
11894
_dictionary = dictionary;
11995

12096
// Sets meta
121-
_meta = [dictionary objectForKey:@"meta"];
97+
_meta = dictionary[@"meta"];
12298
if ([_meta isKindOfClass:[NSDictionary class]] == NO) {
12399
_meta = nil;
124100
}
125101

126-
// Sets linked
127-
NSMutableDictionary *creatingLinked = [NSMutableDictionary dictionary];
128-
NSDictionary *rawLinked = [dictionary objectForKey:@"linked"];
129-
if ([rawLinked isKindOfClass:[NSDictionary class]] == YES) {
102+
// Parse resources
103+
_data = _dictionary[@"data"];
104+
105+
NSMutableArray *resources = @[].mutableCopy;
106+
if ([_data isKindOfClass:[NSArray class]] == YES) {
107+
108+
NSArray *dataArray = (NSArray*) _data;
109+
for (NSDictionary *data in dataArray) {
110+
id resource = [self inflateResourceData:data];
111+
if (resource) [resources addObject:resource];
112+
}
130113

131-
NSMutableArray *linkedToLinkWithLinked = [NSMutableArray array];
114+
} else if ([_data isKindOfClass:[NSDictionary class]] == YES) {
115+
id resource = [self inflateResourceData:_data];
116+
if (resource) [resources addObject:resource];
117+
}
118+
_resources = resources;
119+
120+
// Parses included resources
121+
NSArray *included = _dictionary[@"included"];
122+
NSMutableDictionary *includedResources = @{}.mutableCopy;
123+
for (NSDictionary *data in included) {
132124

133-
// Loops through linked arrays
134-
for (NSString *key in rawLinked.allKeys) {
135-
NSArray *value = [self arrayFromDictionary:rawLinked withKey:key];
136-
137-
if ([value isKindOfClass:[NSArray class]] == YES) {
138-
NSMutableDictionary *resources = [NSMutableDictionary dictionary];
139-
for (NSDictionary *resourceDictionary in value) {
140-
Class c = [JSONAPIResourceModeler resourceForLinkedType:[JSONAPIResourceLinker linkedType:key]];
141-
JSONAPIResource *resource = [JSONAPIResource jsonAPIResource:resourceDictionary withLinked:nil withClass:c];
142-
if (resource.ID != nil) {
143-
[resources setObject:resource forKey:resource.ID];
144-
[linkedToLinkWithLinked addObject:resource];
145-
}
146-
}
147-
[creatingLinked setObject:resources forKey:key];
148-
149-
}
125+
JSONAPIResource *resource = [self inflateResourceData:data];
126+
if (resource) {
127+
128+
NSMutableDictionary *typeDict = includedResources[resource.type] ?: @{}.mutableCopy;
129+
typeDict[resource.ID] = resource;
150130

131+
includedResources[resource.type] = typeDict;
151132
}
152-
153-
// Linked the linked
154-
for (JSONAPIResource *resource in linkedToLinkWithLinked) {
155-
[resource linkLinks:creatingLinked];
133+
}
134+
_includedResources = includedResources;
135+
136+
// Link included with included
137+
// TODO: Need to look into / stop circular references
138+
for (NSDictionary *typeIncluded in _includedResources.allValues) {
139+
for (JSONAPIResource *resource in typeIncluded.allValues) {
140+
[resource linkWithIncluded:self];
156141
}
157-
158142
}
159143

160-
_linked = creatingLinked;
144+
// Link data with included
145+
for (JSONAPIResource *resource in _resources) {
146+
[resource linkWithIncluded:self];
147+
}
148+
149+
// Parse errors
150+
NSMutableArray *errors = @[].mutableCopy;
151+
NSLog(@"ERROS - %@", _dictionary[@"errors"]);
152+
for (NSDictionary *data in _dictionary[@"errors"]) {
153+
154+
JSONAPIErrorResource *resource = [[JSONAPIErrorResource alloc] initWithDictionary:data];
155+
NSLog(@"Error resource - %@", resource);
156+
if (resource) [errors addObject:resource];
157+
}
158+
_errors = errors;
159+
}
160+
161+
- (id)inflateResourceData:(NSDictionary*)data {
162+
return [JSONAPIResource jsonAPIResource:data];
161163
}
162164

163165
@end

Classes/JSONAPIErrorResource.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// JSONAPIErrorResource.h
3+
// JSONAPI
4+
//
5+
// Created by Josh Holtz on 3/17/15.
6+
// Copyright (c) 2015 Josh Holtz. All rights reserved.
7+
//
8+
9+
#import "JSONAPIResource.h"
10+
11+
@interface JSONAPIErrorResource : JSONAPIResource
12+
13+
@property (nonatomic, strong) NSString *status;
14+
@property (nonatomic, strong) NSString *code;
15+
@property (nonatomic, strong) NSString *title;
16+
@property (nonatomic, strong) NSString *detail;
17+
@property (nonatomic, strong) NSArray *links;
18+
@property (nonatomic, strong) NSArray *paths;
19+
20+
@end

Classes/JSONAPIErrorResource.m

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// JSONAPIErrorResource.m
3+
// JSONAPI
4+
//
5+
// Created by Josh Holtz on 3/17/15.
6+
// Copyright (c) 2015 Josh Holtz. All rights reserved.
7+
//
8+
9+
#import "JSONAPIErrorResource.h"
10+
11+
@implementation JSONAPIErrorResource
12+
13+
- (NSDictionary *)mapKeysToProperties {
14+
return @{
15+
@"status" : @"status",
16+
@"code" : @"code",
17+
@"title" : @"title",
18+
@"detail" : @"detail",
19+
@"paths" : @"paths",
20+
};
21+
}
22+
23+
@end

Classes/JSONAPIResource.h

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,20 @@
88

99
#import <Foundation/Foundation.h>
1010

11+
@class JSONAPI;
12+
1113
@interface JSONAPIResource : NSObject<NSCopying, NSCoding>
1214

1315
@property (nonatomic, strong) id ID;
14-
@property (nonatomic, strong) NSString *href;
15-
@property (nonatomic, strong) NSDictionary *links;
16-
17-
+ (NSArray*)jsonAPIResources:(NSArray*)array withLinked:(NSDictionary*)linked;
18-
+ (NSArray*)jsonAPIResources:(NSArray*)array withLinked:(NSDictionary*)linked withClass:(Class)resourceObjectClass;
19-
20-
+ (id)jsonAPIResource:(NSDictionary*)dictionary withLinked:(NSDictionary*)linked;
21-
+ (id)jsonAPIResource:(NSDictionary*)dictionary withLinked:(NSDictionary*)linked withClass:(Class)resourceObjectClass;
22-
23-
- (id)initWithDictionary:(NSDictionary*)dict withLinked:(NSDictionary*)linked;
24-
- (void)setWithDictionary:(NSDictionary*)dict;
16+
@property (nonatomic, strong) NSString *type;
17+
@property (nonatomic, strong) id links;
2518

26-
- (id)objectForKey:(NSString*)key;
27-
- (id)linkedResourceForKey:(NSString*)key;
19+
+ (id)jsonAPIResource:(NSDictionary*)dictionary;
20+
+ (NSArray*)jsonAPIResources:(NSArray*)array;
2821

29-
- (void)linkLinks:(NSDictionary*)linked;
22+
- (id)initWithDictionary:(NSDictionary*)dict;
3023

3124
- (NSDictionary *)mapKeysToProperties;
25+
- (void)linkWithIncluded:(JSONAPI*)jsonAPI;
3226

3327
@end

0 commit comments

Comments
 (0)