【iOS】json数据解析以及简单的网络数据请求

文章目录

  • 前言
  • 一、json数据解析
  • 二、简单的网络数据请求
  • 三、实现访问API得到网络数据
  • 总结


前言

近期写完了暑假最后一个任务——天气预报,在里面用到了简单的网络数据请求以及json数据的解析,特此记录博客总结

一、json数据解析

JSON是一种轻量级的数据格式,一般用于数据交互。目前JSON的使用非常广泛,绝大多数网络请求都采用了JSON格式。
举个例子:

{
  "code": "200",
  "updateTime": "2021-11-15T16:35+08:00",
  "fxLink": "http://hfx.link/2ax1",
  "daily": [
    {
      "fxDate": "2021-11-15",
      "sunrise": "06:58",
      "sunset": "16:59",
      "moonrise": "15:16",
      "moonset": "03:40",
      "moonPhase": "盈凸月",
      "moonPhaseIcon": "803",
      "tempMax": "12",
      "tempMin": "-1",
      "iconDay": "101",
      "textDay": "多云",
      "iconNight": "150",
      "textNight": "晴",
    },
    {
      "fxDate": "2021-11-16",
      "sunrise": "07:00",
      "sunset": "16:58",
      "moonrise": "15:38",
      "moonset": "04:40",
      "moonPhase": "盈凸月",
      "moonPhaseIcon": "803",
      "tempMax": "13",
      "tempMin": "0",
      "iconDay": "100",
      "textDay": "晴",
      "iconNight": "101",
      "textNight": "多云",
    }
  ],
  "refer": {
    "sources": [
      "QWeather",
      "NMC",
      "ECMWF"
    ],
    "license": [
      "QWeather Developers License"
    ]
  }
}

这就是我们利用API请求到的json数据,接下来我们对其进行解释


JSON的格式很像Objective-C中的字典和数组,标准JSON格式key必须用双引号包裹起来。像上述数据中的code,updateTime都是字典中的key。我们用一张图来解释我们的json数据:
在这里插入图片描述
例如在上面的json数据中,daily就相当于我们的NSArray,数组中的每一个元素的类型都是NSDictionary(字典)
搞清楚json数据中每个数据的类型后,我们就要去得到对应的数据,具体怎么得到将会在下文讲解完简单的网络数据请求后一并解释,在此我们只需要知道json数据在OC中对应的数据类型即可

二、简单的网络数据请求

在学习网络数据请求之前,我们有必要先了解两个概念:URL和API

API(应用程序编程接口)和URL(统一资源定位器)之间有密切的关系,但它们代表了不同的概念。

URL是用于定位资源在网络上的地址,它描述了资源的位置和访问方式。在Web中,URL通常用于标识和定位网页、图片、视频或其他文件。一个标准的URL通常由协议(例如HTTP或HTTPS)、主机名(例如www.example.com)、可选的端口号、文件路径和查询参数组成。例如:https://www.example.com/api/get_data。

API是一组规定的规则和协议,用于不同软件应用程序之间的通信和交互。API定义了应用程序如何请求和交换信息。在Web开发中,API通常以URL的形式提供,通过HTTP请求发送给服务器,并以JSON或XML等格式返回数据。API允许开发人员访问远程服务的功能或数据,而不需要了解底层的实现细节。

因此,URL可以被视为API的一部分。URL是实现访问API的重要组成部分,它是指向API的网络地址,用于标识和定位API的特定功能和资源。通过构建和发送HTTP请求到API的URL,可以实现与API的交互,请求数据或执行操作。

API一般是通过URL的形式进行访问,API相当于一种接口,而URL则是我们访问相应API所必须的参数


接下来笔者简单讲解一下iOS进行简单的网络数据请求的六步

  1. 创建API的URL:构建API的URL,包括指定基本地址、路径和查询参数等。
  2. 创建一个NSURL对象:使用URL字符串来创建NSURL对象,以便在请求中使用。
  3. 创建NSURLRequest:使用NSURL对象创建一个NSURLRequest对象,该对象将包含请求的类型(GET、POST等)和其他必要的信息。
  4. 创建NSURLSession:初始化NSURLSession来管理网络会话,它是发送请求的主要组件。
  5. 创建NSURLSessionDataTask:使用NSURLSession创建一个NSURLSessionDataTask对象,用于发送网络请求,并在请求完成后接收数据。
  6. 处理请求结果:在请求完成后,处理服务器返回的数据并进行相应的处理,例如解析数据或更新UI。
