一个jsonmodel的使用可以同事使用两个json解析的数据吗

技术文章分类(180)
技术随笔(11)
demo下载:/MartinLi/JsonModelDemo2
简单说,就是dictionary to model. &专业一些就是:解析json数据。
可以为您省下大量的代码,时间,精力,还能提高准确度。
操作步骤:
一,引入JsonModel :这里我使用了pods,&pod 'JSONModel'
二,对应url建立model,如:/tec/api/mm/category?source=sears&agent=123&client=ios
这里必然需要建立2个model:一个是category,一个是self。
这里我贴代码进来吧,大家注意看:
注意:1,继承JSONModel
   & 2,创建Cat协议
& & & & 3,实现所有或者部分对应属性(命名必须和Json属性名一模一样)
#import "JSONModel.h"
@protocol Cat @end
@interface Cat : JSONModel
@property (strong, nonatomic) NSString* id;
@property (strong, nonatomic) NSString*
@property (assign, nonatomic) long
UserModel.h
注意:1,继承JSONModel
   & 2,实现所有或者部分对应属性
   & 3,对应到categories属性的地方,做如下处理
#import &JSONModel/JSONModel.h&
#import "Cat.h"
@interface UserModel : JSONModel
@property (strong, nonatomic) NSString*
@property (strong, nonatomic) NSString*
@property (strong, nonatomic) NSString*
@property (strong, nonatomic) NSArray&Cat&*
三,开始发送请求获取数据了
#import "ViewController.h"
#import "UserModel.h"
#import "JSONModelLib.h"
@interface ViewController ()
UserModel *userM
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
userModel = [[UserModel alloc] initFromURLWithString:@"/tec/api/mm/category?source=sears&agent=123&client=ios" completion:^(UserModel *model, JSONModelError *err) {
NSLog(@"loans: %@",userModel);
NSLog(@"%@",model);
1,import :XXXModel.h & JSONModelLib.h
2,这里以initFromURLWithString:请求数据为例(还有很多其他的方法)。
这里提供两种获取数据的方式:这里的userModel,model是一样的数据,你可以根据实际情况选择一种。
在上面的例子中,你添加了两个jsonModel类,如果还有三级,四级分类,是不是要添加更多。这样无疑也是麻烦的,而且浪费了一些资源。
其实,后来仔细想想,他们原理上是可以放在一个.h .m文件中的。后面我用实例证明了我的说法:
#import &JSONModel/JSONModel.h&
@protocol Cat @end
@interface Cat : JSONModel
@property (strong, nonatomic) NSString* id;
@property (strong, nonatomic) NSString*
@property (assign, nonatomic) long
@interface UserModel : JSONModel
@property (strong, nonatomic) NSString*
@property (strong, nonatomic) NSString*
@property (strong, nonatomic) NSString*
@property (strong, nonatomic) NSArray&Cat&*
#import "UserModel.h"
@implementation Cat
@implementation UserModel
阅读(...) 评论()一、思路:
1、通过模型类型获得所有的属性和其类型
2、对获得的json进行处理。类型处理
3、考虑字典键值和模型属性名不一致的情况
4、添加code用于归档
5、补充JSON转字典、字典转JSON、字典转模型等接口
6、对处理过的properties做缓存
二、设计模式思考:
设计模式的选择---------继承、接口、抽象基类的选择。
在使用方便、高效率、低耦合之间抉择。
三、细节及实现
先把任务分解,实现各个部分细节,然后进行组合,当然我们要思考好,采用何种设计模式组装。先来看看各个部分的实现细节。
1.通过模型类型获得所有的属性和其类型,
unsigned int outCount = 0;
//获得Class c所有属性这里的c是[Model class]
objc_property_t *properties = class_copyPropertyList(c, &outCount);
for (int i = 0; i & outC i++) {
objc_property_t propert = properties[i];
//获得属性名
NSString *key = @(property_getName(propert));
//获得属性类型,如CGFloat、nonatomic、copy等信息
NSString *type = @(property_getAttributes(propert));
NSLog(@"key = %@ , type = %@", key, type);
 Model模型如下
typedef void(^block)();
@interface Model : NSObject
@property (nonatomic, copy) NSString *q_NSS
@property (nonatomic, assign) CGFloat q_CGF
@property (nonatomic, assign) CGRect q_CGR
@property (nonatomic, assign) double q_
@property (nonatomic, assign) int q_
@property (nonatomic, assign) BOOL q_
@property (nonatomic, assign) float q_
@property (nonatomic, assign) short q_
@property (nonatomic, assign) long q_
@property (nonatomic, assign) long long q_
@property (nonatomic, assign) Point q_
@property (nonatomic, strong) id q_
@property (nonatomic, weak) id&NSObject& q_
@property (nonatomic, copy) block q_
@property (nonatomic, strong) Model1 *q_model1;
@property SEL q_SEL;
@property Class q_C
@property Ivar q_I
@property Method q_M
输出结果为
key = q_NSString , type = T@"NSString",C,N,V_q_NSString
key = q_CGFloat , type = Td,N,V_q_CGFloat
key = q_CGRect , type = T{CGRect={CGPoint=dd}{CGSize=dd}},N,V_q_CGRect
key = q_double , type = Td,N,V_q_double
key = q_int , type = Ti,N,V_q_int
key = q_bool , type = TB,N,V_q_bool
key = q_float , type = Tf,N,V_q_float
key = q_short , type = Ts,N,V_q_short
key = q_long , type = Tq,N,V_q_long
key = q_longlong , type = Tq,N,V_q_longlong
key = q_point , type = T{Point=ss},N,V_q_point
key = q_id , type = T@,&,N,V_q_id
key = q_delegate , type = T@"&NSObject&",W,N,V_q_delegate
key = q_block , type = T@?,C,N,V_q_block
key = q_model1 , type = T@"Model1",&,N,V_q_model1
key = q_SEL , type = T:,V_q_SEL
key = q_Class , type = T#,&,V_q_Class
key = q_Ivar , type = T^{objc_ivar=},V_q_Ivar
key = q_Method , type = T^{objc_method=},V_q_Method
将type用&,&分开,以T@"NSNumber",N,R,Vname& 为例
在类中的声明为 let name:&NSNumber =& NSNumber()
T@&NSNumber& 标记了属于什么类型
N & & & & & &线程安全&相当与Objective-C中的nonmatic
R & & & & & &不可变,R相当与Objective-C中的readonly,C相当于copy & & & &
Vname & & & &去掉V,name就是变量名
通过对type进行处理就可以获得属性的类型。从而进行下一步处理。
注意点:class_copyPropertyList返回的仅仅是对象类的属性,class_copyIvarList返回类的所有属性和变量,在swift中如let a: Int? 是无法通过class_copyPropertyList返回的。
2.对type的处理使用方法可能不同,但是目的是一样的,就是为了从type字符串中区分出不同的类型
主要分为这几种:对象、协议、block、基本类型、结构体、自定义类型、Class、Ivar、Method、SEL、
MJExtension采用这样区分,在MJExtensionConst中这样定义
NSString *const MJPropertyTypeInt = @"i";
NSString *const MJPropertyTypeShort = @"s";
NSString *const MJPropertyTypeFloat = @"f";
NSString *const MJPropertyTypeDouble = @"d";
NSString *const MJPropertyTypeLong = @"l";
NSString *const MJPropertyTypeLongLong = @"q";
NSString *const MJPropertyTypeChar = @"c";
NSString *const MJPropertyTypeBOOL1 = @"c";
NSString *const MJPropertyTypeBOOL2 = @"b";
NSString *const MJPropertyTypePointer = @"*";
NSString *const MJPropertyTypeIvar = @"^{objc_ivar=}";
NSString *const MJPropertyTypeMethod = @"^{objc_method=}";
NSString *const MJPropertyTypeBlock = @"@?";
NSString *const MJPropertyTypeClass = @"#";
NSString *const MJPropertyTypeSEL = @":";
NSString *const MJPropertyTypeId = @"@";
MJExtension采用对type进行字符串处理就能够区分出具体的类型
而在JSONModel采用 NSScanner,对类型进行处理。
比较下,个人觉得采用定义MJExtensionConst这样一个类来存放区分的值显得更加清晰。对于阅读源代码的人来说相对比较好。当然也可以结合起来使用
3.对获得的JSON进行类型处理。
在JSON中为NSNumer,而propertytype为NSString,这种情况很常见。我们就需要处理一下,当propertytype为NSString,而在JSON中为NSNumber,就把NSNumber转化为NSString。
Readonly不需要赋值
可变和不可变处理
模型就需要递归处理
NSString -& NSURL
字符串转BOOL
还有一些其他处理,以上的处理中也不是每个第三方都进行处理了
截取MJEextension中的一部分代码
if ([value isKindOfClass:[NSStringclass]]) {
if (propertyClass == [NSURL class]) {
// NSString -& NSURL
// 字符串转码
value = [value mj_url];
} else if (type.isNumberType) {
NSString *oldValue =
// NSString -& NSNumber
value = [numberFormatter_ numberFromString:oldValue];
// 如果是BOOL
if (type.isBoolType) {
// 字符串转BOOL(字符串没有charValue方法)
// 系统会调用字符串的charValue转为BOOL类型
NSString *lower = [oldValue lowercaseString];
if ([lower isEqualToString:@"yes"] || [lower isEqualToString:@"true"]) {
value = @YES;
} else if ([lower isEqualToString:@"no"] || [lower isEqualToString:@"false"]) {
value = @NO;
4.采用KVC赋值
setValue:forKey:
&就不多说了
5.考虑字典键值和模型属性名不一致的情况
比如id、descripition不能作为属性名,当服务器使用时我们就需要另外构造名字;还有服务器一般使用user_name的命名方式,而OC中一般使用驼峰命名法即userName,那么我们就需要建立一对一的对应关系。
我想到有三种方法处理:
& & &采用继承,定义model基类,子类重写父类方法。
& & &block设置block回调。
& & &可以采用抽象基类。
&&&&&&这个部分就需要我们好好考虑下了,因为涉及到我们如何提供接口,使用者如何使用的问题。需要考虑到使用是否方便、效率高低、低耦合是否高等问题。
& & &先来说第一种,采用继承的方法,无疑的会带来高耦合的后果,当然在设计合理的情况下,大部分情况下使用起来更方便。
& & &第二种采用block的方法。解决了继承带来的高耦合的成本。使用起来也很方便。MJEextension就是用这种方法。但是这种方法往往让我们在调用转化方法时调用block,些一大串的不同键值的转化。个人觉得不同键值的转化写在model里面比较好,而且在封装时,就有意识地引导使用者这么做
& 第三种方法使用抽象基类,定义一个协议,协议提供一个或者几个键值转化的方法。当model遵守并实现了此协议,就找到处理方法进行处理。这种作法避免了继承的高耦合的成本,也是使用者在model遵守协议,实现此方法。键值转化的方法写在model里面,避免转化的地方些太多东西。有时候还要写几遍。当然这样也有些缺点,就是每次有需要转化时(而且键值不同的情况很常见)需要引入,然后遵守协议。连续建几个model时,复制起来都不方便。
6.其他方面
& & (未测试)&对于SEL、Method 、Ivar不能使用KVC,如果考虑这些情况,需要进行判断。
& & 在赋值时,设置可以忽略的属性
7.添加code用于归档
& 添加方法
- (id)initWithCoder:(NSCoder *)decoder
- (void)encodeWithCoder:(NSCoder *)encoder
一般是给NSObject添加分类,因为我们可以得到类的所有属性和对应的值。在两个方法中遍历属性,进行编码和解码。
方便做些缓存,很多的页面缓存就可以这样做。使用比较方便。
8.补充JSON转字典
+ (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString {
  if (jsonString == nil) {
    return
  NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
  NSError *
  NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
   options:NSJSONReadingMutableContainers
   error:&error];
  if(error) {
    NSLog(@"json解析失败:%@",error);
    return
  return
此方法稍作变换,也可输出数组,主要看json格式。
9.字典转JSON
+ (NSString*)dictionaryToJson:(NSDictionary *)dic
NSError *error =
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic                                  options:NSJSONWritingPrettyPrinted                                  error:&error];
return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
10.对处理过的properties一般需要做缓存
& & &定义一个字典缓存,缓存处理过的properties,重复使用是不需要重复计算,用空间换时间。例如在归档的时候需要获得属性名列表,然后遍历归档、解挡。其他中间操作也需要用到properties。
水平有限,错误之处,欢迎大家指正。互相学习。转载请注明出处
阅读(...) 评论()一段JSON,如何进行解析 - ITeye问答
从sFlow-rt提供的REST API得到了一段JSON数据,如何进行解析呢?
{
"17.ifInmulticastpkts": 0,
"17.ifindex": "17",
"17.ifindiscards": 0,
"17.ifinerrors": 0,
"17.ifinoctets": 0,
"17.ifinucastpkts": 0,
"17.ifoutdiscards": 0,
"17.ifouterrors": 0,
"17.ifoutoctets": 0,
"17.ifoutucastpkts": 0,
"17.ifspeed": ,
"17.iftype": "ethernetCsmacd",
"19.ifInmulticastpkts": 0,
"19.ifindex": "19",
"19.ifindiscards": 0,
"19.ifinerrors": 0,
"19.ifinoctets": 0,
"19.ifinucastpkts": 0,
"19.ifoutdiscards": 0,
"19.ifouterrors": 0,
"19.ifoutoctets": 0,
"19.ifoutucastpkts": 0,
"19.ifspeed": ,
"19.iftype": "ethernetCsmacd",
"21.ifInmulticastpkts": 0,
"21.ifindex": "21",
"21.ifindiscards": 0,
"21.ifinerrors": 0,
"21.ifinoctets": 0,
"21.ifinucastpkts": 0,
"21.ifoutdiscards": 0,
"21.ifouterrors": 0,
"21.ifoutoctets": 0,
"21.ifoutucastpkts": 0,
"21.ifspeed": ,
"21.iftype": "ethernetCsmacd",
"23.ifInmulticastpkts": 0,
"23.ifindex": "23",
"23.ifindiscards": 0,
"23.ifinerrors": 0,
"23.ifinoctets": 0,
"23.ifinucastpkts": 0,
"23.ifoutdiscards": 0,
"23.ifouterrors": 0,
"23.ifoutoctets": 0,
"23.ifoutucastpkts": 0,
"23.ifspeed": ,
"23.iftype": "ethernetCsmacd"
}
也就是每组数字对应的一个model,但是没有在JSON中分开,这样的JSON如何进行解析,谢谢各位大神。
采纳的答案
public class JSon2ModelTest {
public static void main(String[] args) {
Map&String,String& map = new HashMap&String,String&();
map.put("1.xx", "1xx");
map.put("1.yy", "1yy");
map.put("1.zz", "1zz");
map.put("2.xx", "2xx");
map.put("2.yy", "2yy");
map.put("2.zz", "2zz");
map.put("3.xx", "3xx");
map.put("3.yy", "3yy");
map.put("3.zz", "3zz");
String str=JSON.toJSON(map).toString();
Map&String,String& m=JSON.parseObject(str, Map.class);
Set&String& s=m.keySet();
Iterator&String& it=s.iterator();
//缓存分组后的数据的map对象
Map&String,List&String&& mm=new HashMap&String,List&String&&();
//缓存分组后的数据的map对象的key
List&String& listKey=new ArrayList&String&();
//初始化缓存的map对象开始
List&String& listInit=new ArrayList&String&();
String t = it.next();
String initKey = t.substring(0,t.indexOf("."));
listKey.add(initKey);
listInit.add(t);
mm.put(initKey, listInit);
//初始化缓存的map对象结束
for(;it.hasNext();){
String str2 = it.next();
String temp = str2.substring(0,str2.indexOf("."));
if(mm.containsKey(temp)){
mm.get(temp).add(str2);
List&String& ll = new ArrayList&String&();
listKey.add(temp);
mm.put(temp, ll);
这是测试的代码,你可以参考一下
转成Map对象,取出来keySet,然后根据条件将keySet分组,然后根据分组后的keySet从Map对象里获取值,组装成VO对象就好了呀
JSONObject jo = new JSONObject(sFlow-rt);
String 17.ifInmulticastpkts= jo.getString("17.ifInmulticastpkts");
....
....
其他都一样
用 json-org.jar
取出来后,再根据.进行分割再处理
一个在线的json格式化视图工具,很方便:
/go.php?u=/jsonviewernew/
已解决问题
未解决问题

我要回帖

更多关于 ios jsonmodel使用 的文章

 

随机推荐