Objective-C JSON decoding with actionable errors
Objective-C
#import <Foundation/Foundation.h>
static id DecodeJSON(NSData *data, Class expected, NSError **error) {
NSError *parseError = nil;
id object = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (!object) {
NSNumber *offset = parseError.userInfo[NSJSONSerializationErrorIndex];
NSString *detail = offset ? [NSString stringWithFormat:@"invalid JSON at byte %@", offset] : @"invalid JSON payload";
if (error) *error = [NSError errorWithDomain:@"JSONError" code:parseError.code userInfo:@{NSLocalizedDescriptionKey: detail, NSUnderlyingErrorKey: parseError}];
return nil;
}
if (expected && ![object isKindOfClass:expected]) {
if (error) *error = [NSError errorWithDomain:@"JSONError" code:2 userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"expected %@, got %@", NSStringFromClass(expected), NSStringFromClass([object class])]}];
return nil;
}
return object;
}