// 引入头文件
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 1. 创建API的URL
    NSString *urlString = @"https://api.example.com/data"; // 请替换为实际的API地址
    
    // 2. 创建NSURL对象
    NSURL *url = [NSURL URLWithString:urlString];
    
    // 3. 创建NSURLRequest
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    // 4. 创建NSURLSession
    NSURLSession *session = [NSURLSession sharedSession];
    
    // 5. 创建NSURLSessionDataTask
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            // 处理请求出错
            NSLog(@"Error: %@", error.localizedDescription);
        } else {
            // 6. 处理请求结果(这里简单地将返回的数据转为字符串并输出)
            NSString *responseData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"Response: %@", responseData);
            
            // 如果需要解析JSON数据,可以使用NSJSONSerialization类进行解析
            // NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
        }
    }];
    
    // 7. 启动数据任务
    [dataTask resume];
}

@end

需要注意的是这里只是最简单的GET请求,后续还会有POST请求等知识,笔者以后学到再进行补充


同时我们注意我们的第四步的方法也可以用
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;这个方法来实现,其与[NSURLSession sharedSession]方法的区别在于后者只能用于简单的网络请求,而前者可以允许您使用自定义配置来创建会话,并且可以设置代理来处理相关事件

假设我们的API需要进行HTTP基本认证(Basic Authentication),我们需要在请求中包含用户名和密码。在这种情况下,我们可以在 NSURLSessionDelegate 中实现URLSession:task:didReceiveChallenge:completionHandler: 方法来处理认证。

#import "ViewController.h"

@interface ViewController () <NSURLSessionDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 1. 创建API的URL
    NSString *urlString = @"https://api.example.com/data"; // 请替换为实际的API地址
    
    // 2. 创建NSURL对象
    NSURL *url = [NSURL URLWithString:urlString];
    
    // 3. 创建NSURLSessionConfiguration
    NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
    
    // 4. 创建NSURLSession并设置代理
    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    
    // 5. 创建NSURLSessionDataTask
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            // 处理请求出错
            NSLog(@"Error: %@", error.localizedDescription);
        } else {
            // 处理请求结果(这里简单地将返回的数据转为字符串并输出)
            NSString *responseData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"Response: %@", responseData);
        }
    }];
    
    // 6. 启动数据任务
    [dataTask resume];
}

#pragma mark - NSURLSessionDelegate

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
    
    // 这里我们处理HTTP基本认证(Basic Authentication)
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]) {
        
        // 在这里设置您的用户名和密码
        NSString *username = @"your_username";
        NSString *password = @"your_password";
        
        // 创建NSURLCredential对象
        NSURLCredential *credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceForSession];
        
        // 调用完成处理程序,将凭据传递给会话
        completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
    }
}

@end

同样的,在第五步中,我们同样可以使用两种方法来进行我们的数据请求
在这里插入图片描述

dataTaskWithRequest:completionHandler: 方法需要您自己创建和配置一个 NSURLRequest 对象,然后将其作为参数传递给该方法,以实现更多自定义和配置的选项。
dataTaskWithURL:completionHandler: 方法更为简洁,只需要传递一个 NSURL 对象,即请求的目标URL,而不需要自己创建和配置 NSURLRequest 对象。这个方法是发送GET请求的快捷方式,适用于简单的数据获取

但是在实际代码中我们更推荐使用第一种方法进行请求,因为我们的POST与GET一般结合在一起使用,也许GET方法可以不用到Request,但是POST方法一定会用到,这里的讲解等后面学到了具体写博客进行讲解,这里给出POST的栗子:

