欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS学习笔记-147.网络07——NSURLConnection04_简单JSON的解析

程序员文章站 2022-05-16 10:23:54
网络07——nsurlconnection04_简单json的解析 前面,我们获取到了数据,数据的格式是json字符串。那么我们如何把它转成我们的oc对象呢?这就是我们接下来...

网络07——nsurlconnection04_简单json的解析

前面,我们获取到了数据,数据的格式是json字符串。那么我们如何把它转成我们的oc对象呢?这就是我们接下来学习的。

一、什么是json

json是一种轻量级的数据格式,一般用于数据交互

服务器返回给客户端的数据,一般都是json格式或者xml格式(文件下载除外)

json的格式很像oc中的字典和数组

{"name" : "jack", "age" : 10}
{"names" : ["jack", "rose", "jim"]}

标准json格式的注意点:key必须用双引号

要想从json中挖掘出具体数据,得对json进行解析

json 转换为 oc数据类型


二、json – oc 转换对照表

 

json oc
大括号 { } nsdictionary
中括号 [ ] nsarray
双引号 ” “ nsstring
数字 10、10.8 nsnumber

三、json解析方案

在ios中,json的常见解析方案有4种

第三方框架:jsonkit、sbjson、touchjson(性能从左到右,越差)

苹果原生(自带):nsjsonserialization(性能最好)


四、nsjsonserialization的常见方法

4.1 json数据 → oc对象

//第一个参数:json的二进制数据
//第二个参数:
//第三个参数:错误信息

//nsjsonreadingoptions说明-----------
//nsjsonreadingmutablecontainers = (1ul << 0), 可变字典和数组
//nsjsonreadingmutableleaves = (1ul << 1),      内部所有的字符串都是可变的 ios7之后又问题  一般不用
//nsjsonreadingallowfragments = (1ul << 2)   既不是字典也不是数组,则必须使用该枚举值

+ (id)jsonobjectwithdata:(nsdata *)data options:(nsjsonreadingoptions)opt error:(nserror **)error;

4.2 oc对象 → json数据

//第一个参数:要转换的oc对象
//第二个参数:选项nsjsonwritingprettyprinted 排版 美观
+ (nsdata *)datawithjsonobject:(id)obj options:(nsjsonwritingoptions)opt error:(nserror **)error;

使用例如

-(void)octojson{
    nsarray *mode = @[@"123",@"456"];
    nsdata *data = [nsjsonserialization datawithjsonobject:mode options:nsjsonwritingprettyprinted error:nil];
    nslog(@"%@",[[nsstring alloc]initwithdata:data encoding:nsutf8stringencoding]);
}

注意:并不是所有的oc对象都能转换为json

最外层必须是 nsarray or nsdictionary

所有的元素必须是 nsstring, nsnumber, nsarray, nsdictionary, or nsnull

字典中所有的key都必须是 nsstring类型的

nsnumbers不能是无穷大

4.3 isvalidjsonobject 判断oc能否转json

+ (bool)isvalidjsonobject:(id)obj;

五、登陆接口的简单装换

5.1 分析

我们请求登陆接口 ios学习笔记-143.网络03——自己搭建的后台登陆接口文档 后返回json类型的二进制数据。我们可以通过 nsjsonserialization 上面说的的 + (id)jsonobjectwithdata:(nsdata *)data options:(nsjsonreadingoptions)opt error:(nserror **)error; 方法,把它转为oc对象,主要的代码是

nsdictionary * dict = [nsjsonserialization jsonobjectwithdata:data options:nsjsonreadingmutablecontainers error:nil];

由前面,或者接口文档,我们可以知道,返回的数据转为字符串以后是如下的样子

{
    "code": 200,
    "msg": "登录成功",
    "t": {
        "username": "qiwenming",
        "clienttype": "1"
    }
}

那么我们上面转换的地址拿到的数据就这这个样子的。那么我们想要获取我们的 code,怎么获取呢??

可以通过字典拿到 dict[@”code”] 。其次我们的 t 又是一个字典,我们可以把它转为一个对象。

当然我们也可以这样,把最外城数据装换为一个oc对象,这个对象里面包含,我们的 t 这个oc 对象。

对应的,我们们创建了两个对应的类,分别是qwmloginmodeqwmloginsuccessmode

5.2 qwmloginmode

5.2.1 qwmloginmode.h

//
//  qwmloginmode.h
//  002_json解析
//
//  created by 杞文明 on 17/9/13.
//  copyright ? 2017年 杞文明. all rights reserved.
//

#import 
#import "qwmloginsuccessmode.h"

@interface qwmloginmode : nsobject
@property(nonatomic,strong)nsstring *msg;
@property(nonatomic,strong)nsnumber *code;
@property(nonatomic,strong)qwmloginsuccessmode *t;

+(instancetype)initwithdict:(nsdictionary*)dict;
@end


5.2.2 qwmloginmode.m

