Created
April 18, 2013 11:32
-
-
Save huacnlee/5412056 to your computer and use it in GitHub Desktop.
BaseModel,用于 JSON 转 Objective-C Model
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#import "XMImageURL.h" | |
enum { | |
// 保密 | |
XMGenderUnknow = 0, | |
// 男 | |
XMGenderMale = 1, | |
// 女 | |
XMGenderFemale = 2, | |
}; | |
// 用户性别 | |
typedef int XMGender; | |
enum { | |
XMRankInfoTypeSong = 1, | |
XMRankInfoTypeAlbum, | |
XMRankInfoTypeArtist, | |
}; | |
// Rank.getInfo 查询参数类型 | |
typedef int XMRankInfoType; | |
@interface XMBaseModel : NSObject <NSCoding> | |
+ (NSDictionary *) keysMapping; | |
+ (id)modelWithResponseDict:(NSDictionary *)dict; | |
// 将 API 返回的 str 的性别转换成 XMGender | |
+ (XMGender) xmGenderWithResponseString: (NSString *) str; | |
@end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "XMBaseModel.h" | |
#import "NSURL+XMAddition.h" | |
#import <objc/runtime.h> | |
@implementation XMBaseModel | |
+ (XMGender) xmGenderWithResponseString: (NSString *) str { | |
XMGender gender = XMGenderUnknow; | |
gender = XMGenderUnknow; | |
if ([str isEqualToString:@"M"]) { | |
gender = XMGenderMale; | |
} | |
else if ([str isEqualToString:@"F"]) { | |
gender = XMGenderFemale; | |
} | |
return gender; | |
} | |
// 自动将 JSON 里面的值根据 keyMappings 的定义填充到对应的属性里面,并生成一个对象 | |
// 此方法将不会处理 NSArray 的内容 | |
+ (id)modelWithResponseDict:(NSDictionary *)dict { | |
id obj = [self new]; | |
for (NSString *originKey in [[self keysMapping] allKeys]) { | |
// OC 的 key | |
NSString *key = [[self keysMapping] objectForKey:originKey]; | |
// JSON 的值 | |
if ([[[dict allKeys] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF == %@",originKey]] count] == 0) { | |
// 跳过结果里面没有的 key | |
continue; | |
} | |
id originVal = dict[originKey]; | |
// 得到 OC 那个 Key 的类型 | |
if ([originVal isKindOfClass:[NSString class]]) { | |
// NSString | |
if ([obj propertyIsNSUInteger:key]) { | |
// NSUInteger & int | |
[obj setValue:[NSNumber numberWithUnsignedInteger:(NSUInteger) [originVal integerValue]] forKey:key]; | |
} | |
else if ([obj propertyIsBoolean:key]) { | |
// BOOL | |
if ([originVal isEqualToString:@"1"] || [originVal isEqualToString:@"yes"] || [originVal isEqualToString:@"true"]) { | |
[obj setValue:[NSNumber numberWithBool:true] forKey:key]; | |
} | |
else { | |
[obj setValue:[NSNumber numberWithBool:false] forKey:key]; | |
} | |
} | |
else if ([obj propertyIsNSURL:key]) { | |
// NSURL | |
[obj setValue:[NSURL URLWithEscapedString:originVal] forKey:key]; | |
} | |
else if ([obj propertyIsXMImageURL:key]) { | |
XMImageURLType imageUrlType = XMImageURLTypeAlbum; | |
if ([[obj className] isEqualToString:@"XMAlbum"]) { | |
imageUrlType = XMImageURLTypeAlbum; | |
} | |
else if ([[obj className] isEqualToString:@"XMSong"]) { | |
imageUrlType = XMImageURLTypeSong; | |
} | |
else if ([[obj className] isEqualToString:@"XMUser"]) { | |
imageUrlType = XMImageURLTypeUser; | |
} | |
else if ([[obj className] isEqualToString:@"XMCollect"]) { | |
imageUrlType = XMImageURLTypeCollect; | |
} | |
else if ([[obj className] isEqualToString:@"XMRadio"]) { | |
imageUrlType = XMImageURLTypeRadio; | |
} | |
else if ([[obj className] isEqualToString:@"XMArtist"]) { | |
imageUrlType = XMImageURLTypeArtist; | |
} | |
[obj setValue:[XMImageURL urlWithType:imageUrlType url:originVal] forKey:key]; | |
} | |
else { | |
// NSString | |
[obj setValue:originVal forKey:key]; | |
} | |
} | |
else if ([originVal isKindOfClass:[NSNumber class]]) { | |
if ([obj propertyIsDate:key]) { | |
[obj setValue:[NSDate dateWithTimeIntervalSince1970:[originVal integerValue]] forKey:key]; | |
} | |
else { | |
[obj setValue:originVal forKey:key]; | |
} | |
} | |
} | |
return obj; | |
} | |
- (BOOL) propertyIsNSString: (NSString *) property { | |
return ([[self.class typeForProperty:property] isEqualToString:@"@\"NSString\""]); | |
} | |
- (BOOL) propertyIsDate: (NSString *) property { | |
return ([[self.class typeForProperty:property] isEqualToString:@"@\"NSDate\""]); | |
} | |
- (BOOL) propertyIsNSUInteger: (NSString *) property { | |
return ([[self.class typeForProperty:property] isEqualToString:@"Q"]); | |
} | |
- (BOOL) propertyIsBoolean: (NSString *) property { | |
return ([[self.class typeForProperty:property] isEqualToString:@"c"]); | |
} | |
- (BOOL) propertyIsNSURL: (NSString *) property { | |
return ([[self.class typeForProperty:property] isEqualToString:@"@\"NSURL\""]); | |
} | |
- (BOOL) propertyIsXMImageURL: (NSString *) property { | |
return ([[self.class typeForProperty:property] isEqualToString:@"@\"XMImageURL\""]); | |
} | |
+ (NSString *) typeForProperty:(NSString *)prop { | |
NSString *result = nil; | |
objc_property_t property = class_getProperty(self, [prop UTF8String]); | |
if (!property) | |
return nil; | |
// This will return some garbage like "Ti,GgetFoo,SsetFoo:,Vproperty" | |
// See https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html | |
NSString *atts = [NSString stringWithCString:property_getAttributes(property) encoding:NSUTF8StringEncoding]; | |
for (NSString *att in [atts componentsSeparatedByString:@","]) { | |
if ([att hasPrefix:@"T"]) { | |
result = [att substringFromIndex:1]; | |
// NSLog(@"---- %@ || %@", atts, result); | |
return result; | |
} | |
} | |
return nil; | |
} | |
+ (NSDictionary *)keysMapping { | |
return @{}; | |
} | |
#pragma mark - NSCoding | |
- (id)initWithCoder:(NSCoder *)aDecoder { | |
NSArray *keys = [[self.class keysMapping] allValues]; | |
if ([aDecoder allowsKeyedCoding]) { | |
for (NSString *key in keys) { | |
[self setValue:[aDecoder decodeObjectForKey:key] forKey:key]; | |
} | |
} else { | |
for (NSString *key in keys) { | |
[self setValue:[aDecoder decodeObject] forKey:key]; | |
} | |
} | |
return self; | |
} | |
- (void)encodeWithCoder:(NSCoder *)aCoder { | |
NSArray *keys = [[self.class keysMapping] allValues]; | |
if ([aCoder allowsKeyedCoding]) { | |
for (NSString *key in keys) { | |
[aCoder encodeObject:[self valueForKey:key] forKey:key]; | |
} | |
} else { | |
for (NSString *key in keys) { | |
[aCoder encodeObject:[self valueForKey:key]]; | |
} | |
} | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment