在SwiftUI中从服务器下载数据的最佳实践

在SwiftUI中从服务器下载数据的最佳实践,swiftui,Swiftui,我的问题是一个概念问题 我有以下代码: 结构分类列表:视图{ @国家私有变量类别:[类别数据]=[] var body:一些观点{ 导航视图{ 列表(self.categories){categories in 导航按钮(目的地:PostsList(类别:类别)){ 类别(类别:类别) } } }.navigationBarTitle(文本(“分类”)) } } 它只是使用元素(类别)列表组成我的UI,并且我有一个与视图关联的状态,当视图发生更改时,该状态会自动更新视图 这一切都很奇妙,但对我

我的问题是一个概念问题

我有以下代码:

结构分类列表:视图{ @国家私有变量类别:[类别数据]=[] var body:一些观点{ 导航视图{ 列表(self.categories){categories in 导航按钮(目的地:PostsList(类别:类别)){ 类别(类别:类别) } } }.navigationBarTitle(文本(“分类”)) } } 它只是使用元素(类别)列表组成我的UI,并且我有一个与视图关联的状态,当视图发生更改时,该状态会自动更新视图

这一切都很奇妙,但对我来说,不清楚谁应该发出网络请求来填充模型

我理解绑定和
@state
的思想,但是,一般来说,我应该如何构建代码,以获得一开始需要的模型


在旧方法中,我会在
viewDidLoad
中实现此行为,但在新的SwiftUI范例中,获取数据的最佳方法是什么?

SwiftUI社区还没有真正建立任何最佳实践,因为这项技术太新了。我的答案是基于我从不同的WWDC19会议中看到的

首先,使用
categories
属性创建一个
BindableObject
。然后编写网络请求代码,并将
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"]
    }
}
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将使用新类别(tysm)进行更新

您可以查看我的答案

基本上,您创建的模型对象符合
BindableObject

类登录模型:BindableObject{
var didChange=PassthroughSubject()
私有(设置)变量用户名:字符串{
迪塞特{
发送(自我)
}
}
func load(){
DispatchQueue.main.asyncAfter(截止日期:.now()+5.0){
self.username=“Sorin”
}
}
}
此示例使用普通的ol'
asyncAfter
模拟异步服务器调用

然后,视图将与其链接,并在模型更改时自动更新

公共结构登录筛选:查看{ @ObjectBinding var loginObject=LoginModel() 公共机构:一些看法{ 团体{ 如果login.username==nil{ 文本(“正在尝试登录,请稍候…”) }否则{ 文本(“成功登录,用户名为\(loginObject.username!)”) } }奥纳佩尔先生{ self.loginObject.load() } } }
这里的关键是避免试图让
视图
执行与
模型
相关的任何操作,只显示它
SwiftUI
会一直抵制你:-)

iOS开发者似乎不像Mac OS开发者那样熟悉这个想法,在Mac应用程序中,我们将控制器层分为ViewController和ModelController,ViewController负责视图和模型之间的同步,ModelControllers负责管理模型等的存档,因此SwiftUI不再使用ViewControllers,但如果您有网络处理功能,那么ModelControllers将非常有用,它们可以处理远程源和模型之间的同步,这就是我目前在一个示例应用程序中所做的工作,尽管我一直在想是否可以用Combine来代替它,这将是我下一步要做的实验。

这只是UI。您不应该从UI请求。您一直从UI请求,这是什么意思?虽然这不是问题的详细答案,也可能不是完美的解决方案,但我发现这个开源项目使用了SwiftUI和Combine框架。它不是由我维护的,所以我不能保证它将来也会成为参考。在我看来,这家伙有一个很好的体系结构(即使他使用第三方库来包装Combine框架,我个人不太喜欢),并且可以作为一个很好的起点,对SwiftUI/Combine框架中的项目进行全面的概述。