├── .gitignore ├── LICENSE ├── NSDictionary+Accessors.h ├── NSDictionary+Accessors.m ├── NSDictionary+Accessors.podspec └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | *.xccheckout 19 | 20 | #CocoaPods 21 | Pods 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Allen Hsu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /NSDictionary+Accessors.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+Accessors.h 3 | // Belle 4 | // 5 | // Created by Allen Hsu on 1/11/14. 6 | // Copyright (c) 2014 Allen Hsu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDictionary (Accessors) 12 | 13 | - (BOOL)isKindOfClass:(Class)aClass forKey:(NSString *)key; 14 | - (BOOL)isMemberOfClass:(Class)aClass forKey:(NSString *)key; 15 | - (BOOL)isArrayForKey:(NSString *)key; 16 | - (BOOL)isDictionaryForKey:(NSString *)key; 17 | - (BOOL)isStringForKey:(NSString *)key; 18 | - (BOOL)isNumberForKey:(NSString *)key; 19 | 20 | - (NSArray *)arrayForKey:(NSString *)key; 21 | - (NSDictionary *)dictionaryForKey:(NSString *)key; 22 | - (NSString *)stringForKey:(NSString *)key; 23 | - (NSNumber *)numberForKey:(NSString *)key; 24 | - (double)doubleForKey:(NSString *)key; 25 | - (float)floatForKey:(NSString *)key; 26 | - (int)intForKey:(NSString *)key; 27 | - (unsigned int)unsignedIntForKey:(NSString *)key; 28 | - (NSInteger)integerForKey:(NSString *)key; 29 | - (NSUInteger)unsignedIntegerForKey:(NSString *)key; 30 | - (long long)longLongForKey:(NSString *)key; 31 | - (unsigned long long)unsignedLongLongForKey:(NSString *)key; 32 | - (BOOL)boolForKey:(NSString *)key; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /NSDictionary+Accessors.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+Accessors.m 3 | // Belle 4 | // 5 | // Created by Allen Hsu on 1/11/14. 6 | // Copyright (c) 2014 Allen Hsu. All rights reserved. 7 | // 8 | 9 | #import "NSDictionary+Accessors.h" 10 | 11 | @implementation NSDictionary (Accessors) 12 | 13 | - (BOOL)isKindOfClass:(Class)aClass forKey:(NSString *)key 14 | { 15 | id value = [self objectForKey:key]; 16 | return [value isKindOfClass:aClass]; 17 | } 18 | 19 | - (BOOL)isMemberOfClass:(Class)aClass forKey:(NSString *)key 20 | { 21 | id value = [self objectForKey:key]; 22 | return [value isMemberOfClass:aClass]; 23 | } 24 | 25 | - (BOOL)isArrayForKey:(NSString *)key 26 | { 27 | return [self isKindOfClass:[NSArray class] forKey:key]; 28 | } 29 | 30 | - (BOOL)isDictionaryForKey:(NSString *)key 31 | { 32 | return [self isKindOfClass:[NSDictionary class] forKey:key]; 33 | } 34 | 35 | - (BOOL)isStringForKey:(NSString *)key 36 | { 37 | return [self isKindOfClass:[NSString class] forKey:key]; 38 | } 39 | 40 | - (BOOL)isNumberForKey:(NSString *)key 41 | { 42 | return [self isKindOfClass:[NSNumber class] forKey:key]; 43 | } 44 | 45 | - (NSArray *)arrayForKey:(NSString *)key 46 | { 47 | id value = [self objectForKey:key]; 48 | if ([value isKindOfClass:[NSArray class]]) { 49 | return value; 50 | } 51 | return nil; 52 | } 53 | 54 | - (NSDictionary *)dictionaryForKey:(NSString *)key 55 | { 56 | id value = [self objectForKey:key]; 57 | if ([value isKindOfClass:[NSDictionary class]]) { 58 | return value; 59 | } 60 | return nil; 61 | } 62 | 63 | - (NSString *)stringForKey:(NSString *)key 64 | { 65 | id value = [self objectForKey:key]; 66 | if ([value isKindOfClass:[NSString class]]) { 67 | return value; 68 | } else if ([value respondsToSelector:@selector(description)]) { 69 | return [value description]; 70 | } 71 | return nil; 72 | } 73 | 74 | - (NSNumber *)numberForKey:(NSString *)key 75 | { 76 | id value = [self objectForKey:key]; 77 | if ([value isKindOfClass:[NSNumber class]]) { 78 | return value; 79 | } else if ([value isKindOfClass:[NSString class]]) { 80 | NSNumberFormatter *nf = [[NSNumberFormatter alloc] init]; 81 | return [nf numberFromString:value]; 82 | } 83 | return nil; 84 | } 85 | 86 | - (double)doubleForKey:(NSString *)key 87 | { 88 | id value = [self objectForKey:key]; 89 | if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]) { 90 | return [value doubleValue]; 91 | } 92 | return 0; 93 | } 94 | 95 | - (float)floatForKey:(NSString *)key 96 | { 97 | id value = [self objectForKey:key]; 98 | if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]) { 99 | return [value floatValue]; 100 | } 101 | return 0; 102 | } 103 | 104 | - (int)intForKey:(NSString *)key 105 | { 106 | id value = [self objectForKey:key]; 107 | if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]) { 108 | return [value intValue]; 109 | } 110 | return 0; 111 | } 112 | 113 | - (unsigned int)unsignedIntForKey:(NSString *)key 114 | { 115 | id value = [self objectForKey:key]; 116 | if ([value isKindOfClass:[NSString class]]) { 117 | NSNumberFormatter *nf = [[NSNumberFormatter alloc] init]; 118 | value = [nf numberFromString:value]; 119 | } 120 | if ([value isKindOfClass:[NSNumber class]]) { 121 | return [value unsignedIntValue]; 122 | } 123 | return 0; 124 | } 125 | 126 | - (NSInteger)integerForKey:(NSString *)key 127 | { 128 | id value = [self objectForKey:key]; 129 | if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]) { 130 | return [value integerValue]; 131 | } 132 | return 0; 133 | } 134 | 135 | - (NSUInteger)unsignedIntegerForKey:(NSString *)key 136 | { 137 | id value = [self objectForKey:key]; 138 | if ([value isKindOfClass:[NSString class]]) { 139 | NSNumberFormatter *nf = [[NSNumberFormatter alloc] init]; 140 | value = [nf numberFromString:value]; 141 | } 142 | if ([value isKindOfClass:[NSNumber class]]) { 143 | return [value unsignedIntegerValue]; 144 | } 145 | return 0; 146 | } 147 | 148 | - (long long)longLongForKey:(NSString *)key 149 | { 150 | id value = [self objectForKey:key]; 151 | if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]) { 152 | return [value longLongValue]; 153 | } 154 | return 0; 155 | } 156 | 157 | - (unsigned long long)unsignedLongLongForKey:(NSString *)key 158 | { 159 | id value = [self objectForKey:key]; 160 | if ([value isKindOfClass:[NSString class]]) { 161 | NSNumberFormatter *nf = [[NSNumberFormatter alloc] init]; 162 | value = [nf numberFromString:value]; 163 | } 164 | if ([value isKindOfClass:[NSNumber class]]) { 165 | return [value unsignedLongLongValue]; 166 | } 167 | return 0; 168 | } 169 | 170 | - (BOOL)boolForKey:(NSString *)key 171 | { 172 | id value = [self objectForKey:key]; 173 | if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]) { 174 | return [value boolValue]; 175 | } 176 | return NO; 177 | } 178 | 179 | @end 180 | -------------------------------------------------------------------------------- /NSDictionary+Accessors.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "NSDictionary+Accessors" 3 | s.ios.deployment_target = '7.0' 4 | s.osx.deployment_target = '10.7' 5 | s.watchos.deployment_target = '2.0' 6 | s.tvos.deployment_target = '10.0' 7 | s.version = "1.0.0" 8 | s.summary = "Type safe accessors for NSDictionary, better used with dictionary parsed from JSON." 9 | s.homepage = "https://github.com/allenhsu/NSDictionary-Accessors" 10 | s.license = "MIT" 11 | s.authors = { "Allen Hsu" => "me@imallen.com" } 12 | s.source = { :git => "https://github.com/allenhsu/NSDictionary-Accessors.git", :tag => '1.0.0' } 13 | s.framework = 'Foundation' 14 | s.source_files = '*.{h,m}' 15 | s.requires_arc = true 16 | end 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | NSDictionary-Accessors 2 | ====================== 3 | 4 | Type safe accessors for NSDictionary, better used with dictionary parsed from JSON. 5 | 6 | Before: 7 | 8 | id value = nil; 9 | value = [dictionary objectForKey:@"id"]; 10 | if ([value isKindOfClass:[NSNumber class]]) { 11 | model.identifier = [value unsignedLongLongValue]; 12 | } 13 | value = [dictionary objectForKey:@"title"]; 14 | if ([value isKindOfClass:[NSString class]]) { 15 | model.title = value; 16 | } 17 | value = [dictionary objectForKey:@"content"]; 18 | if ([value isKindOfClass:[NSString class]]) { 19 | model.content = value; 20 | } 21 | 22 | Problems: 23 | 24 | - Boilerplate code 25 | - 64bit ids will be returned as string instead of number in some api 26 | - Libs like [RestKit](https://github.com/RestKit/RestKit/) even lighter [JSONModel](https://github.com/icanzilb/JSONModel) are still heavy for simple apps sometimes 27 | 28 | What you need is just [AFNetworking](https://github.com/AFNetworking/AFNetworking) + NSDictionary+Accessors 29 | 30 | After: 31 | 32 | model.identifier = [dictionary unsignedLongLongForKey:@"id"]; 33 | model.title = [dictionary stringForKey:@"title"]; 34 | model.content = [dictionary stringForKey:@"content"]; --------------------------------------------------------------------------------