【iOS_Swift_Alamofire实现网络请求】

news2024/11/7 3:29:29

文章目录

  • 前言
    • 导入库
    • 原生网络请求
    • 单例封装一个原生网络请求
    • Alamofire
      • 用法
      • Alamofire的返回响应
      • 将返回的data转为字典/字符串
  • 总结

前言

学习swift继续延续之前的思路,对照着OC学,从UI起手,学习到对应的自适应布局。
今天再次学习了swift的原生网络请求和对应的第三方库-Alamofire。

导入库

  • 因为电脑配置原因,学习了一种新的导入第三方库的方法。Swift Package Manager
  • 首先去库的官网的readme文件找到请添加图片描述
  • 复制最下面的Swift Package Manager的url。
  • 到项目的General的framework
    请添加图片描述
  • 请添加图片描述
  • 左下角Add Other Package
  • 请添加图片描述
  • 请添加图片描述
    在右上角输入网址搜索到库,add即可。

原生网络请求

  • 原生的网络请求和OC的思路是一模一样的,创建url,构建请求,发送请求,得到数据即可。
 // 普通的网络请求
    func makeLogon() {
        // 构建URL
        let url:URL = URL(string: "https://news-at.zhihu.com/api/4/news/latest")!
        // 发送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("Request Erroor")
                return
            }
            let dataString =  String(data: data, encoding: String.Encoding.utf8)
            let dict = self.getDictionaryFromJSONString(jsonString: dataString!)
            print(dict)
        }
        task.resume()
    }

这段代码是使用 URLSession 发起 GET 请求,并将返回的数据转换为字典类型。

  1. 首先,通过 session.dataTask(with:completionHandler:) 方法创建一个任务对象,并在闭包中处理请求的结果。

  2. 在闭包中,首先使用可选绑定 guard let 检查请求的返回数据 data 是否存在,以及响应 response 是否存在且是 URLResponse 类型,并检查是否有错误 error。如果其中任何一个条件不满足,就会打印错误信息并返回。

  3. 如果没有错误,我们将返回的数据 data 使用 String(data:encoding:) 方法转换为字符串类型,并存储在 dataString 变量中。

  4. 接下来,调用 getDictionaryFromJSONString(jsonString:) 方法将字符串类型的数据 dataString 转换为字典类型。

  5. 最后,打印转换后的字典 dict

getDictionaryFromJSONString(jsonString:) 是一个自定义的方法,用于将 JSON 字符串转换为字典类型。

  • 因为请求的数据不是字典类型的,我们需要为它写一个转字典的方法。
 func getDictionaryFromJSONString(jsonString: String) -> NSDictionary {
        // 将传入的 JSON 字符串 jsonString 使用 data(using:) 方法转换为 Data 类型
        let jsonData:Data = jsonString.data(using: .utf8)!
        // 通过 JSONSerialization.jsonObject(with:options:) 方法将 jsonData 进行 JSON 解析,并将解析结果存储在 dict 变量中。这里使用的选项是 .mutableContainers,表示可以修改容器对象
        let dict = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers)
        // 使用条件语句判断 dict 是否为 nil。如果不为 nil,表示 JSON 解析成功,将 dict 强制转换为 NSDictionary 类型,并返回。
      //   如果 dict 为 nil,表示 JSON 解析失败,返回一个空的 NSDictionary 对象。
        if dict != nil {
            return dict as! NSDictionary
        }
        return NSDictionary()
    }
    

请添加图片描述

单例封装一个原生网络请求

这里还是以get请求为例,请求一下知乎日报的接口

  • 创建单例类
    请添加图片描述
  • 初始化
static let shareSingenal = Mananger()

构建函数,发送请求

这里用到了swift的闭包来写succeed或者failure的回调。

用到了if let 语法:很安全

  func getWithPath(path: String,paras: Dictionary<String,Any>?,success: @escaping ((_ result: Any) -> ()),failure: @escaping ((_ error: Error) -> ())) {
//            var i = 0
            let address = path
            // 首先,定义了变量 i 和 address,用于拼接完整的 URL 地址。
//            if let paras = paras {
//                for (key,value) in paras {
//                    if i == 0 {
//                        address += "?\(key)=\(value)"
//                    }else {
//                        address += "&\(key)=\(value)"
//                    }
//                    i += 1
//                }
//            }
            // 完成参数拼接后,通过 URL(string:) 方法将拼接后的 address 转换为 URL 对象。
            let url = URL(string: address.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!)
            
            // 使用 URLSession.shared 创建一个共享的会话对象,并通过 dataTask(with:completionHandler:) 方法发起网络请求。
            let session = URLSession.shared
            let dataTask = session.dataTask(with: url!) { (data, respond, error) in
                if let data = data {
                    // 在网络请求的回调闭包中,首先判断返回的数据 data 是否存在。如果存在,则通过 JSONSerialization.jsonObject(with:options:) 方法将数据进行 JSON 解析,并将解析结果传递给成功回调闭包 success。
                    if let result = try? JSONSerialization.jsonObject(with: data, options: .allowFragments){
                        success(result)
                    }
                }else {
                    // 如果数据不存在,即请求失败,将错误信息 error 传递给失败回调闭包 failure。
                    failure(error!)
                }
            }
            // 通过调用 dataTask.resume() 方法开始执行网络请求。
            dataTask.resume()
        }
}

