ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SwiftUI 中级之List显示远程Json文件(2020年教程)

2020-01-24 11:00:52  阅读:307  来源: 互联网

标签:10 title List Json SwiftUI year var 2019 id


SwiftUI 中级之List显示远程Json文件(2020年教程)

本文的目的是展示一种从远程JSON文件获取数据并将其显示在SwiftUI中的列表上的简单方法。

数据介绍

下面是我们json文件的格式

[{
    "id": 5,
    "title": "Joker",
    "year": "2019",
    "image": "",
    "created_at": "2019-10-06T17:55:21.374Z",
    "updated_at": "2019-10-06T17:55:21.374Z"
}, {
    "id": 1,
    "title": "Pulp Fiction",
    "year": "1994",
    "image": "",
    "created_at": "2019-10-06T15:26:36.675Z",
    "updated_at": "2019-10-06T18:05:31.649Z"
}, {
    "id": 4,
    "title": " The Godfather ",
    "year": "1972",
    "image": "",
    "created_at": "2019-10-06T15:27:38.123Z",
    "updated_at": "2019-10-06T18:05:50.242Z"
}, {
    "id": 6,
    "title": "The Dark Knight ",
    "year": "2008",
    "image": "",
    "created_at": "2019-10-06T18:06:12.933Z",
    "updated_at": "2019-10-06T18:06:12.933Z"
}, {
    "id": 7,
    "title": "Fight Club",
    "year": "1999",
    "image": "",
    "created_at": "2019-10-06T18:06:33.096Z",
    "updated_at": "2019-10-06T18:06:33.096Z"
}, {
    "id": 8,
    "title": " Inception",
    "year": "2010",
    "image": "",
    "created_at": "2019-10-06T18:06:52.034Z",
    "updated_at": "2019-10-06T18:06:52.034Z"
}, {
    "id": 2,
    "title": "The Matrix ",
    "year": "1999",
    "image": "",
    "created_at": "2019-10-06T15:26:48.042Z",
    "updated_at": "2019-10-06T18:08:00.902Z"
}, {
    "id": 3,
    "title": "The Shawshank Redemption ",
    "year": "1984",
    "image": "",
    "created_at": "2019-10-06T15:26:59.572Z",
    "updated_at": "2019-10-06T18:08:47.637Z"
}]

预期效果

41085-71d7eb68cfe2b140.jpg Jietu20200124-094043@2x.jpg

编码

首先,我们需要为Movie定义模型,在这种情况下,该模型是具有Decodable和Identifiable协议的struct。Decodable能够从JSON文件中对其进行解码,Identifiable能够与List一起列出。List可以像UITableViewController一样显示可标识集合中的数据列表。

struct Movie: Decodable, Identifiable {
    public var id: Int
    public var name: String
    public var released: String
    
    enum CodingKeys: String, CodingKey {
           case id = "id"
           case name = "title"
           case released = "year"
        }
}

CodingKeys能够将JSON key名称与您创建的Model的变量名称进行映射。在这种情况下,我将其命名为Release而不是年份,只是为了表明您可以在模型中使用自己的名称,只要您在Coding Keys中定义它即可。

下面我们将编码读取数据并进行解码的代码

public class MovieFetcher: ObservableObject {
    @Published var movies = [Movie]()
    
    init(){
        load()
    }
    
    func load() {
        let url = URL(string: "https://gist.githubusercontent.com/rbreve/60eb5f6fe49d5f019d0c39d71cb8388d/raw/f6bc27e3e637257e2f75c278520709dd20b1e089/movies.json")!
    
        URLSession.shared.dataTask(with: url) {(data,response,error) in
            do {
                if let d = data {
                    let decodedLists = try JSONDecoder().decode([Movie].self, from: d)
                    DispatchQueue.main.async {
                        self.movies = decodedLists
                    }
                }else {
                    print("No Data")
                }
            } catch {
                print ("Error")
            }
            
        }.resume()
         
    }
}

Combine框架提供了一个声明性的Swift API,用于随时间处理值。这些值可以表示多种异步事件。 Combine声明发布者公开随时间变化的值,订阅者从发布者那里接收这些值。
@ObervableObject:具有发布者功能的一种对象,该对象在对象更改之前发出。默认情况下,@ObservableObject会合成一个objectWillChange发布者,该发布者会在其@Published属性中的任何一个发生更改之前发出更改的值。
@Published修饰movies数组后,当movies发生改变是将通知所有的ObserableObject。

load()方法从网络异步获取JSON数据,一旦数据加载完毕,我们便将其分配给movie数组。movie数组更改时,它将向订户发送事件。

struct ContentView: View {
    @ObservedObject var fetcher = MovieFetcher()
    
    var body: some View {
        VStack {
            List(fetcher.movies) { movie in
                VStack (alignment: .leading) {
                    Text(movie.name)
                    Text(movie.released)
                        .font(.system(size: 11))
                        .foregroundColor(Color.gray)
                }
            }
        }
    }
}

完整代码


import Foundation
import SwiftUI
import Combine
 
public class MovieFetcher: ObservableObject {

    @Published var movies = [Movie]()
    
    init(){
        load()
    }
    
    func load() {
        let url = URL(string: "https://gist.githubusercontent.com/rbreve/60eb5f6fe49d5f019d0c39d71cb8388d/raw/f6bc27e3e637257e2f75c278520709dd20b1e089/movies.json")!
    
        URLSession.shared.dataTask(with: url) {(data,response,error) in
            do {
                if let d = data {
                    let decodedLists = try JSONDecoder().decode([Movie].self, from: d)
                    DispatchQueue.main.async {
                        self.movies = decodedLists
                    }
                }else {
                    print("No Data")
                }
            } catch {
                print ("Error")
            }
            
        }.resume()
         
    }
}

struct Movie: Codable, Identifiable {
    public var id: Int
    public var name: String
    public var released: String
    
    enum CodingKeys: String, CodingKey {
           case id = "id"
           case name = "title"
           case released = "year"
        }
}


struct ListJsonView: View {
    @ObservedObject var fetcher = MovieFetcher()
    
    var body: some View {
        VStack {
            List(fetcher.movies) { movie in
                VStack (alignment: .leading) {
                    Text(movie.name)
                    Text(movie.released)
                        .font(.system(size: 11))
                        .foregroundColor(Color.gray)
                }
            }
        }
    }
}

 


struct ListJsonView__Previews: PreviewProvider {
    static var previews: some View {
        ListJsonView()
    }
}

参考文件

更多SwiftUI教程和代码关注专栏

知识大胖 发布了637 篇原创文章 · 获赞 4 · 访问量 5万+ 私信 关注

标签:10,title,List,Json,SwiftUI,year,var,2019,id
来源: https://blog.csdn.net/iCloudEnd/article/details/104079667

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有