如何使用nsmanagedObject在Swiftui中重复使用同一功能

发布于 2025-02-09 22:57:49 字数 2077 浏览 0 评论 0原文

假设我们有一个主视图mainview和一个子查看loginview哪些执行用户登录功能。我选择了Coredata来存储一些持久的数据,例如用户名和密码以及@State in mainView以存储非固定数据(例如登录状态)。

当用户打开应用程序时,我还想支持自动登录。因此,loginview中的登录函数也在mainView中使用。我的演示代码在下面粘贴。

import SwiftUI
import CoreData

struct MainView: View {
    @State private var loggingIn: Bool = false
    @State private var token: String? = nil
    // `UserInfo` here is a `NSManagedObject` fetched from CoreData
    @ObservedObject private var info: UserInfo 
    
    init() {
        // fetch info from CoreData
    }
    
    func logIn() {
        await MainActor.run {
            self.loggingIn = true
        }
        let token = await performLoginHttpRequest(cred.username!, cred.password!)
        await MainActor.run {
            self.loggingIn = false
            self.token = token
        }
    }
    
    var body: some View {
        NavigationView {
            VStack {
                if logging {
                    ProgressView()
                } else if token == nil {
                    Text("Logged Out")
                } else {
                    Text("Token: \(token!)")
                }
                NavigationLink("Login") {
                    LoginView(info: info, logging: $loggingIn)
                }
            }
        }
        .task {
            await logIn()
        }
    }
}

struct LoginView: View {
    @ObservedObject var info: UserInfo
    @Binding var loggingIn: Bool
    @Binding var token: String?
    
    func logIn() async {
        // basically same as in MainView, but
        // `loggingIn` and `token` here is wrapped
        // with `@Binding`
    }
    
    var body: some View {
        // UI to login
    }
}

如您所见,这里的问题是我必须在mainViewloginview中编写相同的逻辑,因为我不知道如何在这种配置中共享逻辑。

我尝试了一些丑陋的解决方法,例如将userInfo包装在另一个observableObject中并在视图之间共享。但是嵌套的可观察到在SwiftUI中似乎不建议使用。有什么优雅的方法可以实施吗?

Suppose we have a main view MainView and a child view LoginView which perform login function for user. I have chosen CoreData to store some persisted data like username and password and @State in MainView to store non-persisted data like logging-in status.

I also want to support automatic login when the user opens the app. So the login function in LoginView is also used in MainView. My demo code is pasted below.

import SwiftUI
import CoreData

struct MainView: View {
    @State private var loggingIn: Bool = false
    @State private var token: String? = nil
    // `UserInfo` here is a `NSManagedObject` fetched from CoreData
    @ObservedObject private var info: UserInfo 
    
    init() {
        // fetch info from CoreData
    }
    
    func logIn() {
        await MainActor.run {
            self.loggingIn = true
        }
        let token = await performLoginHttpRequest(cred.username!, cred.password!)
        await MainActor.run {
            self.loggingIn = false
            self.token = token
        }
    }
    
    var body: some View {
        NavigationView {
            VStack {
                if logging {
                    ProgressView()
                } else if token == nil {
                    Text("Logged Out")
                } else {
                    Text("Token: \(token!)")
                }
                NavigationLink("Login") {
                    LoginView(info: info, logging: $loggingIn)
                }
            }
        }
        .task {
            await logIn()
        }
    }
}

struct LoginView: View {
    @ObservedObject var info: UserInfo
    @Binding var loggingIn: Bool
    @Binding var token: String?
    
    func logIn() async {
        // basically same as in MainView, but
        // `loggingIn` and `token` here is wrapped
        // with `@Binding`
    }
    
    var body: some View {
        // UI to login
    }
}

As you can see, the problem here is that I have to write the same logic in MainView and LoginView since I do not know how to share the logic in such configuration.

I have tried some ugly workaround like wrapping the UserInfo in another ObservableObject and sharing it between views. But nested ObservableObject seems not recommended in SwiftUI. Is there any elegant way to implement this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文