Alamofire

  • Alamofire是使用Swift语言开发的网络库,它和AFNetworking很像
  • Alamofire使用链式编程实现的。具有简洁的语法,良好的性能和优秀的可读性等特点。
  • Alamofire,本质上是基于NSURLSession进行封装的,其核心是URLSessionURLSessionTask子类。其早期版本使用Alamofire.request(),5.0之后使用AF.request()。

本质上第三方库是为了减轻我们的压力,缩减了请求过程的代码。

用法

最基础的就是发送一个GET请求

 func sendReqWithAlamofire() -> Void {
   let url: URL = URL(string: "https://news-at.zhihu.com/api/4/news/latest")!
     AF.request(url).response { response in
            switch response.result {
            case let .success(data):
                print("data:\(String(describing: data))")
            case let .failure(error):
                print(error)
            }
     }
}

能看出来,已经帮我们封装好了succeed和failure的回调。

这里需要注意,打印上述data。请添加图片描述

  • Alamofire 中,responsedata 属性是一个可选类型 Data?。因此,打印结果中显示的 Optional 表示该值是可选的。而 3643 bytes 表示返回的数据的字节数,这个值会根据实际返回的数据大小而变化。
  • 下面说如何转字典

针对AF的request请求接口,Alamofire封装了三个同名接口,三个接口是针对不同的参数进行设置的。

open func request(_ convertible: URLConvertible,
                      method: HTTPMethod = .get,
                      parameters: Parameters? = nil,
                      encoding: ParameterEncoding = URLEncoding.default,
                      headers: HTTPHeaders? = nil,
                      interceptor: RequestInterceptor? = nil,
                      requestModifier: RequestModifier? = nil)
 
open func request<Parameters: Encodable>(_ convertible: URLConvertible,
                                             method: HTTPMethod = .get,
                                             parameters: Parameters? = nil,
                                             encoder: ParameterEncoder = URLEncodedFormParameterEncoder.default,
                                             headers: HTTPHeaders? = nil,
                                             interceptor: RequestInterceptor? = nil,
                                             requestModifier: RequestModifier? = nil)
 
open func request(_ convertible: URLRequestConvertible, interceptor: RequestInterceptor? = nil)

参数一: convertible(可变化)一个可变化的参数。其实就是请求的url地址。
参数二:method 请求方式。就是我们常说的GET,POST。
参数三:parameters 请求参数。业务数据的参数部分,如登录模块的userNamePassword等之类的业务数据。
参数四:encoding 编码方式。Alamofire支持两种编码方式:

  • JSONParameterEncoder和- URLEncodedFormParameterEncoder若encoding设置为JSONEncoding, 即为JSON格式。

参数五: headers 请求头参数。http请求中请求头的参数设置,支持Json格式,例如设置tokencookie等参数。这个还是根据接口不同来写不同的需求。
参数六: interceptor 请求拦截器,主要用来在请求流程中拦截请求,并对请求进行一些必要的处理,(没用过)
参数七:requestModifier 请求修改器。在请求流程中修改数据,例如针对特定请求,不使用默认超时时间,而自定义超时时间

Alamofire的返回响应

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

 
 let url: URL = URL(string: "https://news-at.zhihu.com/api/4/news/latest")!
//Data示例
AF.request(url).responseData { response in
    switch response.result {
   case let .success(data):
       print("data:\(String(describing: data))")
   case let .failure(error):
       print(error)
  }
}
 
//String示例
AF.request(url).responseString { response in
    switch response.result {
   case let .success(data):
       print("data:\(String(describing: data))")
   case let .failure(error):
       print(error)
  }
}
 
//JSON示例
AF.request(url).responseJSON { response in
    switch response.result {
   case let .success(data):
       print("data:\(String(describing: data))")
   case let .failure(error):
       print(error)
  }
}
 
//自定义格式示例
struct PersonResponse: Decodable { let name: String,  let nickName : String, let 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)
  }
}

