# Multiple player managers for tvOS Version   4.4.0 of the Wowza Flowplayer Apple SDK added support to manage more than one `AvPlayer` instance simultaneously in your tvOS applications. With the help of these managers, all player instances can be controlled separately as they function independently of each other. For information related to listening to events, managing media playback, and handling errors, see the following pages: * [Listen for events](/docs/wowza-flowplayer/apple-sdk/listen-for-events/) * [Manage media playback](/docs/wowza-flowplayer/apple-sdk/manage-media-playback/) * [Handle errors](/docs/wowza-flowplayer/apple-sdk/handle-errors/) ## Set up multiple managers When using the `FlowplayerManager` class, generally only one `AVPlayer` instance can be controlled at once. However, if you have multiple `AVPlayer` instances in a single view, you can set up multiple managers to handle different players. All events are streamlined into a single source, allowing you to listen to them using the [delegate pattern](/docs/wowza-flowplayer/apple-sdk/tvos-features/multiple-player-managers/#use-delegation-to-identify-a-manager) or the [NotificationCenter](/docs/wowza-flowplayer/apple-sdk/tvos-features/multiple-player-managers/#use-notifications-to-identify-a-manager). In the following example, we create two manager instances with the `FlowplayerManager` class, then load specific media for a main player and a secondary player: ```swift // Declare AVPlayer instances let mainPlayer = AVPlayer() let secondaryPlayer = AVPlayer() // Create two manager instances using the FlowplayerManager class // Associate each manager instances with a player instance lazy var mainManager = FlowplayerManager(avPlayer: mainPlayer) lazy var secondaryManager = FlowplayerManager(avPlayer: secondaryPlayer) // Load the managers and call load() method for each mainManager.load(...) secondaryManager.load(...) ``` ## Identify a manager instance To work with each manager instance, you can use the `id` property of the [FlowplayerAPI protocol](/docs/wowza-flowplayer/apple-sdk/manage-media-playback/#properties). By default, the manager randomly generates and emits the value of this property. You can also set up a manager `id` that uses a custom string. For more, see [Set a custom manager identifier](/docs/wowza-flowplayer/apple-sdk/tvos-features/multiple-player-managers/#set-a-custom-manager-identifier). This section provides examples of how to identify a manager instance, then use the delegate pattern or the notification dispatch mechanism to perform a certain action. ### Use delegation to identify a manager You can use the delegate pattern to listen for an capture the `id` of a manager that's triggered a specific event. The following example monitors changes in the manager's state and responds based on which manager instance triggered the state change. For an event listeners reference, see [Listen for events with the delegate method](/docs/wowza-flowplayer/apple-sdk/listen-for-events/#listen-with-the-delegate-method). ```swift // Declare AVPlayer instances let mainPlayer = AVPlayer() let secondaryPlayer = AVPlayer() // Create two manager instances using the FlowplayerManager class // Associate each manager instances with a player instance lazy var mainManager = FlowplayerManager(avPlayer: mainPlayer) lazy var secondaryManager = FlowplayerManager(avPlayer: secondaryPlayer) // Set delegate property and conform to FlowplayerDelegate protocol mainManager.delegate = self secondaryManager.delegate = self // Use FlowplayerDelegate protocol to observe and respond to manager state changes func player(manager: FlowplayerAPI, didChangeState state: PlayerState) { // Compare id property of mainManager variable and manager parameter guard mainManager.id == manager.id else { // If not equal, indicate event was triggered by secondaryManager instance print("secondaryManager triggered this event") return } // If equal, indicate event was triggered by mainManager instance print("mainManager changed the state to: \(state)") } ``` ### Use notifications to identify a manager You can also use the notification dispatch mechanism in the Wowza Flowplayer Apple SDK to detect the `id` of the manager and respond to manager events. The following code snippet sets up a notification observer for changes in the manager's state. When a state notification is received, it checks the manager's identifier and performs a certain action based on which manager triggered the event. For more information, see [Listen for events with the NotificationCenter](/docs/wowza-flowplayer/apple-sdk/listen-for-events/#listen-with-the-notificationcenter). ```swift // Declare player instances let mainPlayer = FlowplayerView() let secondaryPlayer = FlowplayerView() // Create two manager instances using the FlowplayerManager class // Associate each manager instances with a player instance lazy var mainManager = FlowplayerManager(avPlayer: mainPlayer) lazy var secondaryManager = FlowplayerManager(avPlayer: secondaryPlayer) // Register observer for flowplayerDidChangeState notification NotificationCenter.default.addObserver( self, selector: #selector(onReceivedState), name: .flowplayerDidChangeState, object: nil ) // Call onReceivedState method when notification is received @objc private func onReceivedState(_ notification: Notification) { guard // Retrieve id from notification's user info and check if it matches mainManager id let id = notification.userInfo?[\FlowplayerAPI.id] as? String, mainManager.id == id else { // If not equal, indicate event was triggered by secondaryManager instance print("secondaryManager triggered this event") return } guard let state = notification.object as? PlayerState else { return } // If equal, indicate event was triggered by mainManager instance print("mainManager changed state to: \(state)") } ``` ## Set a custom manager identifier The player's default behavior randomly generates and emits the value of an `id` property to identify each manager instance. You can also set a manager `id` that uses a custom string. This is helpful when you have a requirement to use a specific identifier for your manager. To set up a manager with a custom `id`, you can leverage this `FlowplayerManager` initializer: ```swift public init(avPlayer: AVPlayer? = nil, id: String? = nil) ``` When you [add the player](/docs/wowza-flowplayer/apple-sdk/set-up-the-player/#tvos-projects) to your tvOS project, use the initializer and replace the `[some-id]` placeholder with a desired ID value: ```swift // If not AVPlayer is provided FlowplayerManager will create one let manager = FlowplayerManager(avPlayer: nil, id: "[some-id]") ``` The `avPlayer` and `id` parameters are optional. If `avPlayer` is omitted, the `FlowplayerManager` class creates its own `AVPlayer` instance instead of using an instance you provide.