Извлечение значений свойств @IBOutlets из контроллера основного представления - PullRequest
0 голосов
/ 15 октября 2018

С самого начала я работал с моделью MVP, чтобы все продолжалось, но теперь, спустя месяцы, я понимаю, что большинство моих проектов имеют «контроллеры массового просмотра».Вначале расширения работали хорошо, чтобы разгрузить фактический файл контроллера представления, но технически код все еще находится в контроллере представления.

Более практичный подход к моему вопросу - в моем последнем проекте, где у меня была покупка в приложении, после чего пользователь получает некоторые новые функции, разблокированные.Мы предполагаем, что вся логика StoreKit выполняет свою работу, покупка была успешно завершена, и вы как раз собираетесь передать новые функциональные возможности пользователю.

Чтобы справиться с этим, у меня есть функция func unlockFeaturesвнутри контроллера основного вида (PreferencesViewController), который запускается наблюдателем при успешной покупке в приложении.

class PreferencesViewController: UIViewController {

    ...
    @obc func unlockFeatures {
        InAppPuchaseButton.isEnabled = false
        InAppPuchaseButton.applyOpacity(opacity: 1.0)
    }
    ...
}

В этот момент, когда мне нужно было только включить и изменить прозрачностьодной кнопки все кажется чистым.Мой вопрос заключается в том, как обрабатывать ситуации, когда внутри func unlockFeatures вам нужно обрабатывать несколько строк кода пользовательского интерфейса, например:

class PreferencesViewController: UIViewController {

    ...
    @obc func unlockFeatures {
        InAppPuchaseButton.isEnabled = false
        InAppPuchaseButton.applyOpacity(opacity: 1.0)
        InAppPuchaseButton.isHidden = false
        RefreshLabel.text = "DOWNLOADING EVENTS"
        self.activityIndicator.stopAnimating()
        //And keep going for 50 lines more of code!!
    }
    ...
}

Для меня это выглядит загроможденным, и я хотел бы извлечь эту функцию за пределы PreferencesViewController и звони, когда мне это нужно.Есть ли способ извлечь всю эту логику пользовательского интерфейса за пределы класса контроллера представления или это плохая практика?

1 Ответ

0 голосов
/ 15 октября 2018

Отличный пример покупок в приложении.Здесь мы хотели бы предоставить один централизованный объект, который может (например):

  • выступать в качестве локуса для кода, связанного с IAP, который не включает интерфейс,например, выступая в качестве SKPaymentTransactionObserver

  • Выступать в качестве шлюза для остальной части приложения, чтобы иметь возможность спросить, совершил ли пользователь покупку (конечно, наш объект будет знать ответ поконсультирование пользователей по умолчанию, но это будет деталь реализации, скрытая его общедоступным API)

Имеет смысл отключить эти функции от контроллера представления, потому что они не имеют ничего общего с управление любыми представлениями .

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


В более широком контексте я постоянно использую этот тип вспомогательного объекта, чтобы решить именно ту проблему, которую вы описываете.Например, в игровом приложении у меня был код lot в контроллере основного вида, пока я не разбил несколько областей работы на вспомогательные классы, потому что они действительно не имели никакого отношения к элементу управления просмотров .Например, логика таймера и ведение счета ушли в вспомогательный объект.«Конечный автомат», который решает, что делать дальше, когда мы перейдем к следующему этапу игры, превратился в вспомогательный объект.И так далее.


В своем исправленном вопросе вы говорите:

Для меня это выглядит загроможденным, и я хотел бы извлечь эту функцию из PreferencesViewController и вызвать ее простокогда мне это нужно.Есть ли способ извлечь всю эту логику пользовательского интерфейса вне класса контроллера представления, или это плохая практика?

Здесь нет ничего "загроможденного";это все в одной функции, и это правильно.Хорошей практикой является использование пользовательского интерфейса внутри класса контроллера представления, но, возможно, вызов из другого места (например, помощником, которого я описал в своем ответе).На самом деле, то, что I сделал бы, - это чтобы помощник отправил уведомление, чтобы он не знал о том, что произойдет;это просто кричит "Хорошо, пользователь купил!"и контроллер представления получает уведомление и вызывает этот метод.

...