|
1 | 1 | // |
2 | 2 | // JSONModel.m |
3 | 3 | // |
4 | | -// @version 0.9.3 |
| 4 | +// @version 0.10.0 |
5 | 5 | // @author Marin Todorov, http://www.touch-code-magazine.com |
6 | 6 | // |
7 | 7 |
|
|
20 | 20 |
|
21 | 21 |
|
22 | 22 | #import <objc/runtime.h> |
| 23 | +#import <objc/message.h> |
23 | 24 |
|
24 | 25 | #import "JSONModel.h" |
25 | 26 | #import "JSONModelClassProperty.h" |
@@ -175,14 +176,14 @@ -(id)initWithDictionary:(NSDictionary*)dict error:(NSError**)err |
175 | 176 | NSString* transformedName = nil; |
176 | 177 |
|
177 | 178 | //loop over the required properties list |
178 | | - for (NSString* requiredPropertyName in requiredProperties) { |
| 179 | + for (JSONModelClassProperty* property in [self __properties__]) { |
179 | 180 |
|
180 | 181 | //get the mapped key path |
181 | | - transformedName = keyMapper.modelToJSONKeyBlock(requiredPropertyName); |
| 182 | + transformedName = keyMapper.modelToJSONKeyBlock(property.name); |
182 | 183 |
|
183 | 184 | //chek if exists and if so, add to incoming keys |
184 | 185 | if ([dict valueForKeyPath:transformedName]) { |
185 | | - [transformedIncomingKeys addObject: requiredPropertyName]; |
| 186 | + [transformedIncomingKeys addObject: property.name]; |
186 | 187 | } |
187 | 188 | } |
188 | 189 |
|
@@ -220,9 +221,16 @@ -(id)initWithDictionary:(NSDictionary*)dict error:(NSError**)err |
220 | 221 | id jsonValue = [dict valueForKeyPath: jsonKeyPath]; |
221 | 222 |
|
222 | 223 | //check for Optional properties |
223 | | - if (isNull(jsonValue) && property.isOptional==YES) { |
| 224 | + if (isNull(jsonValue)) { |
224 | 225 | //skip this property, continue with next property |
225 | | - continue; |
| 226 | + if (property.isOptional==YES) continue; |
| 227 | + |
| 228 | + //null value for required property |
| 229 | + NSString* msg = [NSString stringWithFormat:@"Value of required model key %@ is null", property.name]; |
| 230 | + JSONModelError* dataErr = [JSONModelError errorInvalidDataWithMessage:msg]; |
| 231 | + *err = [dataErr errorByPrependingKeyPathComponent:property.name]; |
| 232 | + |
| 233 | + return nil; |
226 | 234 | } |
227 | 235 |
|
228 | 236 | Class jsonValueClass = [jsonValue class]; |
@@ -331,6 +339,9 @@ -(id)initWithDictionary:(NSDictionary*)dict error:(NSError**)err |
331 | 339 | || |
332 | 340 | //the property is mutable |
333 | 341 | property.isMutable |
| 342 | + || |
| 343 | + //custom struct property |
| 344 | + property.structName |
334 | 345 | ) { |
335 | 346 |
|
336 | 347 | // searched around the web how to do this better |
@@ -723,10 +734,8 @@ -(BOOL)__customSetValue:(id<NSObject>)value forProperty:(JSONModelClassProperty* |
723 | 734 |
|
724 | 735 | if (property.setterType==kCustom) { |
725 | 736 | //call the custom setter |
726 | | - #pragma clang diagnostic push |
727 | | - #pragma clang diagnostic ignored "-Warc-performSelector-leaks" |
728 | | - [self performSelector:property.customSetter withObject:value]; |
729 | | - #pragma clang diagnostic pop |
| 737 | + //https://github.com/steipete |
| 738 | + ((void (*) (id, SEL, id))objc_msgSend)(self, property.customSetter, value); |
730 | 739 | return YES; |
731 | 740 | } |
732 | 741 |
|
@@ -756,9 +765,7 @@ -(BOOL)__customGetValue:(id<NSObject>*)value forProperty:(JSONModelClassProperty |
756 | 765 | //call the custom getter |
757 | 766 | #pragma clang diagnostic push |
758 | 767 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" |
759 | | - |
760 | 768 | *value = [self performSelector:property.customGetter withObject:nil]; |
761 | | - |
762 | 769 | #pragma clang diagnostic pop |
763 | 770 | return YES; |
764 | 771 | } |
|
0 commit comments