利用Runtime实现对Json数据的ORM框架
2016-05-12 20:52
633 查看
代码:
// // PBFORMTools.m // PBFBaseToolsDemo // // Created by BY-MAC01 on 16/5/12. // Copyright © 2016年 BY-MAC01. All rights reserved. // #import "PBFORMTools.h" #import <objc/runtime.h> @implementation PBFORMTools //ORM框架,利用Runtime构建Model + (void)assembleDictionaryData:(NSObject*)objDes objRes:(NSDictionary*)objRes{ Class classType = [objDes class]; //NSArray类型对照表 NSDictionary *dicArrClassNames = nil; NSString *strDicArrNames = @"_dicArrayClassName"; Ivar ivarDicArrayClassNames = class_getInstanceVariable(classType, [strDicArrNames UTF8String]); if(ivarDicArrayClassNames != NULL){ id idDicArray = object_getIvar(objDes, ivarDicArrayClassNames); if ([idDicArray isKindOfClass:[NSDictionary class]]) { dicArrClassNames = idDicArray; } } if (objRes) { for (NSString * keyNameRes in [objRes allKeys]) { if (!keyNameRes || [keyNameRes length]<=0) { continue; } //1、获取Class对应属性,判断属性类型 const char * attNameRes = [[NSString stringWithFormat:@"_%@",keyNameRes] UTF8String]; Ivar varTmpDes = class_getInstanceVariable(classType,attNameRes); //2、判断Json数据中,对应数据是否存在 //2.1、如不存在,continue if (varTmpDes == NULL) { continue; } //2.2、判断json数据和属性的类型是否一致 NSObject *objValueRes = [objRes objectForKey:keyNameRes]; const char *ivarType = ivar_getTypeEncoding(varTmpDes); NSString *strIvarTypeDes = [NSString stringWithUTF8String:ivarType]; strIvarTypeDes = [strIvarTypeDes substringWithRange:NSMakeRange(2, [strIvarTypeDes length]-3)]; //2.2.1、NSString类型 if([objValueRes isKindOfClass:[NSString class]] && [strIvarTypeDes containsString:@"NSString"]){ //设置值 object_setIvar(objDes, varTmpDes, objValueRes); } //2.2.2、NSNumber类型 else if([objValueRes isKindOfClass:[NSNumber class]] && [strIvarTypeDes containsString:@"NSNumber"]){ //设置值 object_setIvar(objDes, varTmpDes, objValueRes); } //2.2.3、NSDictionary类型 //如属于NSDictionary、且Class该属性类型不属于上述类型,递归调用 assembleDictionaryData else if ([objValueRes isKindOfClass:[NSDictionary class]]) { //设置值 Class classDes = objc_getClass([strIvarTypeDes UTF8String]); id objDesDic = [[classDes alloc] init]; [PBFORMTools assembleDictionaryData:objDesDic objRes:(NSDictionary*)objValueRes]; object_setIvar(objDes, varTmpDes, objDesDic); } //2.2.4、NSArray类型 //如类型属于NSArray、循环递归 assembleArrayData else if ([objValueRes isKindOfClass:[NSArray class]]) { //设置值 if (dicArrClassNames == NULL) { continue; } id classType = [dicArrClassNames objectForKey:keyNameRes]; if (classType == NULL) { continue; } NSObject *objNSArray = [PBFORMTools assembleArrayData:classType objRes:(NSArray*)objValueRes]; object_setIvar(objDes, varTmpDes, objNSArray); } } } return ; } //ORM框架,利用Runtime构建Model + (NSArray*)assembleArrayData:(Class)classType objRes:(NSArray*)objRes{ NSMutableArray *arrRtn = [[NSMutableArray alloc] init]; for(NSObject* objTmp in objRes){ //1、NSString类型 if([objTmp isKindOfClass:[NSString class]] && classType == [NSString class]){ //设置值 [arrRtn addObject:objTmp]; } //2、NSNumber类型 else if([objTmp isKindOfClass:[NSNumber class]] && classType == [NSNumber class]){ //设置值 [arrRtn addObject:objTmp]; } //3、属于NSArray,递归调用本方法 assembleArrayData else if ([objTmp isKindOfClass:[NSArray class]]) { NSArray *arrDes = [PBFORMTools assembleArrayData:classType objRes:(NSArray*)objTmp]; [arrRtn addObject:arrDes]; } //4、不属于NSArray,属于NSDictionary,直接调用 assembleDictionaryData else if ([objTmp isKindOfClass:[NSDictionary class]]) { id objDes = [[classType alloc] init]; [PBFORMTools assembleDictionaryData:objDes objRes:(NSDictionary*)objTmp]; [arrRtn addObject:objDes]; } } return [arrRtn copy]; } @end
单元测试:
// // PBFORMToolsTests.m // PBFBaseToolsDemo // // Created by BY-MAC01 on 16/5/12. // Copyright © 2016年 BY-MAC01. All rights reserved. // #import <XCTest/XCTest.h> #import "PBFORMTools.h" //跟随者类 @interface PBFORMToolsTestModelFollower : NSObject @property (nonatomic,strong)NSString *name; @property (nonatomic,strong)NSNumber *code; @end @implementation PBFORMToolsTestModelFollower @end //主类 @interface PBFORMToolsTestModelUser : NSObject @property (nonatomic,strong)NSMutableDictionary *KPBFORMToolsDicArrayName; @property (nonatomic,strong)NSString *name; @property (nonatomic,strong)NSNumber *code; @property (nonatomic,strong)NSMutableArray *followers; @property (nonatomic,strong)NSArray *date; @property (nonatomic,strong)PBFORMToolsTestModelFollower *mainFollower; @end @implementation PBFORMToolsTestModelUser - (instancetype)init{ self = [super init]; self.KPBFORMToolsDicArrayName = [[NSMutableDictionary alloc] init]; [self.KPBFORMToolsDicArrayName setValue:[PBFORMToolsTestModelFollower class] forKey:@"followers"]; [self.KPBFORMToolsDicArrayName setValue:[NSString class] forKey:@"date"]; return self; } @end @interface PBFORMToolsTests : XCTestCase @end @implementation PBFORMToolsTests - (void)setUp { [super setUp]; // Put setup code here. This method is called before the invocation of each test method in the class. } - (void)tearDown { // Put teardown code here. This method is called after the invocation of each test method in the class. [super tearDown]; } - (void)testAssembleByDictionary{ //构造 NSMutableDictionary *dicAttUser = [[NSMutableDictionary alloc] init]; [dicAttUser setValue:@"朱林" forKey:@"name"]; [dicAttUser setValue:[NSNumber numberWithInt:123456] forKey:@"code"]; //followers NSMutableDictionary *dicAttFollower1 = [[NSMutableDictionary alloc] init]; [dicAttFollower1 setValue:@"张三" forKey:@"name"]; [dicAttFollower1 setValue:[NSNumber numberWithInt:456] forKey:@"code"]; NSMutableDictionary *dicAttFollower2 = [[NSMutableDictionary alloc] init]; [dicAttFollower2 setValue:@"李四" forKey:@"name"]; [dicAttFollower2 setValue:[NSNumber numberWithInt:789] forKey:@"code"]; NSArray *arrFollowers = [NSArray arrayWithObjects:dicAttFollower1,dicAttFollower2, nil]; [dicAttUser setValue:arrFollowers forKey:@"followers"]; //date NSArray *arrDates = [NSArray arrayWithObjects:@"hello",@"world", nil]; [dicAttUser setValue:arrDates forKey:@"date"]; //mainFollower NSMutableDictionary *dicAttFollowerMain = [[NSMutableDictionary alloc] init]; [dicAttFollowerMain setValue:@"王五" forKey:@"name"]; [dicAttFollowerMain setValue:[NSNumber numberWithDouble:789.23] forKey:@"code"]; [dicAttUser setValue: 4000 dicAttFollowerMain forKey:@"mainFollower"]; //work PBFORMToolsTestModelUser *userInfo = [[PBFORMToolsTestModelUser alloc] init]; [PBFORMTools assembleDictionaryData:userInfo objRes:dicAttUser]; //断言 XCTAssertEqual(userInfo.name, @"朱林",@"name error"); XCTAssertEqual([userInfo.code integerValue], 123456,@"code error"); XCTAssertEqual([userInfo.followers count],2 ,@"followers error"); XCTAssertEqual([userInfo.date count],2 ,@"date error"); XCTAssertEqual(userInfo.mainFollower.name, @"王五",@"mainFollower.name error"); XCTAssertEqual([userInfo.mainFollower.code doubleValue], 789.23,@"mainFollower.code error"); } - (void)testExample { // This is an example of a functional test case. // Use XCTAssert and related functions to verify your tests produce the correct results. } - (void)testPerformanceExample { // This is an example of a performance test case. [self measureBlock:^{ // Put the code you want to measure the time of here. }]; } @end
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 使用 Python 处理 JSON 格式的数据
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- XML 与 JSON 优劣对比
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- VBA将excel数据表生成JSON文件
- newtonsoft.json解析天气数据出错解决方法
- Java Runtime Environment 5.0 Update 12 下载
- vbs 解析json jsonp的方法
- Ruby和Ruby on Rails中解析JSON格式数据的实例教程
- Extjs4如何处理后台json数据中日期和时间
- C#实现将类的内容写成JSON格式字符串的方法
- JQuery ajax返回JSON时的处理方式 (三种方式)
- jquery JSON的解析方式示例介绍
- c#版json数据解析示例分享
- ASP JSON类文件的使用方法