基于属性组合2个模型,在Swift中创建另一个模型

f0ofjuux  于 2023-06-21  发布在  Swift
关注(0)|答案(2)|浏览(117)

免责声明:英语不是我的母语,但我会尽力解释这个问题。
In this image I have 2 Lists, top displays a list of PostModels and bottom a list of UserModels.
这两个都是从API中获取的,我试图创建一个列表,其中PostModels userId == UserModels id。

**预期输出:**类似于您在Facebook帖子中看到的内容。您将在其中看到ListItem中的用户和文本。

我如何做到这一点?

型号

struct PostModel {
    let id: Int
    let userId: Int
    let title: String
    let body: String
}
struct UserModel {
    let id: Int
    let firstName: String
    let lastName: String
    let email: String
    let image: String
}

//The 3rd model where I will store data taken from Post and User
struct PostWithUser {
    let postUserId: Int
    let userImg: String
    let postUserName: String
    let postTitle: String
    let postBody: String
}

视图模型

class DashboardViewModel: WebViewModel, ObservableObject {
    var manager: UserManager = UserManager()
    var postManager: PostManager = PostManager()
    
    @Published var users: UsersModel = UsersModel(users: [UserModel(id: 0, firstName: "", lastName: "", email: "", image: "")])
    @Published var posts: PostsModel = PostsModel(posts: [PostModel(id: 0,userId: 0, title: "", body: "")])
    
    @Published var postsWithUser = [PostWithUser(postUserId: 0, userImg: "",postUserName: "", postTitle: "", postBody: "")]
    
    func getUsers() {
        manager.getUsers { [weak self] result in
            switch result {
            case .success(let usersModel):
                DispatchQueue.main.async {
                    self?.users = usersModel
                }
            case .failure(let error):
                print("Error: \(error)")
            }
        }
    }
    
    func getPosts() {
        postManager.getPosts { [weak self] result in
            switch result {
            case .success(let postsModel):
                DispatchQueue.main.async {
                    self?.posts = postsModel
                }
            case .failure(let error):
                print(error)
            }
        }
    }
    
    func getPostsWithUser() {
        for post in self.posts.posts {
            for user in self.users.users {
                if user.id == post.userId {
                    let post = PostWithUser(postUserId: post.userId, userImg: user.image, postUserName: "\(user.firstName) \(user.lastName)", postTitle: post.title, postBody: post.body)
                    
                    self.postsWithUser.append(post)
                }
            }
        }
    }
}

查看

struct DashboardView: View {
    @StateObject private var viewModel = DashboardViewModel()
    
    var body: some View {
        let users = viewModel.users.users
        let posts = viewModel.posts.posts
        let detailedPosts = viewModel.postsWithUser
        
        VStack {
            Text("Posts")
            List {
                ForEach(detailedPosts) { post in
                    Text(post.postTitle)
                }
            }.task {
                viewModel.getPosts()
                viewModel.getUsers()
                viewModel.getPostsWithUser()
            } 
        }
    }
}
n7taea2i

n7taea2i1#

一种解决方案是使用函数查找用户,而不是创建新类型。

class DashboardViewModel: ObservableObject {

    var users: [UserModel] = [UserModel(id: 0, firstName: "", lastName: "", email: "", image: "")]
    @Published var posts: PostsModel = PostsModel(posts: [PostModel(id: 0,userId: 0, title: "", body: "")])
    

    func userWith(id: Int) -> UserModel {
        users.first(where: { $0.id == id}) ?? .unknown
    }

    //...
}

我在UserModel的扩展中创建了一个未知用户

extension UserModel {
    static let unknown = UserModel(id: -1, firstName: "", lastName: "Unknown", email: "", image: "")
}

然后在视图中使用它,如

ForEach(detailedPosts) { post in
    Text(post.postTitle)
    Text(viewModel.userWith(id: post.userId).email)
}

请注意,由于我不知道UsersModel是什么样子,所以在代码中将其更改为数组。

eqqqjvef

eqqqjvef2#

@State var posts: [Post] = []
@Environment(\.myController) var controller
let userID: User.ID

var body: some View {
...
    .task(id: userID) { userID in
        posts = await controller.getPosts(userID)
...

仅供参考,StateObject不是为遗留视图模型对象设计的,在SwiftUI中,视图结构层次结构的工作是封装视图数据。

相关问题