Как взаимодействовать между сервисом и Viewcontroller?

#ios #swift #firebase

#iOS #swift #firebase

Вопрос:

Я довольно новичок в iOS и разработке Swift. Во многих учебных пособиях по swift firebase все, что связано с firebase (например, аутентификация, выборка и сохранение данных), выполняется в ViewController. Насколько я понял при изучении swift, это напрямую приводит к проблеме «Массивных контроллеров просмотра». В некоторых руководствах они используют такие классы, как «DataService.swift», и получают к ним доступ как к одному элементу:

 class DataService {

   static let dataService: DataService = DataService()

   func createUser(FIRUser: user) {}
   ...
}
  

НО эти классы не имеют связи с контроллером представления, когда они закончили, например, с созданием пользователя. Позвольте мне быть более конкретным. Я думаю, это должно понравиться:

  1. Пользователь нажимает кнопку входа в систему.
  2. Затем ViewController вызывает DataService.CreateUser(user), который обрабатывает данные входа в систему и сохраняет пользовательские данные в firebase.
  3. Если он завершен, он должен сообщить контроллеру представления, что он завершен.
  4. ViewController проверяет результат CreateUser() и переводит пользователя в другое представление.

Как я могу это сделать? На данный момент я использую шаблон делегирования. Это хороший способ справиться с этим?

Комментарии:

1. вам необходимо использовать методы протокола делегирования для обмена данными между ViewControllers и singleton.

2. Существует несколько различных способов справиться с этим. Вы можете использовать NotificationCenter для отправки сообщений о событиях в вашем приложении, вы можете использовать вышеупомянутые шаблоны делегирования / протокола, вы можете добавлять блоки завершения, где это необходимо, и т.д. Вопрос слишком широкий, чтобы дать прямой ответ — я бы предложил изучить каждый из них, чтобы определить, какой метод лучше всего подходит для ваших нужд, а затем задать конкретные вопросы об этом, если вы застряли.

Ответ №1:

Вы можете сделать это таким образом:

 // User.swift
struct User {
    // Declare necessary properties.
    // Such as firstName, lastName, email, etc.
}

// AuthenticationService.swift
protocol AuthenticationService {
    func createUser(user: User, completion: (Error?, User?) -> Void)
}

// AuthServiceProvider.swift
class AuthServiceProvider: AuthenticationService {

    func createUser(user: User, completion: (Error?, User?) -> Void) {
        // Do the necessary work here. 
        // Convert user to an instance of 'FIRUser' if necessary.
        // Use the completion block when you are done.
    }
}

// RegisterViewController.swift
class RegisterViewController: UIViewController {

    var service = AuthServiceProvider()        

    @IBAction func didTapRegisterButton(sender: UIButton) {
        var user = User()
        // Fill the necessary properties to be included.
        // Then call the 'createUser' function.
        service.createUser(user: user) { (error, user) -> Void in
            // This is where you are redirected upon completion.
            // Handle always the error if there is.
            // If there is none, navigate to your next scene/view.
        }
    }
}
  

Кстати, насколько это возможно, просто избегайте реализации одноэлементного класса. Такая реализация может затруднить выполнение некоторых модульных тестов.

Что касается вашей озабоченности по поводу «Массивного контроллера представления», вы можете подумать о модульности вашего проекта. Но прямо сейчас я бы предположил, что лучше столкнуться с этой проблемой «MVC», чем избегать ее.