Ответ
Самый ранний этап для настройки аналитики — это методы инициализации экземпляра класса, а не методы жизненного цикла вью.
Порядок и рекомендуемые методы:
init(nibName:bundle:)— для контроллеров, создаваемых программно.init?(coder:)— для контроллеров, загружаемых из Storyboard или XIB.awakeFromNib()— вызывается после загрузки всех объектов из архива (только для контроллеров из Storyboard/XIB).
Пример реализации:
class AnalyticsViewController: UIViewController {
// Для программной инициализации
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
trackEvent("ViewController initialized programmatically")
}
// Для инициализации из Storyboard/XIB
required init?(coder: NSCoder) {
super.init(coder: coder)
trackEvent("ViewController initialized from storyboard")
}
// Дополнительный ранний метод для Storyboard/XIB
override func awakeFromNib() {
super.awakeFromNib()
trackEvent("ViewController awoke from NIB")
}
private func trackEvent(_ message: String) {
Analytics.shared.log(event: message)
}
}
Почему не viewDidLoad()? viewDidLoad() вызывается позже, когда вью уже загружена. Для отслеживания самого факта создания контроллера методы инициализации подходят лучше.
Ответ 18+ 🔞
Смотри, народ постоянно путает, когда втыкать аналитику в контроллер. Все лезут в viewDidLoad, как будто там святое место, а потом охуевают, почему события дублируются или вообще не летят.
А вся магия начинается гораздо раньше, в этих ваших методах инициализации, блядь. Это как фундамент закладывать, а не шторы вешать, когда дом ещё не достроен.
Вот тебе священный порядок, куда совать нос:
init(nibName:bundle:)— это когда ты контроллер из воздуха материализуешь, кодом, без всяких сторибордов. Прямо в коде:let vc = MyVC().init?(coder:)— а это уже для тех, кто любит визуальный дизайн. Срабатывает, когда система разворачивает твой контроллер из архива (сториборд или xib-файл).awakeFromNib()— финальный аккорд для сторибордных ребят. Вызывается, когда все аутлеты и экшены уже привязаны, но вьюха ещё не нарисовалась.
Вот, смотри, как это выглядит в коде, чтоб не быть пиздаболом:
class AnalyticsViewController: UIViewController {
// Для ручного создания, из пальца
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
trackEvent("ViewController initialized programmatically")
}
// Для красотулей из Interface Builder
required init?(coder: NSCoder) {
super.init(coder: coder)
trackEvent("ViewController initialized from storyboard")
}
// Финальный пинок для сторибордных объектов
override func awakeFromNib() {
super.awakeFromNib()
trackEvent("ViewController awoke from NIB")
}
private func trackEvent(_ message: String) {
Analytics.shared.log(event: message)
}
}
А теперь главный вопрос: нахуй не viewDidLoad()? Да потому что viewDidLoad — это уже когда вьюха загрузилась, жизненный цикл пошёл, а нам-то надо засечь сам момент, когда контрлер родился, епта! Как младенец — сначала он появляется на свет (init), потом приходит в сознание (awakeFromNib), а уж потом начинает ползать и хулиганить (viewDidLoad). Логично же, блядь?