编程进阶网编程进阶网
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 01.UIKit框架学习
  • 02.UIViewController
  • 03.iOS工程面板说明
  • 04.基础控件Swift版
  • 05.手势的处理逻辑
  • 06.通信设计和实践
  • 07.Swift数据的存储
  • 09.Swift版网络请求
  • 10.Swift版数据存储
  • 11.Swift版多媒体实践
  • 12.Swift与ObjC互调
  • 13.Swift多线程开发
  • 14.Swift版SnapKit布局
  • 16.开发SDK实践
  • 17.iOS项目经验积累
  • 18.Swift版grpc请求

09.Swift版网络请求

目录介绍

  • 01.网络请求常见库
  • 02.普通GET请求
  • 03.普通POST请求
  • 04.Alamofire请求
  • 05.Json解析实践
  • 06.将json转结构体
  • 10.参考博客说明

01.网络请求常见库

看看在Swift中是在怎样请求数据,解析数据加载图片这些的,也使我们最基本最常见的用法了,先说说这几个三方库:

  1. 第一个: Alamofire Git地址:https://github.com/Alamofire/Alamofire
  2. 第二个: SwiftyJSON 一个解析JSON数据的三方库,使用swift写的,很简便(推荐!) Git地址: https://github.com/SwiftyJSON/SwiftyJSON
  3. 第三个: Kingfisher (一个图片加载的国产库。重点是国产的的支持!) Git地址:https://github.com/onevcat/Kingfisher/releases

02.普通GET请求

可以使用URLSession来进行普通的GET请求。以下是一个简单的示例代码,演示如何发送GET请求并处理响应:

  1. 首先创建一个URL对象,指定要发送GET请求的目标URL
  2. 使用URLSession.shared创建一个URLSession对象。
  3. 使用URLSession的dataTask方法创建一个数据任务。在数据任务的回调闭包中,我们可以处理响应数据、错误和HTTP响应状态码。
  4. 回调闭包中,首先检查是否有错误发生。然后,我们检查HTTP响应的状态码,如果状态码为200(表示成功),我们可以解析响应数据。
  5. 最后,调用task.resume()来启动任务。
// 构建URL
let url:URL = URL(string: "https://www.wanandroid.com/article/list/0/json")!
// 发送HTTP请求的的session对象
let session = URLSession.shared
// 构建请求request
var request = URLRequest(url: url)
request.httpMethod = "GET"
// 发一个get请求
let task = session.dataTask(with: request as URLRequest) {(
    data, response, error) in
    guard let data = data, let _:URLResponse = response, error == nil else {
        print("error")
        return
    }
    let dataString =  String(data: data, encoding: String.Encoding.utf8)
    let dict = self.getDictionaryFromJSONString(jsonString: dataString!)
    print("网络请求数据:")
    print(dict);
}
task.resume()

03.普通POST请求

可以使用URLSession来进行普通的POST请求。以下是一个简单的示例代码,演示如何发送POST请求并处理响应:

  1. 首先创建一个URL对象,指定要发送POST请求的目标URL。然后,我们使用URLSession.shared创建一个URLSession对象。
  2. 创建一个URLRequest对象,并将其httpMethod属性设置为"POST"。我们还可以设置请求头、请求体数据等。
  3. 使用JSONSerialization将参数字典转换为JSON数据,并将其设置为请求的httpBody。
  4. 使用URLSession的dataTask方法创建一个数据任务。在数据任务的回调闭包中,我们可以处理响应数据、错误和HTTP响应状态码。
  5. 在回调闭包中,首先检查是否有错误发生。然后,检查HTTP响应的状态码,如果状态码为200(表示成功),我们可以解析响应数据。
  6. 最后,我们调用task.resume()来启动任务。
// 这里直接使用 jsonString 转成字典,然后转成 Data
// 将 流 放到 request的 httpBody中, 模拟发送一个http请求
let jsonString = "{\"username\":\"yangchong\",\"password\":\"yc123456\"}"
let dict = self.getDictionaryFromJSONString(jsonString: jsonString)
print(dict)
var  jsonData = NSData()
do {
    jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted) as NSData
} catch {
    print(error.localizedDescription)
}
// 构建URL
let url:URL = URL(string: "https://www.wanandroid.com/user/login")!
// session
let session = URLSession.shared
// request
var request = URLRequest(url: url)
// 必须指定是post请求方式
request.httpMethod = "POST"
// 设置Content-Length,非必须
request.setValue("\(jsonData.length)", forHTTPHeaderField: "Content-Length")
// 设置 Content-Type 为 json 类型
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
// POST    请求将 数据 放置到 请求体中
request.httpBody = jsonData as Data
// 发送请求
let task = session.dataTask(with: request as URLRequest) {(
    data, response, error) in
    guard let data = data, let _:URLResponse = response, error == nil else {
        print("error")
        return
    }
    // 返回值 utf8 转码
    let dataString =  String(data: data, encoding: String.Encoding.utf8)
    // 将 jsonString 转成字典
    let dict = self.getDictionaryFromJSONString(jsonString: dataString!)
    print(dict)
}
task.resume()

