访问从 API 解码的数组中的第一项

Posted

技术标签:

【中文标题】访问从 API 解码的数组中的第一项【英文标题】:Access first item in an array decoded from an API 【发布时间】:2019-12-28 00:48:13 【问题描述】:

大家好,节日快乐!

我是 SwiftUI 新手,刚开始使用 API。我设法习惯了解码 API,但是当我尝试访问数组中的第一项时遇到了问题。我正在使用 SwiftyJSON 进行解码。我尝试访问索引 0,但构建失败并出现错误:索引超出范围

任何提示都会非常有帮助,尤其是对于像我这样的新手。

提前感谢您!

型号

struct  dataType: Identifiable 

var id: String
var title: String
var desc: String
var url: String
var image: String

解码 JSON

class getData: ObservableObject 

@Published var datas = [dataType]()

init() 

    let source = "https://newsapi.org/v2/top-headlines?country=ro&apiKey=c602e42864e148dea1144f1f55255888"

    let url = URL(string: source)!

    let session = URLSession(configuration: .default)

    session.dataTask(with: url)  (data, _, err) in

        if err != nil 

            print((err?.localizedDescription)!)
            return
        

        let json = try! JSON(data: data!)

        for i in json["articles"]

            let title = i.1["title"].stringValue
            let description = i.1["description"].stringValue
            let url = i.1["url"].stringValue
            let image = i.1["urlToImage"].stringValue
            let id = i.1["publishedAt"].stringValue

            DispatchQueue.main.async 
                self.datas.append(dataType(id: id, title: title, desc: description, url: url, image: image))
            
        
    .resume()

最后是视图

struct ContentView: View 

@ObservedObject var list = getData()
var body: some View 

    VStack 

        WebImage(url: URL(string: list.datas[0].title), options: .highPriority, context: nil)
            .resizable()
            .frame(width:400, height:250)

        NavigationView 

                List(list.datas)i in

                    NavigationLink(destination: webView(url: i.url).navigationBarTitle("", displayMode: .inline))
                    
                        HStack 

                            VStack(alignment: .leading, spacing: 10) 

                                Text(i.title).fontWeight(.heavy)

                                Text(i.desc)
                                    .lineLimit(3)
                            

                            if i.image != "" 

                                WebImage(url: URL(string:i.image), options: .highPriority, context: nil)
                                    .resizable()
                                    .frame(width: 110, height: 135)
                                    .cornerRadius(20)
                            

                        .padding(.vertical, 15)
                    

                .navigationBarTitle("Noutati")
        
    

【问题讨论】:

【参考方案1】:

URLSession 异步执行dataTask,所以一开始还没有数据,即。 datas 是空的,因此尝试获取空数组的第一个(低于datas[0])元素会导致异常(您会看到)

WebImage(url: URL(string: list.datas[0].title), options: .highPriority, context: nil)
            .resizable()
            .frame(width:400, height:250)

相反,您需要在数据加载之前显示一些存根视图,如下所示

if list.data.isEmpty 
   Text("Loading...")
 else 
    WebImage(url: URL(string: list.datas[0].title), options: .highPriority, context: nil)
                .resizable()
                .frame(width:400, height:250)

【讨论】:

非常感谢!这非常有效。关于如何访问任何其他索引的任何提示?它适用于第一项,但高于 0 的任何内容都会返回错误:索引超出范围。 我已经设法通过添加 if datas.count

以上是关于访问从 API 解码的数组中的第一项的主要内容,如果未能解决你的问题,请参考以下文章

从 sCrypt 智能合约中访问区块链数据

删除保存在设备上的 plist 中的第一项

如何在IOS中读取多个数组中的第一项

Javascript / React - 获取匹配特定条件的数组中的第一项

ListView 仅显示数组列表中的第一项

Spring Jackson反序列化只选择数组的第一项