- (void)sendPOSTRequest {
    // 1. 创建API的URL
    NSString *urlString = @"https://api.example.com/post_endpoint"; // 请替换为实际的POST请求的URL
    
    // 2. 创建NSURL对象
    NSURL *url = [NSURL URLWithString:urlString];
    
    // 3. 创建NSMutableURLRequest对象,并设置HTTP方法为POST
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"POST"];
    
    // 4. 如果有需要,设置HTTP请求头,例如Content-Type等
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    
    // 5. 如果有参数或需要发送数据,可以将其添加到HTTP请求体中
    NSDictionary *parameters = @{@"key1": @"value1", @"key2": @"value2"};
    NSError *error;
    NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:&error];
    if (!error) {
        [request setHTTPBody:postData];
    } else {
        NSLog(@"Error creating POST data: %@", error.localizedDescription);
        return;
    }
    
    // 6. 创建NSURLSession,并发送POST请求
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            // 处理请求出错
            NSLog(@"Error: %@", error.localizedDescription);
        } else {
            // 处理请求结果
            NSString *responseData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"Response: %@", responseData);
        }
    }];
    
    // 7. 启动数据任务
    [dataTask resume];
}


三、实现访问API得到网络数据

讲解完我们的基本的网络数据请求的步骤,我们以我们上面的以我们上面的json数据为例来进行一个简单的网络数据请求:

{
  "code": "200",
  "updateTime": "2021-11-15T16:35+08:00",
  "fxLink": "http://hfx.link/2ax1",
  "daily": [
    {
      "fxDate": "2021-11-15",
      "sunrise": "06:58",
      "sunset": "16:59",
      "moonrise": "15:16",
      "moonset": "03:40",
      "moonPhase": "盈凸月",
      "moonPhaseIcon": "803",
      "tempMax": "12",
      "tempMin": "-1",
      "iconDay": "101",
      "textDay": "多云",
      "iconNight": "150",
      "textNight": "晴",
    },
    {
      "fxDate": "2021-11-16",
      "sunrise": "07:00",
      "sunset": "16:58",
      "moonrise": "15:38",
      "moonset": "04:40",
      "moonPhase": "盈凸月",
      "moonPhaseIcon": "803",
      "tempMax": "13",
      "tempMin": "0",
      "iconDay": "100",
      "textDay": "晴",
      "iconNight": "101",
      "textNight": "多云",
    }
  ],
  "refer": {
    "sources": [
      "QWeather",
      "NMC",
      "ECMWF"
    ],
    "license": [
      "QWeather Developers License"
    ]
  }
}

例如我们想要的到json数据中的fxDate,首先我们需要使用
+ (nullable id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
将我们的访问API得到的二进制数据 data 解析为 NSDictionary 对象(或 NSArray 对象)。根据上面的知识我们可以知道我们需要将其解析为NSDictionary。于是我们使用如下代码先来解析我们的整个json数据
NSDictionary *weatherData = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

然后我们可以知道我们字典中对应的“daily”键的类型实际上是一个NSArray对象,我们要想得到fxDate,首先需要访问daily,于是我们用如下代码得到daily NSArray *dailyArray = weatherData[@"daily"];

由于我们的daily数组中的每个对象类型都NSDictionary,于是我们可以使用如下代码得到我们数组中所有的fxDate

for (NSDictionary *currentDayData in dailyArray) {  
     NSString *timeString = currentDayData[@"fxDate"]; // 时间
     NSLog(@"%@", timeString);
}

得到我们如下的结果:
在这里插入图片描述
给出完整代码供大家参考:

    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
              // 请求出错处理
          } else {
              NSDictionary *weatherData = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
              if (error) {
                  // 解析数据出错处理
              } else {
                  // 解析数据成功
                  NSArray *dailyArray = weatherData[@"daily"];
                      for (NSDictionary *currentDayData in dailyArray) {
                          NSString *timeString = currentDayData[@"fxDate"]; // 时间
                          NSLog(@"%@", timeString);
                      }
                      NSLog(@"无法获取当前时间的天气数据。");
                  }
              }
          }
      }];

总结

笔者在这里简单了讲解了一下基本的网络数据请求,实际上随着iOS的发展出现了许多第三方库例如JSONModel等,可以让我们更加方便的解析json以及请求网络数据,另外还有网络数据请求的POST用法笔者还不甚了解,后面学到会一并总结

json数据来源:
和风每日天气

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/58542.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vulnhub靶机Empire_LupinOne

