更多技术整理,欢迎关注本人博客www.tomtwos.com
参考资料:
Displaying a List with SwiftUI from a remote JSON file
在开始本教程学习前需要了解MySQLi,知道mysql通过php将表数据转为json格式的步骤。SwiftUI实际处理的是mysql的json格式的数据。
三个链接
TOM教程:什么是MySQLi?
TOM教程:在 ubuntu 上运行 php 脚本文件
TOM教程:php获取mysql表数据,并编码为json
为json的数据定义一个模型,该模型是具有Decodable和Identifiable协议的struct。
比如我显示holiday,代码如下,CodingKeys能够将JSON key名称与您创建的Model的变量名称进行映射。(可以将description映射为festival,在Model中可以自定义名称,可以和数据库中的名称不同。此处不做演示)
struct Holiday: Decodable, Identifiable {
public var id: String
public var year: String
public var month: String
public var day: String
public var description: String
enum CodingKeys: String, CodingKey {
case id = "id"
case year = "year"
case month = "month"
case day = "day"
case description = "description"
}
}
Combine框架提供了一个声明性的Swift API,用于随时间处理值。这些值可以表示多种异步事件。 Combine声明发布者公开随时间变化的值,订阅者从发布者那里接收这些值。
@ObervableObject:具有发布者功能的一种对象,该对象在对象更改之前发出。默认情况下,@ObservableObject会合成一个objectWillChange发布者,该发布者会在其@Published属性中的任何一个发生更改之前发出更改的值。
@Published修饰holidays数组后,当movies发生改变是将通知所有的ObserableObject。
load()方法从网络异步获取JSON数据,一旦数据加载完毕,我们便将其分配给movie数组。movie数组更改时,它将向订户发送事件。
public class HolidayFetcher: ObservableObject {
@Published var holidays = [Holiday]()
init(){
load()
}
func load() {
let url = URL(string: "http://120.77.34.180/holidays.php")!
URLSession.shared.dataTask(with: url) {(data,response,error) in
do {
if let d = data {
let decodedLists = try JSONDecoder().decode([Holiday].self, from: d)
DispatchQueue.main.async {
self.holidays = decodedLists
}
}else {
print("No Data")
}
} catch {
print ("Error")
}
}.resume()
}
}
struct ListJsonView: View {
@ObservedObject var fetcher = HolidayFetcher()
var body: some View {
VStack {
List(fetcher.holidays) { holiday in
HStack {
Text(holiday.year)
Text(holiday.month)
Text(holiday.day)
Text(holiday.description)
.font(.system(size: 20))
.foregroundColor(Color.gray)
}
}
}
}
}
编译通过后预览,屏幕出现数据与数据库的Holiday表数据一致,测试成功。
如果前面测试正常,则无需step5,如果显示异常,按照下面步骤操作一遍。
Info.plist→App Transport Security Settings→Allows Arbitrary Loads→yes,通过以上设置允许外部数据载入
//
// ListJsonView.swift
// mysql_test
//
// Created by Tom on 31/3/2020.
// Copyright © 2020 Tom. All rights reserved.
//
import Foundation
import SwiftUI
import Combine
struct ListJsonView: View {
@ObservedObject var fetcher = HolidayFetcher()
var body: some View {
VStack {
List(fetcher.holidays) { holiday in
HStack {
Text(holiday.year)
Text(holiday.month)
Text(holiday.day)
Text(holiday.description)
.font(.system(size: 20))
.foregroundColor(Color.gray)
}
}
}
}
}
struct ListJsonView_Previews: PreviewProvider {
static var previews: some View {
ListJsonView()
}
}
public class HolidayFetcher: ObservableObject {
@Published var holidays = [Holiday]()
init(){
load()
}
func load() {
let url = URL(string: "http://120.77.34.180/holidays.php")!
URLSession.shared.dataTask(with: url) {(data,response,error) in
do {
if let d = data {
let decodedLists = try JSONDecoder().decode([Holiday].self, from: d)
DispatchQueue.main.async {
self.holidays = decodedLists
}
}else {
print("No Data")
}
} catch {
print ("Error")
}
}.resume()
}
}
struct Holiday: Decodable, Identifiable {
public var id: String
public var year: String
public var month: String
public var day: String
public var description: String
enum CodingKeys: String, CodingKey {
case id = "id"
case year = "year"
case month = "month"
case day = "day"
case description = "description"
}
}