2016-08-23 10 views
2

Имея мою первую трещину в POP. В этом случае я хочу украсить некоторые UIViewControllers так, чтобы они автоматически поднимали событие аналитики «Просмотр страницы».Протоколированное программирование, неявно вызывающий метод расширения

Так что я создал протокол, а также и расширение этого протокола:

protocol ReportPageViewedEvent { 
    func reportPageViewed() 
    var pageName : String? { get set } 
} 

extension ReportPageViewedEvent where Self: UIViewController 
{ 
    func reportPageViewed() 
    { 
     guard let pageName = self.pageName else 
     { 
      fatalError("UIViewController implements ReportPageViewEvent protocol but did not set pageName property") 
     } 
     let eventBusiness = EventBusiness.sharedInstance 
     eventBusiness.logUserViewedPage(pageName) 
    } 
} 

Это работает, как я хочу, если я декорировать UIViewController с ReportPageViewedEvent так:

class HomeView: UIViewController, ReportPageViewedEvent { 

я получаю компилятор, если я не установил «pageName», что именно то, что я хочу.

Где я отклеиваю, где и как вызвать фактический метод reportPageViewed(). Я действительно хочу, чтобы он был вызван от viewDidLoad, что означает, что я либо должен изменять каждый «viewDidLoad» в каждом контроллере, который его использует, либо подклассе, и вызывать метод в суперклассе, который в первую очередь бросает вызов использованию POP.

Есть ли хороший способ достичь этого. Я не могу найти такой пример в любом учебнике/блоге.

+1

Если вы хотите, чтобы он был в каждом представлении ViewController, я бы сказал, что подкласс является лучшим решением. – h345k34cr

+1

Расширение добавляет дополнительные возможности классу, но не делает объекты использующими эту возможность. Вам нужно либо вызвать его вручную, либо использовать традиционное подклассов, чтобы вы могли переопределить унаследованное поведение. Кроме того, 'viewWillAppear' может быть лучшей точкой отчетности, поскольку экземпляр ViewController загружается только один раз, но может быть представлен много раз – Paulw11

+0

Ой, глупая ошибка, когда вы не вызываете его на viewWillAppear. Я старался следовать этому: http://krakendev.io/blog/subclassing-can-suck-and-heres-why, но он отклеился при первом препятствии. Было бы идеально, если бы я мог назвать это автоматически, поскольку украшение классов с необходимой функциональностью кажется хорошим подходом. Старался избегать подкласса для этого. –

ответ

1

В принципе, на всех экранах вашего приложения всегда присутствует какое-то поведение. Поэтому уместно создать класс, называемый (например) BaseViewController, чтобы все остальные контроллеры представления наследовали его. В представлении BaseViewControllerDidLoad вы можете вызвать метод reportPageViewed(). Однако этот подход не требует программирования, ориентированного на протоколы. Протоколы полезны, когда вам нужно назначить такое же поведение объектам, которые не имеют ничего общего (что не относится к экранам приложений).