将返回的data转为字典/字符串

语言的安全性很强,还是先使用了if let结构,也是在succeed的回调里面使用的

  func sendReqWithAlamofire() -> Void {
            let url: URL = URL(string: "https://news-at.zhihu.com/api/4/news/latest")!
            AF.request(url).response { response in
                    switch response.result {
                      // 涉及到了语言的安全性
                    case let .success(data):
                        print("Successd get ReqWithAla")
                        print(data as Any)
                       //  转字符串
                        if let responseData = data {
                            let dataString = String(data: responseData, encoding: .utf8)
                            print("data: \(String(describing: dataString))")
                        }
//                        print("data:\(String(describing: data))")
                        // 转字典
                        if let responseData = data {
                            do {
                                // 首先使用可选绑定 if let 检查 data 是否存在。如果 data 存在,我们尝试使用 JSONSerialization.jsonObject(with:options:) 方法将数据解析为字典类型。
                                if let jsonToDict = try JSONSerialization.jsonObject(with: responseData, options: []) as? [String: Any] {
                                    // 使用转换后的字典进行进一步操作
                                    print("data: \(jsonToDict)")
                                }
                            } catch {
                                // 解析失败,会抛出异常,我们可以使用 catch 块来捕获异常并进行相应的错误处理。
                                print("Failed to parse JSON: \(error)")
                            }
                        }

                    case let .failure(error):
                        print(error)
                    }
             }
            
        }

}


总结

和AFN库一样使用起来简单快捷,swift的语言特性安全在很多处都会体现,接下来会学习swift的原声json Model解析库。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL分库分表全攻略:从小白到大神的进阶指南!

大家好&#xff0c;我是小米&#xff0c;一个热爱技术的程序员。今天&#xff0c;我来和大家聊一下关于MySQL中的分库分表技术&#xff0c;相信对于开发者和DBA来说是一个非常重要的话题。 什么是分库分表 首先&#xff0c;我们先来了解一下什么是分库分表。分库分表是指将原本…

Apifox(1)比postman更优秀的接口自动化测试平台

Apifox介绍 Apifox 是 API 文档、API 调试、API Mock、API 自动化测试一体化协作平台&#xff0c;定位 Postman Swagger Mock JMeter。通过一套系统、一份数据&#xff0c;解决多个系统之间的数据同步问题。只要定义好 API 文档&#xff0c;API 调试、API 数据 Mock、API 自…

scratch躲避陨石 中国电子学会图形化编程 少儿编程 scratch编程等级考试三级真题和答案解析2023年5月

目录 scratch躲避陨石 一、题目要求 1、准备工作 2、功能实现 二、案例分析

性能测试计划,怎么写显得你能更专业?

性能测试计划 性能测试是一种非常重要的测试类型&#xff0c;用于确定系统或应用程序在特定负载下的性能指标。以下是一个性能测试计划的建议步骤&#xff1a; 目标 首先&#xff0c;定义性能测试的目标和范围。这包括测试的系统或应用程序以及所需测试的性能指标&#xff0…

基于蒙特卡洛模拟法的电动汽车充电负荷研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

开源项目的流程

开源的好处 增加知名度和使用量&#xff1a;开源项目可以让更多人知道和使用&#xff0c;进而增加项目的知名度和使用量。提高代码质量&#xff1a;开源项目需要接受有可能来自全球的开发者审核和参与&#xff0c;这样可以使得项目代码得到更多高质量的反复审查和改进。快速修…

计算机视觉 | 目标检测与MMDetection

目 录 目标检测的基本范式 滑窗使用卷积实现密集预测锚框多尺度检测与FPN 单阶段&无锚框检测器选讲 RPNYOLO、SSDFocal loss 与 RetinaNetFCOSYOLO系列选讲 一、目标检测的基本范式 1、什么是目标检测 给定一张图片 ——》用矩形框框出所感兴趣的物体同时预测物体类…

前后端交互一、服务器概念与初识Ajax

零、文章目录 前后端交互一、服务器概念与初识Ajax 1、上网的过程 网络相关知识请参考网络详解HTTP相关知识请参考HTTP详解 &#xff08;1&#xff09;客户端与服务器 **上网的目的&#xff1a;**通过互联网获取和消费资源 **服务器&#xff1a;**上网过程中&#xff0c;负…

基于STM32的智能粮仓系统设计

一、项目背景 随着粮食质量要求的提高和储存方式的改变&#xff0c;对于粮仓环境的监测和控制也愈发重要。在过去的传统管理中&#xff0c;通风、防潮等操作需要定期人工进行&#xff0c;精度和效率都较低。而利用嵌入式技术和智能控制算法进行监测和控制&#xff0c;不仅能够…

