首页 > 解决方案 > 在 SwiftUI 的范围错误中找不到“帖子”

问题描述

我收到一个错误消息cannot find 'posts' in scope。我一直在尝试在线检查解决方案,但没有遇到可以解决此问题的解决方案。

内容视图.swift

struct ContentView: View {
    var body: some View {
        NavigationView{
            List(posts) {  //error on this line
                post in
                Text(post.title)
            }
             .navigationBarTitle("Hacker News")
         }
     }
 }


  struct Results: Decodable {
      let hits: [Post]
  }

  struct Post: Decodable, Identifiable {

      var id: String {
          return objectId
      }
        let objectId: String
        let title: String
        let url: String
        let points: Int
  }
class NetworkManager {
    
    
    func fetchData() {
        if let url = URL(string: "https://hn.algolia.com/api/v1/search?tags=front_page"){
            let session = URLSession(configuration: .default)
            let task = session.dataTask(with: url) { (data, response, error) in
                if error == nil{
                    let decoder = JSONDecoder()
                    if let safeData = data{
                        do {
                            let results=try decoder.decode(Results.self, from: safeData)
                            
                        } catch {
                            print(error)
                        }
                    
                    }
                }
            }
            task.resume()
        }
    }
}

标签: swiftswiftui

解决方案


在范围内找不到“帖子”

这意味着您没有创建任何名为posts.

另请注意,您的代码也会产生警告NetworkManager

从未使用过不可变值“结果”的初始化;考虑替换为“_”的赋值或删除它

这是因为获取的数据NetworkManager没有在任何地方使用。

简而言之,问题在于它不以任何方式NetworkManager与/使用有关。ContentView


一个可能的解决方案是创建一个NetworkManager类型的属性:ObservableObject@Published[Post]

class NetworkManager: ObservableObject { // make ObservableObject
    @Published var posts = [Post]() // create `posts` here
    
    func fetchData() {
        if let url = URL(string: "https://hn.algolia.com/api/v1/search?tags=front_page") {
            let session = URLSession(configuration: .default)
            let task = session.dataTask(with: url) { data, response, error in
                if error == nil {
                    let decoder = JSONDecoder()
                    if let safeData = data {
                        do {
                            let results = try decoder.decode(Results.self, from: safeData)
                            DispatchQueue.main.async {
                                self.posts = results.hits // assign fetched data to `posts`
                            }
                        } catch {
                            print(error)
                        }
                    }
                }
            }
            task.resume()
        }
    }
}

现在您需要使用 NetworkManagerin ContentView

struct ContentView: View {
    @StateObject private var networkManager = NetworkManager() // or `@ObservedObject` for iOS 13
    
    var body: some View {
        NavigationView {
            List(networkManager.posts) { post in // use `posts` from `networkManager`
                Text(post.title)
            }
            .navigationBarTitle("Hacker News")
        }
        .onAppear {
            networkManager.fetchData() // fetch data when the view appears
        }
    }
}

你也有一个错字objectId- >它应该是objectID

struct Post: Decodable, Identifiable {
    var id: String {
        return objectID
    }

    let objectID: String
    let title: String
    let url: String
    let points: Int
}

如果您不想更改名称,则可以CodingKeys改用:

struct Post: Decodable, Identifiable {
    enum CodingKeys: String, CodingKey {
        case objectId = "objectID", title, url, points
    }
    
    var id: String {
        return objectId
    }

    let objectId: String
    let title: String
    let url: String
    let points: Int
}

推荐阅读