下载地址&#xff1a;https://www.vulnhub.com/entry/empire-lupinone,750/ 主机发现 arp-scan -l nmap --min-rate 10000 -p- 192.168.21.137 nmap -sV -sT -O -p22,80 192.168.21.137 nmap --scriptvuln -p22,80 192.168.21.137 先看一下网页 啥也没有 先看一下nmap扫出来的…

10.物联网操作系统之低功耗管理

一。低功耗管理概念及其应用 1.STM32低功耗设计详解 STM32的电源管理系统主要分为&#xff1a; 备份域 调压器供电电路 ADC电源电路 2.低功耗模式 1.运行模式 2.睡眠模式 3.停机模式 4.待机模式 &#xff08;1&#xff09;睡眠模式 在睡眠模式中&#xff0c;仅关闭了内核时钟&…

带你简单认识淘宝 API 接口,API接口适用场景和业务类型

淘宝 API 接口是为开发电商类应用程序而设计的一套完整的、跨浏览器、跨平台的接口规范。通过开放接口&#xff0c;开发者可以不改变现有系统&#xff0c;直接在原有系统上实现新功能。该规范于 2007 年发布&#xff0c;是目前业界唯一完整覆盖电商系统各相关业务领域的接口标准…

Flutter运行app时向logcat输出当前打开的界面路径且点击可跳转

当一个项目大了目录文件多了&#xff0c;我们往往会为了找到一个文件花费大量的时间和精力&#xff0c;为了快捷方便的调试我们的项目&#xff0c;我们往往需要在打开app运行的时候需要知道当前打开的界面的文件在哪儿&#xff0c;我们这个代码就能快捷的知道我们app正在打开的…

iTOP-RK3568开发板Windows 安装 RKTool 驱动

在烧写镜像之前首先需要安装 RKTool 驱动。 RKTool 驱动在网盘资料“iTOP-3568 开发板\01_【iTOP-RK3568 开发板】基础资料 \02_iTOP-RK3568 开发板烧写工具及驱动”路径下。 驱动如下图所示&#xff1a; 解压缩后&#xff0c;进入文件夹&#xff0c;如下图所示&#xff1a;…

电缆故障综合测试仪

一、电缆故障查找仪产品简介 本产品用于地埋电缆故障点的快速、企业产品免费信息发布平台定位、电缆埋设路径及埋设深度的电子商务测&#xff08;在故障点处获取深度&#xff09;。 主要特点 1、用特殊结构的声波振动传感器及低噪声专用器件作前置放大&#xff0c;提高了仪器定…

性价比高的学生用台灯 盘点性价比高的学生护眼台灯

护眼台灯在这些年来已经逐渐淘汰掉了传统的灯泡台灯&#xff0c;和大部分普通台灯&#xff0c;成为现在许多孩子学习桌上的一员。但仍然有不少人对护眼台灯提出质疑&#xff0c;也有不少人仍在观望。原因当然不是被价格劝退&#xff0c;而是听闻了市面上的护眼台灯伤眼的案例&a…

SAN共享存储架构

SAN共享存储架构 概述 近年在高性能专用存储网络需求的驱使下&#xff0c;许多SAN存储系统应用于高性能计算网络系统、大型网站系统、非线性编辑系统等网络系统中&#xff0c;存储设备与计算机主机系统之间一对一的关系&#xff0c;被可供多个计算机主机共享读写同一个存储设…

Nacos 抽取公共配置

文章目录 创建一个公共配置文件其他配置文件引用springboot配置文件 创建一个公共配置文件 其他配置文件引用 ${变量} springboot配置文件 spring:cloud:nacos:discovery:server-addr: current.ip:8848namespace: word_register_proconfig:server-addr: current.ip:8848auto-r…

【2023 华数杯全国大学生数学建模竞赛】 C题 母亲身心健康对婴儿成长的影响 Python代码实现

【2023 华数杯全国大学生数学建模竞赛】 C题 母亲身心健康对婴儿成长的影响 1 题目 母亲是婴儿生命中最重要的人之一&#xff0c;她不仅为婴儿提供营养物质和身体保护&#xff0c; 还为婴儿提供情感支持和安全感。母亲心理健康状态的不良状况&#xff0c;如抑郁、焦虑、压力等…

