企业网站建设价钱,家政服务网站做推广有效果吗,做视频网站需要哪些条件,公司网站有哪些重要性Json数据处理是开发中不可获取的一项技能#xff0c;如果你不会处理json数据#xff0c;那你离失业就不远了#xff0c;所以学完了swift基础教程#xff0c;还是先老老实实学习一下json处理吧#xff0c;有了这项技能#xff0c;你才可以继续下一个网络请求阶段的开发如果你不会处理json数据那你离失业就不远了所以学完了swift基础教程还是先老老实实学习一下json处理吧有了这项技能你才可以继续下一个网络请求阶段的开发因为网络请求大部分都是依赖json数据传输的。 JSONDecoder
JSONDecoder是Swift标准库中的一个类用于将JSON数据解码为Swift中的自定义数据类型或者将swift中的数据类型转化为JSON字符串。它提供了一种简单、类型安全的方式来处理JSON数据可以将JSON数据转换为Swift中的结构体、类或枚举。
注意几个知识点 JSON序列化
将swift中的自定义结构体数据转化为json字符串定义一个Person结构体创建一个这个结构体实例然后使用JSONDecoder序列化为String字符串 // json 序列化
func jsonToStr() {print(json 转为字符串)struct Person: Codable {let name: Stringlet age: Intlet email: String}// 创建结构体实例let per2 Person(name: EmployA, age: 18, email: johnexample.com)// 创建jsonEncoderlet jsonEncoder JSONEncoder()// 将结构体实例per2转为Datalet jsonData try? jsonEncoder.encode(per2)print(jsonData: \(String(describing: jsonData)))// 将data转为Stringlet jsonString String(data: jsonData!, encoding: .utf8)!print(jsonString: \(jsonString))
}JSON反序列化
将Json字符串转化为swift里面的结构体创建一个json字符串然后使用JSONDecoder将字符串反序列化为结构体数据
// json 反序列化
func jsonDecode() {print(json 数据解码)struct Person: Codable {let name: Stringlet age: Intlet email: String}let jsonStr {name: John,age: 30,email: johnexample.com}// 将json字符串转换为Datalet jsonData jsonStr.data(using: .utf8)// JSONDecoderlet decoder JSONDecoder()// 使用decoder将Data转为结构体let per1 try! decoder.decode(Person.self, from: jsonData!)print(person name: \(per1.name))print(person age: \(per1.age))print(persn email: \(per1.email))
}
完整代码示例 源代码
import SwiftUIfunc getFood() - String {return [, , , , , , , , , ].randomElement()!
}// json 反序列化
func jsonDecode() {print(json 数据解码)struct Person: Codable {let name: Stringlet age: Intlet email: String}let jsonStr {name: John,age: 30,email: johnexample.com}// 将json字符串转换为Datalet jsonData jsonStr.data(using: .utf8)// JSONDecoderlet decoder JSONDecoder()// 使用decoder将Data转为结构体let per1 try! decoder.decode(Person.self, from: jsonData!)print(person name: \(per1.name))print(person age: \(per1.age))print(persn email: \(per1.email))
}// json 序列化
func jsonToStr() {print(json 转为字符串)struct Person: Codable {let name: Stringlet age: Intlet email: String}// 创建结构体实例let per2 Person(name: EmployA, age: 18, email: johnexample.com)// 创建jsonEncoderlet jsonEncoder JSONEncoder()// 将结构体实例per2转为Datalet jsonData try? jsonEncoder.encode(per2)print(jsonData: \(String(describing: jsonData)))// 将data转为Stringlet jsonString String(data: jsonData!, encoding: .utf8)!print(jsonString: \(jsonString))
}struct ContentView: View {State var food var body: some View {VStack {Spacer()Spacer()Spacer()Text(food).font(.system(size: 80))Spacer()Button(action: {food getFood()}, label: {Text(今天吃啥).padding().foregroundColor(.white).font(/*START_MENU_TOKEN*/ .title/*END_MENU_TOKEN*/)}).background(.orange).cornerRadius(10)Button(action: {print(解码json)jsonDecode()}, label: {Text(解码JSON).font(/*START_MENU_TOKEN*/ .title/*END_MENU_TOKEN*/).foregroundColor(.white).padding()}).background(.pink).cornerRadius(10)Button(action: {jsonToStr()}, label: {Text(编码JSON).font(/*START_MENU_TOKEN*/ .title/*END_MENU_TOKEN*/).foregroundColor(.white).padding()}).background(.blue).cornerRadius(10)Spacer()Spacer()Spacer()}}
}拓展知识点
1.可选属性类型
如果你自定义的类型有一个逻辑上允许值为空的存储型属性——无论是因为它无法在初始化时赋值还是因为它在之后某个时机可以赋值为空——都需要将它声明为 可选类型。可选类型的属性将自动初始化为 nil表示这个属性是特意在构造过程设置为空。
下面例子中定义了类 SurveyQuestion它包含一个可选 String 属性 response
class SurveyQuestion {var text: Stringvar response: String?init(text: String) {self.text text}func ask() {print(text)}
}let cheeseQuestion SurveyQuestion(text: Do you like cheese?)
cheeseQuestion.ask()
// 打印“Do you like cheese?”
cheeseQuestion.response Yes, I do like cheese.
调查问题的答案在询问前是无法确定的因此我们将属性 response 声明为 String? 类型或者说是 “可选类型 String“。当 SurveyQuestion 的实例初始化时它将自动赋值为 nil表明“暂时还没有字符“。 2.构造过程中常量属性的赋值
你可以在构造过程中的任意时间点给常量属性赋值只要在构造过程结束时它设置成确定的值。一旦常量属性被赋值它将永远不可更改。 注意 对于类的实例来说它的常量属性只能在定义它的类的构造过程中修改不能在子类中修改。 你可以修改上面的 SurveyQuestion 示例用常量属性替代变量属性 text表示问题内容 text 在 SurveyQuestion 的实例被创建之后不会再被修改。尽管 text 属性现在是常量我们仍然可以在类的构造器中设置它的值
class SurveyQuestion {let text: Stringvar response: String?init(text: String) {self.text text}func ask() {print(text)}
}
let beetsQuestion SurveyQuestion(text: How about beets?)
beetsQuestion.ask()
// 打印“How about beets?”
beetsQuestion.response I also like beets. (But not with cheese.) 3.默认构造器
如果结构体或类为所有属性提供了默认值又没有提供任何自定义的构造器那么 Swift 会给这些结构体或类提供一个默认构造器。这个默认构造器将简单地创建一个所有属性值都设置为它们默认值的实例。
下面例子中定义了一个类 ShoppingListItem它封装了购物清单中的某一物品的名字name、数量quantity和购买状态 purchase state
class ShoppingListItem {var name: String?var quantity 1var purchased false
}
var item ShoppingListItem()
由于 ShoppingListItem 类中的所有属性都有默认值且它是没有父类的基类它将自动获得一个将为所有属性设置默认值的并创建实例的默认构造器由于 name 属性是可选 String 类型它将接收一个默认 nil 的默认值尽管代码中没有写出这个值。上面例子中使用默认构造器创造了一个 ShoppingListItem 类的实例使用 ShoppingListItem() 形式的构造器语法并将其赋值给变量 item。 可选链
可选链式调用是一种可以在当前值可能为 nil 的可选值上请求和调用属性、方法及下标的方法。如果可选值有值那么调用就会成功如果可选值是 nil那么调用将返回 nil。多个调用可以连接在一起形成一个调用链如果其中任何一个节点为 nil整个调用链都会失败即返回 nil。
使用可选链式调用代替强制解包
通过在想调用的属性、方法或下标的可选值后面放一个问号?可以定义一个可选链。这一点很像在可选值后面放一个叹号!来强制解包它的值。它们的主要区别在于当可选值为空时可选链式调用只会调用失败然而强制解包将会触发运行时错误。
为了反映可选链式调用可以在空值nil上调用的事实不论这个调用的属性、方法及下标返回的值是不是可选值它的返回结果都是一个可选值。你可以利用这个返回值来判断你的可选链式调用是否调用成功如果调用有返回值则说明调用成功返回 nil 则说明调用失败。
这里需要特别指出可选链式调用的返回结果与原本的返回结果具有相同的类型但是被包装成了一个可选值。例如使用可选链式调用访问属性当可选链式调用成功时如果属性原本的返回结果是 Int 类型则会变为 Int? 类型。
下面几段代码将解释可选链式调用和强制解包的不同。
class Person {var residence: Residence?
}class Residence {var numberOfRooms 1
}
Residence 有一个 Int 类型的属性 numberOfRooms其默认值为 1。Person 具有一个可选的 residence 属性其类型为 Residence?。
假如你创建了一个新的 Person 实例它的 residence 属性由于是可选类型而将被初始化为 nil在下面的代码中john 有一个值为 nil 的 residence 属性
复制
let john Person()
如果使用叹号!强制解包获得这个 john 的 residence 属性中的 numberOfRooms 值会触发运行时错误因为这时 residence 没有可以解包的值
复制
let roomCount john.residence!.numberOfRooms
// 这会引发运行时错误
john.residence 为非 nil 值的时候上面的调用会成功并且把 roomCount 设置为 Int 类型的房间数量。正如上面提到的当 residence 为 nil 的时候上面这段代码会触发运行时错误。
可选链式调用提供了另一种访问 numberOfRooms 的方式使用问号?来替代原来的叹号!
if let roomCount john.residence?.numberOfRooms {print(Johns residence has \(roomCount) room(s).)
} else {print(Unable to retrieve the number of rooms.)
}
// 打印“Unable to retrieve the number of rooms.”
在 residence 后面添加问号之后Swift 就会在 residence 不为 nil 的情况下访问 numberOfRooms。
因为访问 numberOfRooms 有可能失败可选链式调用会返回 Int? 类型或称为“可选的 Int”。如上例所示当 residence 为 nil 的时候可选的 Int 将会为 nil表明无法访问 numberOfRooms。访问成功时可选的 Int 值会通过可选绑定解包并赋值给非可选类型的 roomCount 常量。
要注意的是即使 numberOfRooms 是非可选的 Int 时这一点也成立。只要使用可选链式调用就意味着 numberOfRooms 会返回一个 Int? 而不是 Int。
可以将一个 Residence 的实例赋给 john.residence这样它就不再是 nil 了
john.residence Residence()
john.residence 现在包含一个实际的 Residence 实例而不再是 nil。如果你试图使用先前的可选链式调用访问 numberOfRooms它现在将返回值为 1 的 Int? 类型的值
if let roomCount john.residence?.numberOfRooms {print(Johns residence has \(roomCount) room(s).)
} else {print(Unable to retrieve the number of rooms.)
}
// 打印“Johns residence has 1 room(s).”
更多详细的资料可以查看可选链 | SwiftGG