【Git】git push origin master时发生的各类错误汇总

文章目录 一、常见的git命令二、错误一三、错误二四、错误三五、问题解决 一、常见的git命令 使用 git 命令时&#xff0c;您可以执行一系列操作来管理代码仓库。下面是一些常用的 git 命令及其功能&#xff1a; git init: 在当前目录初始化一个新的 git 仓库。git clone <…

2023年5月青少年机器人技术等级考试理论综合试卷(二级)

青少年机器人技术等级考试理论综合试卷&#xff08;二级&#xff09;2023.6 分数&#xff1a; 100 题数&#xff1a; 45 一、 单选题(共 30 题&#xff0c; 共 60 分) 1.下图中的凸轮机构使用了摆动型从动件的是&#xff1f; &#xff08; &#xff09; A.a B.b C.c D.d 试题类…

我是怎么劝退打算入行软件测试的同学的?

过去千篇一律的机构、文章都在劝大家入行软件测试——门槛低、工资高、加班少&#xff01;而这两年&#xff0c;受国内外形势、经济影响&#xff0c;整个IT行业都在走下坡路&#xff0c;被专家们称作行业回归理性发展。最近机构劝入行测试的帖子少了&#xff0c;而“我是在xxx如…

【Python 继承和多态】零基础也能轻松掌握的学习路线与参考资料

Python 继承和多态是面向对象编程中非常关键的概念。继承是一种创建新类的方法&#xff0c;通过继承一个已有的类来创建新类。而多态则是指不同的对象以不同的方式对同一消息作出响应的能力。在这篇文章中&#xff0c;我们将为您介绍 Python 继承和多态的学习路线&#xff0c;并…

d2l学习_第三章线性回归/欠拟合过拟合/权重衰减

x.1 Linear Regression Theory x.1.1 Model 线性回归的模型如下&#xff1a; 我们给定d个特征值 x 1 , x 2 , . . . , x d x_1, x_2, ..., x_d x1​,x2​,...,xd​&#xff0c;最终产生输出yhat&#xff0c;我们产生的yhat要尽量拟合原来的值y&#xff0c;在这一拟合过程中我…

【MySQL】数据库的增删改查、备份、还原等基本操作

【MySQL】数据库的基本操作 一、创建数据库---create1.1 字符集与校验规则1.1.1 查看系统默认字符集以及校验规则1.1.2 默认方式建立数据库1.1.3 指定编码集建立数据库 1.2 建库的本质 二、查看数据库及其相关属性---show2.1 显示所有数据库2.2 显示数据库的创建语句3.2 显示目…

Yarn【多队列实例、任务优先级设置】

前言 我们知道&#xff0c;Hadoop常见的三种调度器&#xff1a;FIFO调度器&#xff08;几乎不用&#xff0c;因为它是先来先服务&#xff09;、容量调度器&#xff08;Apache Hadoop 默认的调度器&#xff09;、公平调度器&#xff08;CDH默认调度器&#xff09;。 其中&…

PyTorch实战7:咖啡豆识别--手动搭建VGG16

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;365天深度学习训练营-第P7周&#xff1a;咖啡豆识别&#x1f356; 原作者&#xff1a;K同学啊|接辅导、项目定制 目录 一、 前期准备1. 设置GPU2. 导入数据3. 划分数…

Zookeeper节点操作

ZooKeeper的节点操作 ZooKeeper的节点类型 ZooKeeper其实也是一个分布式集群&#xff0c;其中维护了一个目录树结构&#xff0c;在这个目录树中&#xff0c;组成的部分是一个个的节点。ZooKeeper的节点可以大致分为两种类型: 短暂类型 和 持久类型 短暂类型ephemeral: 客户端…

Creating Add-in Hooks (C#)

本文介绍如何使一个文件在添加、检入、检出到库时&#xff0c;让add-in 程序在SOLIDWORKS PDM Professional 中通知到你。 注意&#xff1a; 因为 SOLIDWORKS PDM Professional 无法强制重新加载Add-in程序 &#xff0c;必须重新启动所有客户端计算机&#xff0c;以确保使用最…

电力综合自动化系统在煤矿领域的设计与应用

安科瑞虞佳豪 持续的高温&#xff0c;给能源保供带来严峻的考验。针对南方部分地区电力供应紧张的局面&#xff0c;煤炭资源大省山西&#xff0c;在确保安全生产的基础上&#xff0c;积极协调增产保供。 这几天&#xff0c;南方多地持续高温&#xff0c;用电量达到高峰。在山西…