как опубликовать данные сетевого запроса, используя Combine Framework и SwiftUI - PullRequest
3 голосов
/ 30 октября 2019

Я разрабатываю приложение для iOS с использованием swiftUI и Combine Framework, а также MVVM. Я хочу обработать запрос API входа в отдельный класс, называемый LoginService, который используется в LoginViewModel. Теперь я хочу знать, как я должен публиковать и наблюдать атрибуты между view и ViewModel. Я имею в виду, что ViewModel является ObservableObject и наблюдается в View, но, поскольку я обрабатываю сетевой запрос в классе Service, как LoginService уведомляет LoginViewModel и LoginView о получении данных и обновлении View?

import Foundation
import Combine

class LoginViewModel: ObservableObject {

    @Published var user = UserModel()

    @Published var LoginStatus: Bool = false

    @Published var LoginMessage: String = ""

    var service = LoginService()

    func Login(With email: String, And password: String) -> Bool {
        service.validateLogin(email: email, password: password)
        return false
    }
}

Это код для LoginViewModel. Как LoginService должен изменить значения LoginStatus, LoginMessage и пользователя, когда данные получены с сервера, чтобы уведомить View? Я говорю это потому, что, насколько я знаю, вы можете наблюдать ObservableObjects только в представлении (SwiftUI).

1 Ответ

0 голосов
/ 30 октября 2019

Хорошо, я возьму ваш пример и сделаю следующее:

Я предположил, что ваша служба вернет true или false

import Foundation
import Combine

class LoginViewModel: ObservableObject {

    @Published var LoginStatus: Bool = false

    @Published var LoginMessage: String = ""

    var service = LoginService()

    func Login(_ email: String, _ password: String) -> Bool {
        self.LoginStatus  = service.validateLogin(email: email, password: password)
        return self.LoginStatus
    }
}

По вашему мнению:


import SwiftUI

struct ContentView : View {

    @ObservedObject var model = LoginViewModel()

    var body: some View {
        VStack {
            Button(action: {
                _ = self.model.Login("TestUser", "TestPassword")
            }, label: {
                Text("Login")
            })
            Text(self.model.LoginStatus ? "Logged In" : "Not Logged in")
        }
    }
}

Это должно быть что-то в этом роде.

Я удалил UserModel, потому что вы не должны вкладывать модели.

Надеюсь, это поможет.

РЕДАКТИРОВАТЬ 1:

Для автоматической проверки чего-либо можно использовать onApear() в своем представлении или прослушивать изменения с помощью olnrecieve() для обновления пользовательского интерфейса или состояния

import SwiftUI

struct ContentView : View {

    @ObservedObject var model = LoginViewModel()

    var body: some View {
        VStack {
            Button(action: {
                _ = self.model.Login("TestUser", "TestPassword")
            }, label: {
                Text("Login")
            })
            Text(self.model.LoginStatus ? "Logged In" : "Not Logged in")
        }.onAppear {
            // call a function that gets something from your server 
            // and modifies your state
            self.model.validate()
        }.onReceive(self.model.$LoginMessage, perform: { message in
               // here you can update your state or your ui
               // according the LoginMessage... this gets called
               // whenever LoginMessage changes in your model
        })
    }
}

...