04.Alamofire请求

Alamofire支持4种返回响应处理方式:Data、String、 JSON、自定义类型。

//使用网络库Alamofire做get请求
let url: URL = URL(string: "https://www.wanandroid.com/article/list/0/json")!
//Alamofire支持4种返回响应处理方式:Data、String、 JSON、自定义类型。
//Data示例
AF.request(url).responseData { response in
    switch response.result {
    case let .success(data):
        print("data1:\(String(describing: data))")
    case let .failure(error):
        print(error)
    }
}

//String示例
AF.request(url).responseString { response in
    switch response.result {
    case let .success(data):
        print("data2:\(String(describing: data))")
        DispatchQueue.main.async {
            self.textView.text = "data2:\(String(describing: data))"
        }
    case let .failure(error):
        print(error)
    }
}

//JSON示例
AF.request(url).responseJSON { response in
    switch response.result {
    case let .success(data):
        print("data3:\(String(describing: data))")
    case let .failure(error):
        print(error)
    }
}

//自定义格式示例
struct PersonResponse: Decodable { var name: String,  var nickName : String, var age : Int }
AF.request(url).responseDecodable(of: PersonResponse.self) { response in
    switch response.result {
    case let .success(data):
        print("data:\(String(describing: data))")
    case let .failure(error):
        print(error)
    }
}

request请求接口方法,源码中参数含义

  1. 参数一: convertible(可变化)一个可变化的参数。其实就是请求的url地址。
  2. 参数二:method 请求方式。就是我们常说的GET,POST。
  3. 参数三:parameters 请求参数。业务数据的参数部分,如登录模块的userName,Password等之类的业务数据。
  4. 参数四:encoding 编码方式。
  5. 参数五: headers 请求头参数。http请求中请求头的参数设置,支持Json格式,例如设置token,cookie等参数。这个还是根据接口不同来写不同的需求。
  6. 参数六: interceptor 请求拦截器,主要用来在请求流程中拦截请求,并对请求进行一些必要的处理,(没用过)
  7. 参数七:requestModifier 请求修改器。在请求流程中修改数据,例如针对特定请求,不使用默认超时时间,而自定义超时时间

然后来看一个POST请求的案例

let url:URL = URL(string: "https://www.wanandroid.com/user/login")!
let params: [String: Any] = [
    "username": "yangchong",
    "password": "yc123456"
]
AF.request(url,method: .post,parameters: params).responseString { response in
    switch response.result {
    case let .success(data):
        print("data2:\(String(describing: data))")
        DispatchQueue.main.async {
            self.textView.text = "data2:\(String(describing: data))"
        }
    case let .failure(error):
        print(error)
    }
}

05.Json解析实践

要使用SwiftyJSON将JSON字符串解析为结构体,需要先定义一个与JSON数据结构相匹配的结构体。然后,使用SwiftyJSON来解析JSON字符串并将其映射到结构体对象上。

有以下JSON字符串:

{
  "name": "John Doe",
  "age": 30,
  "email": "johndoe@example.com"
}

定义一个结构体来表示这个JSON数据的结构:

import SwiftyJSON

struct Person {
    let name: String
    let age: Int
    let email: String
    
    init(json: JSON) {
        name = json["name"].stringValue
        age = json["age"].intValue
        email = json["email"].stringValue
    }
}

可以使用SwiftyJSON来解析JSON字符串并将其映射到Person结构体对象上:

let jsonString = """
{
  "name": "打工充",
  "age": 30,
  "email": "yangchong211@163.com"
}
"""

if let jsonData = jsonString.data(using: .utf8) {
    do {
        let json = try JSON(data: jsonData)
        let person = Person(json: json)
        print("Name: \(person.name)")
        print("Age: \(person.age)")
        print("Email: \(person.email)")
        
        DispatchQueue.main.async {
            self.textView.text = person.description
        }
    } catch {
        print("Error parsing JSON: \(error)")
    }
}

如何快速打印结构体全部内容呢,这个时候可以用到CustomStringConvertible协议,如下所示:

extension Person: CustomStringConvertible {
    var description: String {
        let mirror = Mirror(reflecting: self)
        var description = "\(mirror.subjectType) - "
        for (label, value) in mirror.children {
            if let label = label {
                description += "\(label): \(value), "
            }
        }
        // 去除最后一个逗号和空格
        if description.hasSuffix(", ") {
            description = String(description.dropLast(2))
        }
        return description
    }
}

06.将json转结构体

10.参考博客说明

  • iOS_Swift_Alamofire实现网络请求:https://blog.csdn.net/weixin_61639290/article/details/131116785
  • swift 使用Alamofire 来封装一个网络请求 原创:https://blog.51cto.com/u_16175520/11947672
贡献者: yangchong211
上一篇
07.Swift数据的存储
下一篇
10.Swift版数据存储