//
//  qwmloginmode.m
//  002_json解析
//
//  created by 杞文明 on 17/9/13.
//  copyright ? 2017年 杞文明. all rights reserved.
//

#import "qwmloginmode.h"

@implementation qwmloginmode

+(instancetype)initwithdict:(nsdictionary*)dict{
    qwmloginmode * mode = [[qwmloginmode alloc]init];
    [mode setvaluesforkeyswithdictionary:dict];
    mode.t = [qwmloginsuccessmode initwithdict:[dict valueforkey:@"t"]];
    return mode;
}
@end


5.3 qwmloginmode

5.3.1 qwmloginmode.h


//
//  qwmloginsuccessmode.h
//  002_json解析
//
//  created by 杞文明 on 17/9/13.
//  copyright ? 2017年 杞文明. all rights reserved.
//

#import 

@interface qwmloginsuccessmode : nsobject
@property(nonatomic,strong)nsstring* username;
@property(nonatomic,strong)nsstring* clienttype;
+(instancetype)initwithdict:(nsdictionary*)dict;
@end

5.3.2 qwmloginmode.m

//
//  qwmloginsuccessmode.m
//  002_json解析
//
//  created by 杞文明 on 17/9/13.
//  copyright ? 2017年 杞文明. all rights reserved.
//

#import "qwmloginsuccessmode.h"

@implementation qwmloginsuccessmode
+(instancetype)initwithdict:(nsdictionary*)dict{
    qwmloginsuccessmode * mode = [[qwmloginsuccessmode alloc]init];
    [mode setvaluesforkeyswithdictionary:dict];
    return mode;
}
@end


5.4 控制器的代码

//
//  viewcontroller.m
//  002_json解析
//
//  created by 杞文明 on 17/9/12.
//  copyright ? 2017年 杞文明. all rights reserved.
//

#import "viewcontroller.h"
#import "nsstring+md5.h"
#import "qwmloginmode.h"

//登陆请求地址
#define loginurl @"https://127.0.0.1:8080/qwmapi/login"
@interface viewcontroller ()

@end

@implementation viewcontroller

-(void)touchesbegan:(nsset *)touches withevent:(uievent *)event{
    [self jsontooc];
//    [self octojson];
}

-(void)jsontooc{
    //1.设置url
    nsurl *url = [nsurl urlwithstring:loginurl];

    //2.创建请求对象
    nsmutableurlrequest *request = [nsmutableurlrequest requestwithurl:url];
    //设置请求方法
    request.httpmethod = @"post";
    //设置请求头
    [request setvalue:@"2" forhttpheaderfield:@"qwm-client-type"];
    //设置请求体
    nsstring *params = [nsstring stringwithformat:@"username=qiwenming&password=%@",[@"123456" md5_32bitlower]];
    request.httpbody = [params datausingencoding:nsutf8stringencoding];

    //3.发送异步请求
    [nsurlconnection sendasynchronousrequest:request queue:[nsoperationqueue mainqueue] completionhandler:^(nsurlresponse * _nullable response, nsdata * _nullable data, nserror * _nullable connectionerror) {
        /*
              第一个参数:json的二进制数据
              第二个参数:
              第三个参数:错误信息
             */
        /*
              nsjsonreadingoptions------------------
              nsjsonreadingmutablecontainers = (1ul << 0), 可变字典和数组
              nsjsonreadingmutableleaves = (1ul << 1),      内部所有的字符串都是可变的 ios7之后又问题  一般不用
              nsjsonreadingallowfragments = (1ul << 2)   既不是字典也不是数组,则必须使用该枚举值
             */
        nsdictionary * dict = [nsjsonserialization jsonobjectwithdata:data options:nsjsonreadingmutablecontainers error:nil];

        qwmloginmode * mode =[qwmloginmode initwithdict:dict];
        nslog(@"%@",mode.code);
        nslog(@"%@",mode.msg);
        nslog(@"%@",mode.t.clienttype);
        nslog(@"%@",mode.t.username);

    }];
}

-(void)octojson{
//    qwmloginsuccessmode *mode = [[qwmloginsuccessmode alloc]init];
//    mode.clienttype = @"1";
//    mode.username =@"wiming";
//    nsstring *mode = @"wenidngding";
    //注意:并不是所有的oc对象都能转换为json
    /*
       - 最外层必须是 nsarray or nsdictionary
       - 所有的元素必须是 nsstring, nsnumber, nsarray, nsdictionary, or nsnull
       - 字典中所有的key都必须是 nsstring类型的
       - nsnumbers不能是无穷大
     */
    nsarray *mode = @[@"123",@"456"];
    nsdata *data = [nsjsonserialization datawithjsonobject:mode options:nsjsonwritingprettyprinted error:nil];
    nslog(@"%@",[[nsstring alloc]initwithdata:data encoding:nsutf8stringencoding]);
}

@end

5.5 打印结果

[30895:167756] 200
[30895:167756] 登录成功
[30895:167756] 2
[30895:167756] qiwenming