swift - 在 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()
}
}
}
解决方案
在范围内找不到“帖子”
这意味着您没有创建任何名为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()
}
}
}
现在您需要使用 NetworkManager
in 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
}
推荐阅读
- go - 如何防止`go build`更新最新版本的模块
- python - 使用 else if 逻辑将条件列添加到 Pandas 数据框 - Python
- java - How to retrive and use a style attribute from code?
- ckeditor - 我怎样才能知道,CKEditor npm 标准版 v4 中默认删除了哪些按钮?
- dataframe - 如何根据组将 pyspark 数据帧拆分为 2 个数据帧
- mysql - 需要在 mysql 的一个交叉点上做 TOTAL
- javascript - Chrome 86:TypeError:不允许访问器属性
- selenium-webdriver - 如何自动化 vscode 扩展的 UI
- apache-spark - 如何从 spark-submit 访问 Spark Kubernetes 集群上的 kubectl 转发端口?
- laravel - 调用数组上的成员函数 getRealPath()