2021-10-04 16:25:19 +00:00
//
// C o p y r i g h t 2 0 2 1 N e w V e c t o r L t d
//
// L i c e n s e d u n d e r t h e A p a c h e L i c e n s e , V e r s i o n 2 . 0 ( t h e " L i c e n s e " ) ;
// y o u m a y n o t u s e t h i s f i l e e x c e p t i n c o m p l i a n c e w i t h t h e L i c e n s e .
// Y o u m a y o b t a i n a c o p y o f t h e L i c e n s e a t
//
// h t t p : / / w w w . a p a c h e . o r g / l i c e n s e s / L I C E N S E - 2 . 0
//
// U n l e s s r e q u i r e d b y a p p l i c a b l e l a w o r a g r e e d t o i n w r i t i n g , s o f t w a r e
// d i s t r i b u t e d u n d e r t h e L i c e n s e i s d i s t r i b u t e d o n a n " A S I S " B A S I S ,
// W I T H O U T W A R R A N T I E S O R C O N D I T I O N S O F A N Y K I N D , e i t h e r e x p r e s s o r i m p l i e d .
// S e e t h e L i c e n s e f o r t h e s p e c i f i c l a n g u a g e g o v e r n i n g p e r m i s s i o n s a n d
// l i m i t a t i o n s u n d e r t h e L i c e n s e .
//
import Foundation
import WeakDictionary
// / ` N a v i g a t i o n R o u t e r S t o r e ` e n a b l e s t o g e t a N a v i g a t i o n R o u t e r f r o m a U I N a v i g a t i o n C o n t r o l l e r i n s t a n c e .
class NavigationRouterStore : NavigationRouterStoreProtocol {
// MARK: - C o n s t a n t s
static let shared = NavigationRouterStore ( )
// MARK: - P r o p e r t i e s
// FIXME: W e a k D i c t i o n a r y d o e s n o t w o r k w i t h p r o t o c o l
// F i n d a w a y t o u s e N a v i g a t i o n R o u t e r T y p e a s v a l u e
private var navigationRouters = WeakDictionary < UINavigationController , NavigationRouter > ( )
// MARK: - S e t u p
// / A s w e a r e e n s u r i n g t h a t t h e r e i s o n l y o n e n a v i g a t i o n c o n t r o l l e r p e r N a v i g a t i o n R o u t e r , t h e c l a s s h e r e s h o u l d b e u s e d a s a s i n g l e t o n .
private init ( ) {
self . registerNavigationRouterNotifications ( )
}
// MARK: - P u b l i c
2021-10-08 15:03:45 +00:00
func navigationRouter ( for navigationController : UINavigationController ) -> NavigationRouterType {
2021-10-04 16:25:19 +00:00
2021-10-08 15:15:14 +00:00
if let existingNavigationRouter = self . findNavigationRouter ( for : navigationController ) {
2021-10-04 16:25:19 +00:00
return existingNavigationRouter
}
let navigationRouter = NavigationRouter ( navigationController : RiotNavigationController ( ) )
return navigationRouter
}
2021-10-08 15:15:14 +00:00
// MARK: - P r i v a t e
private func findNavigationRouter ( for navigationController : UINavigationController ) -> NavigationRouterType ? {
2021-10-04 16:25:19 +00:00
return self . navigationRouters [ navigationController ]
}
private func removeNavigationRouter ( for navigationController : UINavigationController ) {
self . navigationRouters [ navigationController ] = nil
}
private func registerNavigationRouterNotifications ( ) {
NotificationCenter . default . addObserver ( self , selector : #selector ( navigationRouterDidCreate ( _ : ) ) , name : NavigationRouter . didCreate , object : nil )
NotificationCenter . default . addObserver ( self , selector : #selector ( navigationRouterWillDestroy ( _ : ) ) , name : NavigationRouter . willDestroy , object : nil )
}
@objc private func navigationRouterDidCreate ( _ notification : Notification ) {
guard let userInfo = notification . userInfo ,
let navigationRouter = userInfo [ NavigationRouter . NotificationUserInfoKey . navigationRouter ] as ? NavigationRouterType ,
let navigationController = userInfo [ NavigationRouter . NotificationUserInfoKey . navigationController ] as ? UINavigationController else {
return
}
2021-10-08 15:15:14 +00:00
if let existingNavigationRouter = self . findNavigationRouter ( for : navigationController ) {
2021-10-04 16:25:19 +00:00
fatalError ( " \( existingNavigationRouter ) is already tied to the same navigation controller as \( navigationRouter ) . We should have only one NavigationRouter per navigation controller " )
} else {
// FIXME: W e a k D i c t i o n a r y d o e s n o t w o r k w i t h p r o t o c o l
// F i n d a w a y t o a v o i d t h i s c a s t
self . navigationRouters [ navigationController ] = navigationRouter as ? NavigationRouter
}
}
@objc private func navigationRouterWillDestroy ( _ notification : Notification ) {
guard let userInfo = notification . userInfo ,
let navigationRouter = userInfo [ NavigationRouter . NotificationUserInfoKey . navigationRouter ] as ? NavigationRouterType ,
let navigationController = userInfo [ NavigationRouter . NotificationUserInfoKey . navigationController ] as ? UINavigationController else {
return
}
2021-10-08 15:15:14 +00:00
if let existingNavigationRouter = self . findNavigationRouter ( for : navigationController ) , existingNavigationRouter !== navigationRouter {
2021-10-04 16:25:19 +00:00
fatalError ( " \( existingNavigationRouter ) is already tied to the same navigation controller as \( navigationRouter ) . We should have only one NavigationRouter per navigation controller " )
}
self . removeNavigationRouter ( for : navigationController )
}
}