• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • SwiftUI 中級之List顯示遠程Json文件(2020年教程)

    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"
    }]
    

    預期效果

    編碼

    首先,我們需要為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教程和代碼關注專欄

    版權聲明:本文為iCloudEnd原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/iCloudEnd/article/details/104079667

    智能推薦

    SwiftUI官方教程解讀

    原文鏈接:https://www.jianshu.com/p/ecfdbea7a0ed SwiftUI簡介 SwiftUI是wwdc2019發布的一個新的UI框架,通過聲明和修改視圖來布局UI和創建流暢的動畫效果。并且我們可以通過狀態變量來進行數據綁定實現一次性布局;Xcode 11 內建了直觀的新設計工具canvus,在整個開發過程中,預覽可視化與代碼可編輯性能同時支持并交互,讓我們可以體驗到代...

    SwiftUI 官方教程 (十)

    由于 API 變動,此文章部分內容已失效,最新完整中文教程及代碼請查看 https://github.com/WillieWangWei/SwiftUI-Tutorials 創建 watchOS App 本教程為你提供一個將你已經學到的關于 SwiftUI 的知識應用到自己的產品上的機會,并且不費吹灰之力就可以將 Landmarks app 遷移到 watchOS 上。 首先,給項目添加一個 wa...

    SwiftUI 官方教程 (一)

    由于 API 變動,此文章部分內容已失效,最新完整中文教程及代碼請查看 https://github.com/WillieWangWei/SwiftUI-Tutorials SwiftUI 簡介 SwiftUI 是一種為任何 Apple 平臺聲明用戶界面的現代化方式。以前所未有的速度,創建漂亮、動態的應用程序。 只需要描述一次的布局 為你的視圖聲明任何狀態的內容和布局,一旦狀態發生改變, Swif...

    SwiftUI之List 和form(2020版)

    SwiftUI之List 和form(2020版) VStack 效果 image.png List 效果 image.png List with header & footer 效果 image.png List & navigation Treat.swift 效果 image.png 完成代碼 效果 image.png...

    SwiftUI 基礎之如何獲取json文件

    創建一個playground 運行效果 image.png 更多SwiftUI教程和代碼關注專欄 請關注我的專欄 SwiftUI教程與源碼...

    猜你喜歡

    SwiftUI 中級之同時顯示多個設備Preview

    代碼 效果 [email protected] 更多SwiftUI教程和代碼關注專欄 請關注我的專欄icloudend, SwiftUI教程與源碼 https://www.jianshu.com/c/7b3e3b671970...

    SwiftUI Button 基礎教程

    Button 觸發時執行操作的控件 使用教程 您可以通過提供操作和標簽來創建按鈕。操作是一個方法或閉包屬性,當用戶單擊或輕觸按鈕時,它會執行某些操作。標簽是描述按鈕操作的視圖,例如,通過顯示文本(如取消)或圖標(如后退箭頭)。 代碼 iOSButton效果 macOS代碼 tvOS代碼 推薦 基礎文章推薦 《SwiftUI是什么,聽聽大牛們如何說》 經典教程推薦 更新近百篇SwiftUI教程《Sw...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    精品国产乱码久久久久久蜜桃不卡