Swift下将网络返回json数据转换成struct
假如网络请求返回的数据结构是一个深层嵌套的Json
首先要通过key-value取出这个json中的数据源
// 将返回的json字符串转Dictory
let json = """
{
"name": "jack",
"age": 20,
"description": "A student."
}
""".data(using: .utf8)!
if let jsonData = jsonString.data(using: .utf8) {
do {
let json = try JSONSerialization.jsonObject(with: jsonData, options: [])
if let dictionary = json as? [String: Any],
let key2 = dictionary["key2"] as? [String: Any],
let innerKey2 = key2["key2"] as? [String: Any],
let value = innerKey2["key1"] as? String {
print(value) // 输出"value3"
}
} catch {
print("解析JSON数据失败:(error)")
}
}
数模转换
// 定义数据类型,遵守Codable协议
// 注意定义的类型与接口返回对应,否则JSONSerialization时崩溃
// Struct模型可以根据json中的数据关系对应嵌套
struct ContactSimpleModel: Codable {
var relation: String
var name: String struct ContactSimpleModel1: Codable {
var relation: String
var name: String struct ContactSimpleModel2: Codable {
var relation: String
var name: String
} }
}

字典与struct互相转换

将字典转换成struct模型
根据网络返回的Dictory,从里面取出数组widgets: Array<[String: Any]>
1.map遍历数组,拿到每一个数组元素字典
2.处理每个元素,先使用JSONSerialization.data(withJSONObject:将字典转成data,
3.再使用JSONDecoder().decode(ContactSimpleModel.self, from: data)将data转成struct结构体。
4.使用struct模型
let decoder = JSONDecoder()
let resList = try widgets.map { (item) -> AdJsonModel in
let data = try JSONSerialization.data(withJSONObject: item, options: [])
let res = try decoder.decode(AdJsonModel.self, from: data)
return res
}
return resList
struct模型转字典
也可以通过给Encodable协议加默认实现,提供便捷Struct转字典方法
// 扩展 Encodable 协议
extension Encodable {
var dictionary: [String: Any]? {
if let data = try? JSONEncoder().encode(self) {
if let dict = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {
return dict
}
return nil
}
return nil
} }
 
Struct本地缓存
假如没有使用数据库,通过UserDefaults或者Plist文件保存。
使用data进行保存到UserDefaults
struct Person: Codable {
var name: String
var age: Int
} var people = [Person(name: "John", age: 30), Person(name: "Mary", age: 25)]
//转成data保存
let data = try! JSONEncoder().encode(people)
UserDefaults.standard.set(data, forKey: "peopleData")
//取
if let data = UserDefaults.standard.data(forKey: "peopleData") {
let people = try! JSONDecoder().decode([Person].self, from: data)
}
使用Dictionary保存到Plist文件
本地文件处理
路径判断,创建目录用Url.path
创建目录案例
    lazy var adListDirPath: String? = {
let documentDic = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let adUrl = documentDic?.appendingPathComponent(":ad")
if let adUrlSub = adUrl {
var isDic: ObjCBool = ObjCBool(false)
// 判断adUrlSub.path路径是否存在,如果是文件路径则isDic=false, 如果是目录路径isDic=true
if FileManager.default.fileExists(atPath: adUrlSub.path, isDirectory: &isDic) && isDic.boolValue {
return adUrlSub.absoluteString
} do {
// 如果路径不存在,则创建本地路径,withIntermediateDirectories: true表示如果路径中间有未创建的,则把中间的目录也创建
try FileManager.default.createDirectory(at: adUrlSub, withIntermediateDirectories: true, attributes: nil)
return adUrlSub.absoluteString
} catch {
Logger.error(":adDataManager", content: error.localizedDescription)
return nil
}
}
return nil
}()
写文件要用Url.absoluteString
swift中保存plist文件,使用NSDictionary进行保存

1.先删除历史文件
do {
try FileManager.default.removeItem(at: filePathUrl)
return true
} catch {
Logger.error(":adDataManager", content: error.localizedDescription)
return false
}
2.保存新文件
NSDictionary(object: adList, forKey: adListRootKey).write(to: filePathUrl, atomically: true)
3.读取本地文件
let dict = try NSDictionary(contentsOf: filePathUrl, error: ())
zip文件解压
  func unzipFile() {
let zipPath = "/path/to/zip/file"
let destinationPath = "/path/to/destination/folder"
do {
try ZipArchive.unzipFile(atPath: zipPath, toDestination: destinationPath)
} catch {
print("Error unzipping file: (error.localizedDescription)")
}
}
先缓存后使用,提高用户体验
SDWebImage的先预下载图片,等启动时直接使用缓存的方法
//0.自定义设置缓存大小
URLCache.shared = URLCache(memoryCapacity: 10 * 1024 * 1024, diskCapacity: 50 * 1024 * 1024, diskPath: nil)
//1.缓存
SDWebImage批量下载图片
SDWebImagePrefetcher.shared().prefetchURLs方法下载的图片本地路径默认是Library/Caches/com.hackemist.SDWebImageCache.default目录下的缓存文件。
可以通过SDWebImageManager.shared().imageCache.diskCachePath方法获取具体路径。
//2.使用
在UIImageView加载图片时,使用AAImageView.sd_setImage(with: url, placeholderImage: nil)进行价值
注意:
对于可选类型的数组,如果没有拆包就map, 那么闭包的入参是拆包的数组
let list = dict[adListRootKey] as? Array<[String: Any]>
if let listSub = list {
let decoder = JSONDecoder()
let resList = listSub.map { (item) -> AdJsonModel? in

Swift下Data处理全流程:从网络下载,数模转换,本地缓存到页面使用的更多相关文章

  1. CentOS下搭建wordpress全流程

    突然,想搭建一个个人博客,所以就在网上搜了搜相关内容,好多人推荐wordpress,那么就打算光荣地采用wordpress了.以下是安装过程中遇到的所有的坑,现在总结如下,希望给安装wordpress ...

  2. 简述前后端分离的情况下,Vue实现点击图片下载到本地(并实现IE11浏览器的兼容)

    1.简述 在前后端分离的项目中涉及跨域问题,通常都会使用token进行验证.最近在前后端分离的项目中在一个问题上搞了很久,就是以前下载附件或者导出数据为文件的时候,在以前的那些项目前端可以直接用 wi ...

  3. 探讨下如何更好的使用缓存 —— Redis缓存的特殊用法以及与本地缓存一起构建多级缓存的实现

    大家好,又见面了. 本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面.如果感兴趣,欢迎关注以获取后续更新. 通过前面的文章,我们一起剖析了Guav ...

  4. iOS网络加载图片缓存与SDWebImage

    加载网络图片可以说是网络应用中必备的.如果单纯的去下载图片,而不去做多线程.缓存等技术去优化,加载图片时的效果与用户体验就会很差. 一.自己实现加载图片的方法 tips: *iOS中所有网络访问都是异 ...

  5. python 网络爬虫全流程教学,从入门到实战(requests+bs4+存储文件)

    python 网络爬虫全流程教学,从入门到实战(requests+bs4+存储文件) requests是一个Python第三方库,用于向URL地址发起请求 bs4 全名 BeautifulSoup4, ...

  6. canvas 制作flappy bird(像素小鸟)全流程

    flappy bird制作全流程: 一.前言 像素小鸟这个简单的游戏于2014年在网络上爆红,游戏上线一段时间内appleStore上的下载量一度达到5000万次,风靡一时, 近年来移动web的普及为 ...

  7. 【CKB.DEV 茶话会】第二期:聊聊 CKB 钱包和 Nervos DAO 全流程

    CKB.DEV 茶话会第二期:聊聊 CKB 钱包和 Nervos DAO 全流程 为了鼓励更多优秀的开发者和研究人员参与到 CKB 的开发和生态建设中去,我们希望组织一系列 CKB Developer ...

  8. Kafka处理请求的全流程分析

    大家好,我是 yes. 这是我的第三篇Kafka源码分析文章,前两篇讲了日志段的读写和二分算法在kafka索引上的应用 今天来讲讲 Kafka Broker端处理请求的全流程,剖析下底层的网络通信是如 ...

  9. Jenkins+GitLab+SonnarQube搭建CI/CD全流程

    1. CI/CD 1.1 CI - 持续集成 持续集成( Continuous integration , 简称 CI )指的是,频繁地(一天多次)将代码集成到主干.持续集成的目的就是让产品可以快速迭 ...

  10. HMS Core电商与游戏行业解决方案,全流程赋能开发者创新

    2021年12月29日,"华为云&华为终端云服务创新峰会2022"在北京柏悦酒店成功举办.华为HMS Core电商与游戏行业解决方案亮相本次峰会的线下展区,为行业开发者们解 ...

随机推荐

  1. linux 部署轻量级堡垒机Next Terminal

    对比 类似的开源堡垒机有 Teleport,Jumpserver,Next Terminal等等. Teleport 安全性最好,较轻量,但是对被管理资产不透明,纳管前需要双向认证,在资产设备上需额外 ...

  2. NFS存储安装配置

    一.NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种, 它允许网络中的计算机之间通过TCP/IP网络共享资源.在NFS的应用中,本地NFS的客 户 ...

  3. vue3 ThreeJS 引入obj模型过暗的问题

    当我单纯地用MTLLoader引入材质, OBJLoader引入模型并添加到场景中时, 发现模型非常得暗. 需要将环境光的强度设置到3.5左右看起来才比较正常. 但正常情况下环境光的值不应该超出1.  ...

  4. CanvasScaler的三种适配模式——缩放模式(Scale with Screen Size)

    一.含义 根据屏幕尺寸进行缩放,随着屏幕尺寸进行放大缩小 二.参数介绍 第一个参数一般是美术人员根据游戏主要面向的手机市场,比如安卓市场,用市场上最常用的分辨率作为制作UI图片的标准.这里填的数就是美 ...

  5. maven 多模块项目的测试覆盖率分析 - jacoco 聚合分析

    前言 对于大多数 maven 多模块化工程,可以使用 Jacoco 这款工具,关于 Jacoco 这款工具,ChatGPT 对它的描述是这样的: JaCoCo(Java Code Coverage)是 ...

  6. 一文快速回顾 Servlet、Filter、Listener

    什么是Servlet? 前置知识: Web 服务器:可以指硬件上的,也可以指软件上的.从硬件的角度来说, Web 服务器指的就是一台存储了网络服务软件的计算机:从软件的角度来说, Web 服务器指的是 ...

  7. Less8-Less10 时间注入

    Less-8和Less-5使用的是一样的布尔盲注,为了学习,这里我们使用时间盲注 Less-8 这里使用到了mysql中的if语句,格式为if(条件,正确执行,错误执行) 实例如图: sleep(秒速 ...

  8. Javaweb学习笔记第十五弹--Listente概述、AJAX、Axiox、JSON

    Listener(监听器) 可以在application.session和request三个对象创建 Javaweb提供了8个监听器,其中较为典型的是ServletContextListener监听器 ...

  9. 用Python基于Google Bard做一个交互式的聊天机器人

    用Python基于Google Bard做一个交互式的聊天机器人 之前已经通过浏览器试过了 Google Bard ,更多细节请看: Try out Google Bard, Will Google ...

  10. TS 基础及在 Vue 中的实践:TypeScript 都发布 5.0 版本啦,现在不学更待何时!

    大家好,我是 Kagol,OpenTiny 开源社区运营,TinyVue 跨端.跨框架组件库核心贡献者,专注于前端组件库建设和开源社区运营. 微软于3月16日发布了 TypeScript 5.0 版本 ...