Permalink
Browse files

Added more durable parsing of arrays vs single values for the xml ada…

…pter
  • Loading branch information...
1 parent bec5072 commit b323ff55437cf24aa69de92b3ccb5fc72300f5c1 @sleroux sleroux committed May 30, 2014
Showing with 32 additions and 4 deletions.
  1. +3 −0 Mantle/MTLReflection.h
  2. +8 −0 Mantle/MTLReflection.m
  3. +21 −4 Mantle/MTLXMLAdapter.m
@@ -29,3 +29,6 @@ SEL MTLSelectorWithKeyPattern(NSString *key, const char *suffix) __attribute__((
// Returns a selector, or NULL if the input strings cannot form a valid
// selector.
SEL MTLSelectorWithCapitalizedKeyPattern(const char *prefix, NSString *key, const char *suffix) __attribute__((pure, nonnull(1, 2, 3)));
+
+
+Class MTLClassForPropertyOfClass(NSString *propertyName, Class modelClass);
@@ -7,6 +7,7 @@
//
#import "MTLReflection.h"
+#import "EXTRuntimeExtensions.h"
#import <objc/runtime.h>
SEL MTLSelectorWithKeyPattern(NSString *key, const char *suffix) {
@@ -48,3 +49,10 @@ SEL MTLSelectorWithCapitalizedKeyPattern(const char *prefix, NSString *key, cons
return sel_registerName(selector);
}
+
+Class MTLClassForPropertyOfClass(NSString *propertyName, Class modelClass)
+{
+ objc_property_t property = class_getProperty(modelClass, [propertyName UTF8String]);
+ mtl_propertyAttributes *mtlPropertyAttributes = mtl_copyPropertyAttributes(property);
+ return mtlPropertyAttributes->objectClass;
+}
@@ -4,6 +4,9 @@
#import "MTLReflection.h"
#import "MTLXMLElement.h"
+#import <objc/runtime.h>
+#import "EXTRuntimeExtensions.h"
+
NSString * const MTLXMLAdapterErrorDomain = @"MTLXMLAdapterErrorDomain";
const NSInteger MTLXMLAdapterErrorNoClassFound = 2;
const NSInteger MTLXMLAdapterErrorInvalidXPathMapping = 3;
@@ -89,13 +92,27 @@ - (id)initWithXMLElement:(MTLXMLElement *)xmlDoc modelClass:(Class)modelClass er
if (XMLXPath == nil) continue;
NSArray *xpathResults = [xmlDoc xpathQuery:XMLXPath error:error];
+ if (xpathResults.count == 0) continue;
if (error != NULL && *error) return nil;
- id value;
- if (xpathResults.count > 0) {
- value = [xpathResults[0] value];
+ Class propertyClass = MTLClassForPropertyOfClass(propertyKey, modelClass);
+ id value;
+ // If we are binding the value to an array, send the list of results. If not, just send the first one as
+ // the model expects a single value to be returned from the xpath query
+ if ([propertyClass isSubclassOfClass:NSArray.class]) {
+ value = xpathResults;
} else {
- value = nil;
+ if (xpathResults.count > 1 && error != NULL) {
+ NSDictionary *userInfo = @{
+ NSLocalizedDescriptionKey: NSLocalizedString(@"Ambigious XPath", nil),
+ NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"%1$@ could not be parsed because the XPath mapping (%@) is ambigious (returned %d results)", nil), propertyKey, modelClass]
+ };
+
+ *error = [NSError errorWithDomain:MTLXMLAdapterErrorDomain code:MTLXMLAdapterErrorAmbiguousXPath userInfo:userInfo];
+ return nil;
+ }
+
+ value = [xpathResults[0] value];
}
if (value == nil) continue;

0 comments on commit b323ff5

Please sign in to comment.