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,102 +52,100 @@ - (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#pragma mark - Private
10176
10277- (void )inflateWithDictionary : (NSDictionary *)dictionary {
103- // Sets dictionary
78+
79+ // Sets internal dictionary
10480 _dictionary = dictionary;
10581
10682 // Sets meta
107- _meta = [ dictionary objectForKey: @" meta" ];
83+ _meta = dictionary[ @" meta" ];
10884 if ([_meta isKindOfClass: [NSDictionary class ]] == NO ) {
10985 _meta = nil ;
11086 }
11187
112- // Sets linked
113- NSMutableDictionary *creatingLinked = [NSMutableDictionary dictionary ];
114- NSDictionary *rawLinked = [dictionary objectForKey: @" linked" ];
115- if ([rawLinked isKindOfClass: [NSDictionary class ]] == YES ) {
88+ // Parse resources
89+ _data = _dictionary[@" data" ];
90+
91+ NSMutableArray *resources = @[].mutableCopy ;
92+ if ([_data isKindOfClass: [NSArray class ]] == YES ) {
93+
94+ NSArray *dataArray = (NSArray *) _data;
95+ for (NSDictionary *data in dataArray) {
96+ id resource = [self inflateResourceData: data];
97+ if (resource) [resources addObject: resource];
98+ }
11699
117- NSMutableArray *linkedToLinkWithLinked = [NSMutableArray array ];
100+ } else if ([_data isKindOfClass: [NSDictionary class ]] == YES ) {
101+ id resource = [self inflateResourceData: _data];
102+ if (resource) [resources addObject: resource];
103+ }
104+ _resources = resources;
105+
106+ // Parses included resources
107+ NSArray *included = _dictionary[@" included" ];
108+ NSMutableDictionary *includedResources = @{}.mutableCopy ;
109+ for (NSDictionary *data in included) {
118110
119- // Loops through linked arrays
120- for (NSString *key in rawLinked.allKeys ) {
121- NSArray *value = [rawLinked objectForKey: key];
122-
123- if ([value isKindOfClass: [NSArray class ]] == YES ) {
124- NSMutableDictionary *resources = [NSMutableDictionary dictionary ];
125- for (NSDictionary *resourceDictionary in value) {
126- Class c = [JSONAPIResourceModeler resourceForLinkedType: [JSONAPIResourceLinker linkedType: key]];
127- JSONAPIResource *resource = [JSONAPIResource jsonAPIResource: resourceDictionary withLinked: nil withClass: c];
128- if (resource.ID != nil ) {
129- [resources setObject: resource forKey: resource.ID];
130- [linkedToLinkWithLinked addObject: resource];
131- }
132- }
133- [creatingLinked setObject: resources forKey: key];
134-
135- }
111+ JSONAPIResource *resource = [self inflateResourceData: data];
112+ if (resource) {
113+
114+ NSMutableDictionary *typeDict = includedResources[resource.type] ?: @{}.mutableCopy ;
115+ typeDict[resource.ID] = resource;
136116
117+ includedResources[resource.type] = typeDict;
137118 }
138-
139- // Linked the linked
140- for (JSONAPIResource *resource in linkedToLinkWithLinked) {
141- [resource linkLinks: creatingLinked];
119+ }
120+ _includedResources = includedResources;
121+
122+ // Link included with included
123+ // TODO: Need to look into / stop circular references
124+ for (NSDictionary *typeIncluded in _includedResources.allValues ) {
125+ for (JSONAPIResource *resource in typeIncluded.allValues ) {
126+ [resource linkWithIncluded: self ];
142127 }
143-
144128 }
145129
146- _linked = creatingLinked;
130+ // Link data with included
131+ for (JSONAPIResource *resource in _resources) {
132+ [resource linkWithIncluded: self ];
133+ }
134+
135+ // Parse errors
136+ NSMutableArray *errors = @[].mutableCopy ;
137+ NSLog (@" ERROS - %@ " , _dictionary[@" errors" ]);
138+ for (NSDictionary *data in _dictionary[@" errors" ]) {
139+
140+ JSONAPIErrorResource *resource = [[JSONAPIErrorResource alloc ] initWithDictionary: data];
141+ NSLog (@" Error resource - %@ " , resource);
142+ if (resource) [errors addObject: resource];
143+ }
144+ _errors = errors;
145+ }
146+
147+ - (id )inflateResourceData : (NSDictionary *)data {
148+ return [JSONAPIResource jsonAPIResource: data];
147149}
148150
149151@end
0 commit comments