使用SwiftUI和MVVM模式映射单个响应对象

使用SwiftUI和MVVM模式映射单个响应对象,mvvm,swiftui,Mvvm,Swiftui,我有一个简单的用户配置文件模型,它作为单个节点从JSON API返回 (型号)UserProfile.swift struct UserProfile: Codable, Identifiable { let id: Int var name: String var profile: String var image: String? var status: String var timezone: String } class UserProf

我有一个简单的用户配置文件模型,它作为单个节点从JSON API返回

(型号)UserProfile.swift

struct UserProfile: Codable, Identifiable {
    let id: Int
    var name: String
    var profile: String
    var image: String?
    var status: String
    var timezone: String
}
class UserProfileService {    
    func getProfile(completion: @escaping(UserProfile?) -> ()) {
        guard let url = URL(string: "https://myapi.com/profile") else {
            completion(nil)
            return
        }
        
        var request = URLRequest(url: url)
        
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue("application/json", forHTTPHeaderField: "Accept")
        request.httpMethod = "GET"
        
        URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data, error == nil else {
                DispatchQueue.main.async {
                    completion(nil)
                }
                return
            }
            
            do {
                let profile = try JSONDecoder().decode(UserProfile.self, from: data)
                
                DispatchQueue.main.async {
                    completion(profile)
                }
            } catch {
                print("ERROR: ", error)
            }
        }.resume()
    }
}
class UserProfileRequestViewModel: ObservableObject {
    @Published var profile = UserProfile.self
    
    init() {
        fetchProfile()
    }
    
    func fetchProfile() {
        UserProfileService().getProfile { profile in
            if let profile = profile {
                self.profile = UserProfileViewModel.init(profile: profile)
            }
        }
    }
}

class UserProfileViewModel {
    var profile: UserProfile
    
    init(profile: UserProfile) {
        self.profile = profile
    }
    
    var id: Int {
        return self.profile.id
    }
}
(服务)用户档案服务.swift

struct UserProfile: Codable, Identifiable {
    let id: Int
    var name: String
    var profile: String
    var image: String?
    var status: String
    var timezone: String
}
class UserProfileService {    
    func getProfile(completion: @escaping(UserProfile?) -> ()) {
        guard let url = URL(string: "https://myapi.com/profile") else {
            completion(nil)
            return
        }
        
        var request = URLRequest(url: url)
        
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue("application/json", forHTTPHeaderField: "Accept")
        request.httpMethod = "GET"
        
        URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data, error == nil else {
                DispatchQueue.main.async {
                    completion(nil)
                }
                return
            }
            
            do {
                let profile = try JSONDecoder().decode(UserProfile.self, from: data)
                
                DispatchQueue.main.async {
                    completion(profile)
                }
            } catch {
                print("ERROR: ", error)
            }
        }.resume()
    }
}
class UserProfileRequestViewModel: ObservableObject {
    @Published var profile = UserProfile.self
    
    init() {
        fetchProfile()
    }
    
    func fetchProfile() {
        UserProfileService().getProfile { profile in
            if let profile = profile {
                self.profile = UserProfileViewModel.init(profile: profile)
            }
        }
    }
}

class UserProfileViewModel {
    var profile: UserProfile
    
    init(profile: UserProfile) {
        self.profile = profile
    }
    
    var id: Int {
        return self.profile.id
    }
}
(视图模型)UserProfileViewModel.swift

struct UserProfile: Codable, Identifiable {
    let id: Int
    var name: String
    var profile: String
    var image: String?
    var status: String
    var timezone: String
}
class UserProfileService {    
    func getProfile(completion: @escaping(UserProfile?) -> ()) {
        guard let url = URL(string: "https://myapi.com/profile") else {
            completion(nil)
            return
        }
        
        var request = URLRequest(url: url)
        
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue("application/json", forHTTPHeaderField: "Accept")
        request.httpMethod = "GET"
        
        URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data, error == nil else {
                DispatchQueue.main.async {
                    completion(nil)
                }
                return
            }
            
            do {
                let profile = try JSONDecoder().decode(UserProfile.self, from: data)
                
                DispatchQueue.main.async {
                    completion(profile)
                }
            } catch {
                print("ERROR: ", error)
            }
        }.resume()
    }
}
class UserProfileRequestViewModel: ObservableObject {
    @Published var profile = UserProfile.self
    
    init() {
        fetchProfile()
    }
    
    func fetchProfile() {
        UserProfileService().getProfile { profile in
            if let profile = profile {
                self.profile = UserProfileViewModel.init(profile: profile)
            }
        }
    }
}

class UserProfileViewModel {
    var profile: UserProfile
    
    init(profile: UserProfile) {
        self.profile = profile
    }
    
    var id: Int {
        return self.profile.id
    }
}
有人能告诉我需要在上面添加什么吗,因为这会导致错误“无法将“UserProfileViewModel”类型的值分配给“UserProfile.type”类型

如果我有一个数据循环,那么像下面这样的循环就没有问题了,但是我如何处理单个节点呢

if let videos = videos {
    self.videos = videos.map(VideoViewModel.init)
}

似乎您的UserProfileService().getProfile已返回UserProfile类型,因此您可能需要

UserProfileService().getProfile { profile in
   if let profile = profile {
      self.profile = profile
   }
}


使用正确的视图模型工作版本,因此为可能存在相同问题的其他人添加此版本

(视图模型)UserProfileViewModel.swift

class UserProfileViewModel: ObservableObject {
    @Published var profile: UserProfile?
    
    init() {
        fetchProfile()
    }
    
    func fetchProfile() {
        UserProfileService().getProfile { profile in
              self.profile = profile
           
        }
    }
    
    var name: String {
        return self.profile?.name ?? "Name"
    }
}

谢谢,是的,这正是我需要的。虽然我不明白“if let profile=profile{…}”这行的意思,但这只是检查没有空的响应吗?是的,它是空的。UserProfileService可以通过“if let profile”返回nil“completion(nil)”,我们检查它。此外,您还需要在catch部分返回completion(nil)(以防jsondecode中出现错误)