Ios SwiftUI MVVM将变量从ViewModel传递到API服务
我对Swift&XCode非常陌生,在学习了几篇教程之后,我已经制作了一个带有API服务的MVVM体系结构,但是我无法将变量从ViewModel传递到API服务。我想传递var user&从LoginViewModel传递到apidentIos SwiftUI MVVM将变量从ViewModel传递到API服务,ios,swift,mvvm,swiftui,Ios,Swift,Mvvm,Swiftui,我对Swift&XCode非常陌生,在学习了几篇教程之后,我已经制作了一个带有API服务的MVVM体系结构,但是我无法将变量从ViewModel传递到API服务。我想传递var user&从LoginViewModel传递到apident enum APIEndpoint { case userLogin case menuList } extension APIEndpoint: RequestBuilder { var urlRequest: URLRequest
enum APIEndpoint {
case userLogin
case menuList
}
extension APIEndpoint: RequestBuilder {
var urlRequest: URLRequest {
switch self {
case .userLogin:
guard let url = URL(string: "https://jcouserapidev.oxxo.co.id/home/app")
else {preconditionFailure("Invalid URL format")}
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(Constants.API_TOKEN, forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"
// I want to pass the variables here, how??
let body: [String: Any] = ["user": $user, "pass": $pass]
let rb = try! JSONSerialization.data(withJSONObject: body)
request.httpBody = rb
return request
case .menuList:
guard let url = URL(string: "https://jcouserapidev.oxxo.co.id/home/app")
else {preconditionFailure("Invalid URL format")}
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(Constants.API_TOKEN, forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"
return request
}
}
}
LoginView模型
class LoginViewModel: ObservableObject, LoginService {
// I want to send this 2 variables to APIEndpoint
@Published var user = ""
@Published var pass = ""
var cancellables = Set<AnyCancellable>()
init(apiSession: APIService = APISession()) {
self.apiSession = apiSession
}
func login() {
let cancellable = self.login()
.sink(receiveCompletion: { result in
switch result {
case .failure(let error):
print("Handle error: \(error)")
case .finished:
break
}
}) { (detail) in
print(detail)
}
cancellables.insert(cancellable)
}
}
请求生成器
protocol RequestBuilder {
var urlRequest: URLRequest {get}
}
登录服务
protocol LoginService {
var apiSession: APIService {get}
func login() -> AnyPublisher<LoginAPIResponse, APIError>
}
extension LoginService {
func login() -> AnyPublisher<LoginAPIResponse, APIError> {
return apiSession.request(with: APIEndpoint.userLogin)
.eraseToAnyPublisher()
}
}
协议登录服务{
var apiSession:APIService{get}
func login()->AnyPublisher
}
扩展登录服务{
func login()->AnyPublisher{
返回apiSession.request(使用:apident.userLogin)
.删除任何发布者()
}
}
蜂房服务
protocol APIService {
func request<T: Decodable>(with builder: RequestBuilder, test: String) -> AnyPublisher<T, APIError>
}
协议服务{
func请求(使用builder:RequestBuilder,test:String)->AnyPublisher
}
阿皮塞恩
struct APISession: APIService {
func request<T>(with builder: RequestBuilder) -> AnyPublisher<T, APIError> where T: Decodable {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
return URLSession.shared
.dataTaskPublisher(for: builder.urlRequest)
.receive(on: DispatchQueue.main)
.mapError { _ in .unknown }
.flatMap { data, response -> AnyPublisher<T, APIError> in
if let response = response as? HTTPURLResponse {
if (200...299).contains(response.statusCode) {
print(String(data: data, encoding: .utf8) ?? "")
return Just(data)
.decode(type: T.self, decoder: decoder)
.mapError {_ in .decodingError}
.eraseToAnyPublisher()
} else {
return Fail(error: APIError.httpError(response.statusCode))
.eraseToAnyPublisher()
}
}
return Fail(error: APIError.unknown)
.eraseToAnyPublisher()
}
.eraseToAnyPublisher()
}
}
struct APISession:APIService{
func request(带builder:RequestBuilder)->AnyPublisher,其中T:Decodable{
let decoder=JSONDecoder()
decoder.keyDecodingStrategy=.convertFromSnakeCase
返回URLSession.shared
.dataTaskPublisher(适用于:builder.urlRequest)
.receive(在:DispatchQueue.main上)
.maperor{in.unknown}
.flatMap{data,response->AnyPublisher in
如果let response=response as?HTTPURLResponse{
if(200…299).contains(response.statusCode){
打印(字符串(数据:数据,编码:.utf8)??“”)
仅返回(数据)
.解码(类型:T.self,解码器:解码器)
.mapError{in.decodingError}
.删除任何发布者()
}否则{
返回失败(错误:apirerror.httpError(response.statusCode))
.删除任何发布者()
}
}
返回失败(错误:APIRROR.unknown)
.删除任何发布者()
}
.删除任何发布者()
}
}
提前感谢大家。您应该在以下表单中更改您的枚举:
enum端点{
case userLogin(用户:字符串,密码:字符串)
案例专家
}
更改您的requestBuilder:
扩展API端点:RequestBuilder{
var urlRequest:urlRequest{
切换自身{
case.userLogin(let user,let password):
guard let url=url(字符串:https://jcouserapidev.oxxo.co.id/home/app")
else{PremissionFailure(“无效URL格式”)}
var-request=URLRequest(url:url)
request.setValue(“application/json”,forHTTPHeaderField:“Content Type”)
request.setValue(Constants.API_令牌,用于HttpHeaderField:“授权”)
request.httpMethod=“POST”
let body:[字符串:任意]=[“用户”:用户,“通过”:通过]
让rb=try!JSONSerialization.data(带jsonobject:body)
request.httpBody=rb
退货申请
案例.菜单列表:
guard let url=url(字符串:https://jcouserapidev.oxxo.co.id/home/app")
else{PremissionFailure(“无效URL格式”)}
var-request=URLRequest(url:url)
request.setValue(“application/json”,forHTTPHeaderField:“Content Type”)
request.setValue(Constants.API_令牌,用于HttpHeaderField:“授权”)
request.httpMethod=“POST”
退货申请
}
}
}
在此之后,在所有
登录
功能中,您应该将用户
和密码
作为参数传递谢谢您的回答,但我仍然无法从viewmodel中获取要传递到APIEndpoint的值,我需要在LoginViewModel和LoginService中做什么?我很抱歉,我真的是新手,我尝试过调整代码,但它只是不断弹出错误