算法通过村第二关-链表白银笔记|指定区间反转

文章目录 前言链表反转|指定区间内头插法&#xff1a;穿针引线法&#xff1a; 总结 前言 提示&#xff1a;人啊&#xff0c;果然跟花一样&#xff0c;开花前的等待无比漫长&#xff0c;绽放的魅力却转瞬即逝。 链表反转|指定区间内 参考题目&#xff1a;92. 反转链表 II - 力…

【Apollo学习笔记】—— 相机仿真

文章目录 前言相关代码整理 测试实践文件目录包管理BUILD文件以及cyberfile.xml文件源程序BUILD运行结果其他参考CameraOutput channels启动camera驱动启动camera video compression驱动 前言 本文是对Cyber RT的学习记录,文章可能存在不严谨、不完善、有缺漏的部分&#xff0…

Redis 6.0的新特性:多线程、客户端缓存与安全

2020年5月份&#xff0c;6.0版本。 面向网络处理的多IO线程可以提高网络请求处理的速度&#xff0c;而客户端缓存可以让应用直接在客户端本地读取数据&#xff0c;这两个特性可以提升Redis的性能。 细粒度权限控制让Redis可以按照命令粒度控制不同用户的访问权限&#xff0c;…

云服务器SVN仓库搭建(以阿里云为例)

远程连接阿里云服务器 安装svn(注意需要root权限使用命令sudo su) yum install subversion 安装成功后查看svn版本 svnserve --version 创建版本库的根目录 mkdir /var/svn 创建代码仓库 svnadmin create /var/svn/test 当前生成的目录结构 此处为svn的配置文件 创建用户名…

【Kubernetes】Kubernetes的部署

kubernetes 一、Kubernetes 的安装部署1. 常见的安装部署方式1.1 Minikube1.2 Kubeadm1.3 二进制安装部署2. K8S 部署 二进制与高可用的区别2.1 二进制部署2.2 kubeadm 部署二、Kubernetes 二进制部署过程1. 服务器相关设置以及架构2. 操作系统初始化配置3. 部署 etcd 集群4. 部…

数据结构【第3章】——线性表

线性表的定义 线性表&#xff1a;零个或多个数据元素的有限序列。 1&#xff09;线性表是一个序列。即元素之间是有顺序的&#xff0c;若元素存在多个&#xff0c;则第一个元素无前驱&#xff0c;最后一个元素无后继&#xff0c;其他每个元素都有且只有一个前驱和后继。 2&a…

问道管理:两市股指冲高回落,沪指一度突破3300点,券商、保险板块领涨

8月4日&#xff0c;两市股指高开高走&#xff0c;沪指一度突破3300点。开盘后&#xff0c;沪指、深成指涨近1%&#xff0c;创业板指、上证50指数涨幅超1%。职业方面&#xff0c;券商、稳妥板块领涨&#xff0c;传媒、石油、半导体、银行、煤炭等板块均上扬&#xff0c;互联金融…

三、JVM-如何判断对象已死问题

内存模型以及如何判定对象已死问题 体验与验证 2.4.5.1 使用visualvm visualgc插件下载链接 &#xff1a;https://visualvm.github.io/pluginscenters.html 选择对应JDK版本链接—>Tools—>Visual GC 若上述链接找不到合适的&#xff0c;大家也可以自己在网上下载对应…

2023年电赛A题报告模板--可直接使用

任务 图1 任务内容 要求 图2 基本要求内容 图3 发挥部分内容 说明 图4 说明内容 评分标准 图5 评分内容 正文 &#xff08;部分&#xff09; 摘要 本实验旨在设计和制作一个由两个单相逆变器组成的并联系统&#xff0c;用于为电阻负载供电或并入220V电网。采用基于STM…

某银行软件测试笔试题

&#xff08;时间90分钟&#xff0c;满分100分&#xff09; 考试要求&#xff1a;计算机相关专业试题 一、填空题&#xff08;每空1分&#xff0c;共10分&#xff09; 1. ______验证___是保证软件正确实现特定功能的一系列活动和过程。 2. 按开发阶段分&#xff0c;软件测试可…