反射--> 解析JSON数据

 

方法一

Persons.json文件

[
 {
 "name": "Chris",
 "age": 18,
 "city": "Shanghai",
 "job": "iOS"
 },
 {
 "name": "Ada",
 "age": 16,
 "city": "Beijing",
 "job": "student"
 },
 {
 "name": "Rita",
 "age": 17,
 "city": "Xiamen",
 "job": "HR"
 }
 ]

 Model.h类

 1 #import <Foundation/Foundation.h>
 2 
 3 @interface PersonModel : NSObject
 4 
 5 @property (nonatomic, copy) NSString *name;
 6 @property (nonatomic, assign) NSInteger age;
 7 @property (nonatomic, copy) NSString *city;
 8 @property (nonatomic, copy) NSString *job;
 9 @property (nonatomic, copy) NSString *sex;
10 
11 - (instancetype)initWithNSDictionary:(NSDictionary *)dict;
12 
13 @end

 

Model.m类

 1 #import "PersonModel.h"
 2 #import <objc/runtime.h>
 3 
 4 @implementation PersonModel
 5 
 6 - (instancetype)initWithNSDictionary:(NSDictionary *)dict {
 7     self = [super init];
 8     if (self) {
 9         [self prepareModel:dict];
10     }
11     return self;
12 }
13 
14 - (void)prepareModel:(NSDictionary *)dict {
15     NSMutableArray *keys = [[NSMutableArray alloc] init];
16     
17     u_int count = 0;
18     objc_property_t *properties = class_copyPropertyList([self class], &count);
19     for (int i = 0; i < count; i++) {
20         objc_property_t property = properties[i];
21         const char *propertyCString = property_getName(property);
22         NSString *propertyName = [NSString stringWithCString:propertyCString encoding:NSUTF8StringEncoding];
23         [keys addObject:propertyName];
24     }
25     free(properties);
26     
27     for (NSString *key in keys) {
28         if ([dict valueForKey:key]) {
29             [self setValue:[dict valueForKey:key] forKey:key];
30         }
31     }
32 }
33 
34 @end

 

 

调用

1 NSString *file = [[NSBundle mainBundle] pathForResource:@"Persons" ofType:@"json"];
2     NSData *data = [NSData dataWithContentsOfFile:file];
3     NSMutableArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
4     
5     for (NSDictionary *model in array) {
6         PersonModel *person = [[PersonModel alloc] initWithNSDictionary:model];
7         NSLog(@"%@, %ld, %@, %@", person.name, (long)person.age, person.city, person.job);
8     }

 

 

打印结果:

 

 


 

 

方法二

数据模型的父类是:JSONModel

JSONModel的子类是:JSONPerson, JSONStudent, JSONTeacther等;

JSONStudent.h中

 1 @import JSONModel;
 2 
 3 @interface JSONStudent : JSONModel
 4 
 5 @property (nonatomic, copy) NSString * id;
 6 @property (nonatomic, copy) NSString * name;
 7 @property (nonatomic, copy) NSString * nickName;
 8 @property (nonatomic, copy) NSString * phoneNumber;
 9 
10 @end

 

 

注意:这是用OC来写的!

 

获取属性 

 1 func getAllProperties<T: JSONModel>(anyClass: T) -> [String] {
 2         var properties = [String]()
 3         let count = UnsafeMutablePointer<UInt32>.allocate(capacity: 0)
 4         let buff = class_copyPropertyList(object_getClass(anyClass), count)
 5         let countInt = Int(count[0])
 6         
 7         for i in 0..<countInt {
 8             let temp = buff![i]
 9             let tempPro = property_getName(temp)
10             let proper = String(utf8String: tempPro!)
11             properties.append(proper!)
12         }
13         return properties
14         
15     }

 

注意:获取属性使用Swift写的,单纯用Swift和OC要简单!

使用

1 func returnListStudent(students: [JSONStudent]) {
2         for item in students {
3             let studentProperties = self.getAllProperties(anyClass: item)
4             for i in 0..< studentProperties.count{
5                 print("值是:\(item.value(forKey: studentProperties[I]))" + "属性是:\(studentProperties[i])"self.dataError)
6             }
7         }
8     }

 

 

方法三

User.swift

1 import UIKit
2 
3 class User: NSObject {
4     var name:String = ""  //姓名
5     var nickname:String?  //昵称
6     var age:Int?   //年龄
7     var emails:[String]?  //邮件地址
8 }

 

Mirror

属性

//    实例化
let user = User()
let mirror: Mirror = Mirror(reflecting:user)

//    subjectType:对象类型

print(mirror.subjectType) // 打印出:User

//    children:反射对象的属性集合

//    displayStyle:反射对象展示类型


// advance 的使用
let children = mirror.children
let p0 = advance(children.startIndex, 0, children.endIndex) // name 的位置
let p0Mirror =  Mirror(reflecting: children[p0].value) // name 的反射
print(p0Mirror.subjectType) //Optional<String> 这个就是name 的类型

 

 

调用:

 1     @objc func testOne() {
 2 //        得到应用名称
 3         let nameSpace = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as! String
 4         let clsName = "User"
 5 //        使用NSClassFromString通过类名得到实例(得到类的完整路径, 注意分隔符是小数点;并判断数据类型是否符合预期。 备注: as?后面的格式是类名.Type, cls可能是nil)
 6         guard let cls = NSClassFromString(nameSpace + "." + clsName) as? NSObject.Type else { return }  //得到类完整路径
 7         print("------_>\(cls)")
 8         let user = cls.init()
 9         print("------111111_>\(user)")
10         
11 //        使用Mirror得到属性值
12         let mirror = Mirror(reflecting: user)
13         for case let(key?, value) in mirror.children {
14             print("key:\(key), value: \(value)")    //打印成员属性
15         }
16         print(mirror.subjectType)    //反射对象的数据类型</span>
17 
18     }

 

打印:

 

 

转载于:https://www.cnblogs.com/EchoHG/p/8458337.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值