【发布时间】:2021-07-13 02:08:04
【问题描述】:
我正在尝试检索用户配置文件的数据,但我不确定如何在我的视图模型中初始化可观察对象。我看到了很多关于将返回一组对象的示例,但不是一个对象。
在尝试获取配置文件数据之前,如何使用 null 值初始化视图模型中的 profile 变量,还是不应该使用此方法来检索此数据?
另外,最好的做法是编写一个通用类(如 RestManager 类)来处理所有 API 请求并拥有一个调用 URLSession dataTaskPublisher 方法的方法?
型号:
struct Profile: Codable, Hashable, Identifiable {
var id: UUID
var address: String
var city: String
var emailAddress: String
var firstName: String
var lastName: String
var smsNumber: String
var state: String
var userBio: String
var username: String
var zipCode: Int
}
视图模型:
class ProfileViewModel: ObservableObject {
// Cannot create Profile() as it needs data to be instantiated
@Published var profile: Profile = Profile()
init() {
fetchProfile()
}
func fetchProfile() {
guard let url = URL(string: "https://path/to/api/v1/profiles") else {
print("Failed to create URL")
return
}
let requestData = [
"username": "testuser"
]
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "GET"
request.httpBody = try? JSONEncoder().encode(requestData)
URLSession.shared.dataTaskPublisher(for: request)
.tryMap { output in
guard let response = output.response as? HTTPURLResponse, response.statusCode == 200 else {
throw HTTPError.statusCode
}
return output.data
}
.decode(type: Profile.self, decoder: JSONDecoder())
.retry(3)
.replaceError(with: Profile()) // Same issue here - requires data to be instantiated
.eraseToAnyPublisher()
.receive(on: DispatchQueue.main)
.assign(to: &$profile)
}
}
查看:
struct ProfileSummary: View {
@ObservedObject var viewModel: ProfileViewModel
var body: some View {
NavigationView {
VStack {
Text(viewModel.profile.firstName)
Text(viewModel.profile.lastName)
}
.navigationTitle("Profile")
.onAppear {
viewModel.fetchProfile()
}
}
}
}
【问题讨论】:
标签: ios swift xcode mvvm swiftui