我的问题是一个概念性问题。
我有以下代码:
struct CategoriesList : View {
@State private var categories: [CategoryMetadata] = []
var body: some View {
NavigationView {
List(self.categories) { category in
NavigationButton(destination: PostsList(category: category)) {
CategoryRow(category: category)
}
}
}.navigationBarTitle(Text("Categorie"))
}
}
那只是使用元素(类别)列表来构成我的UI,并且我具有与视图关联的状态,该状态会在视图更改时自动更新。
一切都很好,但对我来说尚不清楚世卫组织应触发网络请求以填充模型。
我了解绑定和@state
的想法,但是,总的来说,我应该如何构建代码以在开始时具有所需的模型?
在旧方法中,我会在viewDidLoad
中实现此行为,但是使用SwiftUI的新范例,什么是获取数据的最佳方法?
答案 0 :(得分:2)
SwiftUI社区尚未真正建立任何最佳实践,因为该技术太新了。我的答案基于我从不同的WWDC19会话中看到的内容。
首先,创建一个具有BindableObject
属性的categories
。然后编写您的网络请求代码,并将self.categories
设置为新下载的类别。
import SwiftUI
import Combine
final class CategoryStore: BindableObject {
var didChange = PassthroughSubject<Void, Never>()
var categories = [String]()
init() {
// TODO: Fetch categories from API
self.categories = ["A", "B", "C"]
}
}
然后,将CategoryStore
添加到View
并将其与List
一起使用以遍历类别。
import SwiftUI
struct ContentView : View {
@ObjectBinding private var store = CategoryStore()
var body: some View {
List(store.categories.identified(by: \.self)) { category in
Text(category)
}
}
}
只要categories
属性更新,您的UI就会更新为新类别(类型Combine)
答案 1 :(得分:1)
您可以看看我的答案here。
基本上,您创建一个符合BindableObject
的模型对象:
class LoginModel : BindableObject {
var didChange = PassthroughSubject<LoginModel, Never>()
private(set) var username: String? {
didSet {
didChange.send(self)
}
}
func load() {
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
self.username = "Sorin"
}
}
}
此示例通过使用普通ol'asyncAfter
模拟一个异步服务器调用。
然后,视图与之链接,并且在模型更改时会自动更新。
public struct LoginScreen: View {
@ObjectBinding var loginObject = LoginModel()
public var body: some View {
Group {
if login.username == nil {
Text("Trying to login, please wait...")
} else {
Text("Successful login, the username is \(loginObject.username!)")
}
}.onAppear {
self.loginObject.load()
}
}
}
这里的关键是要避免使View
执行与Model
相关的任何事情,除了显示它。 SwiftUI
会一路抵抗您:-)
答案 2 :(得分:1)
iOS开发人员似乎不像Mac OS开发人员那样熟悉此思想,在Mac应用程序中,我们将控制器层分为ViewController和ModelControllers,ViewController负责视图和模型之间的同步,ModelController负责管理模型的归档等,因此SwiftUI取消了ViewControllers,但是如果您具有网络处理功能,那么那在ModelControllers有用的地方,它们就可以处理您的远程源和模型之间的同步,这就是我目前正在做的我正在工作的一个示例应用程序,尽管我一直在想是否也可以使用Combine替换它,这将是我接下来要尝试的事情。