-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge commit '6965fe817fe14075b66413ba27e7072c60d699d9' into feature/F…
…EM-831-Changes * commit '6965fe817fe14075b66413ba27e7072c60d699d9': (65 commits) Simple OVP Session Provider (#90) #FEM-1117 (#88) #FEC-6462 #comment [~oren.melamed], do we know this issue doesn’t happen for Phoenix too? If you could get me a response sample for concurrency I could check. (#87) Added initObj key to the media mark request. It was missing. (#84) fix podspec Fec 6473 (#86) Small enhancement to player config (#82) Fixes memory leak created by Apple’s interoperability (#85) Update README.md Fix to prevent initializing `PlayKitManager` from outside in swift and objc (#81) Some tweaks for objective-c compatibility (#80) fixed issue with `KalturaLiveStatsPlugin` conforming to PKPlugin (#79) support wideinve privae pod Config API change and PKPlugin (#78) LocalAssetsManager: rename registerDownloadedAsset to assetDownloadFinished. (#77) bump v0.1.9 fix event observation on KalturaLiveStatsPlugin fix issues with tests after events change. (#74) bump v0.1.8 update podfile ... # Conflicts: # Example/PlayKit.xcodeproj/project.pbxproj # Example/Podfile # Example/Podfile.lock # Example/Tests/MediaEntryProvider/OVPMediaProviederTest.swift
- Loading branch information
Showing
67 changed files
with
1,879 additions
and
1,068 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
3.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
3.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// | ||
// AppStateProvider.swift | ||
// Pods | ||
// | ||
// Created by Gal Orlanczyk on 19/01/2017. | ||
// | ||
// | ||
|
||
import Foundation | ||
|
||
/// The delegate of `AppStateProvider`, allows the delegate to inform on app state notifications. | ||
protocol AppStateProviderDelegate: class { | ||
/// fire this delegate function when received observation event. | ||
/// for every observer with the same observation event process the on observe block. | ||
func appStateEventPosted(name: ObservationName) | ||
} | ||
|
||
/// The interface of `AppStateProvider`, allows us to better divide the logic and mock easier. | ||
protocol AppStateProviderProtocol { | ||
var notificationsManager: NotificationsManager { get } | ||
/// Holds all the observation names we will be observing. | ||
/// If you want to observe more events add them here. | ||
var observationNames: Set<ObservationName> { get } | ||
weak var delegate: AppStateProviderDelegate? { get } | ||
} | ||
|
||
extension AppStateProviderProtocol { | ||
/// Add observers for the provided notification names. | ||
func addObservers() { | ||
observationNames.forEach { name in | ||
notificationsManager.addObserver(notificationName: name) { notification in | ||
self.delegate?.appStateEventPosted(name: notification.name) | ||
} | ||
} | ||
} | ||
|
||
/// Remove observers for the provided notification names. | ||
func removeObservers() { | ||
notificationsManager.removeAllObservers() | ||
} | ||
|
||
} | ||
|
||
/************************************************************/ | ||
// MARK: - AppStateProvider | ||
/************************************************************/ | ||
|
||
/// The `AppStateProvider` is a provider for receiving events from the system about app states. | ||
/// Used to seperate the events providing from the app state subject and enabling us to mock better. | ||
final class AppStateProvider: AppStateProviderProtocol { | ||
|
||
init(delegate: AppStateProviderDelegate? = nil) { | ||
self.delegate = delegate | ||
} | ||
|
||
var delegate: AppStateProviderDelegate? | ||
|
||
let notificationsManager = NotificationsManager() | ||
|
||
let observationNames: Set<ObservationName> = [ | ||
.UIApplicationWillTerminate, | ||
.UIApplicationDidEnterBackground, | ||
.UIApplicationDidBecomeActive, | ||
.UIApplicationWillResignActive, | ||
.UIApplicationWillEnterForeground | ||
] | ||
|
||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
// | ||
// AppStateSubject.swift | ||
// Pods | ||
// | ||
// Created by Gal Orlanczyk on 19/01/2017. | ||
// | ||
// | ||
|
||
import Foundation | ||
|
||
/// The interface of `AppStateSubject`, allows us to better divide the logic and mock easier. | ||
protocol AppStateSubjectProtocol: class, AppStateProviderDelegate { | ||
associatedtype InstanceType | ||
static var sharedInstance: InstanceType { get } | ||
/// Lock object for synchronizing access. | ||
var lock: AnyObject { get } | ||
/// The app state events provider. | ||
var appStateProvider: AppStateProvider { get } | ||
/// The current app state observers. | ||
var observers: [AppStateObservable] { get set } | ||
/// States whether currently observing. | ||
/// - note: when mocking set initial value to false. | ||
var isObserving: Bool { get set } | ||
} | ||
|
||
extension AppStateSubjectProtocol { | ||
/// Starts observing the app state events | ||
func startObservingAppState() { | ||
sync { | ||
// if not already observing and has more than 0 oberserver then start observing | ||
if !isObserving { | ||
PKLog.trace("start observing app state") | ||
appStateProvider.addObservers() | ||
isObserving = true | ||
} | ||
} | ||
} | ||
|
||
/// Stops observing the app state events. | ||
func stopObservingAppState() { | ||
sync { | ||
if isObserving { | ||
PKLog.trace("stop observing app state") | ||
appStateProvider.removeObservers() | ||
isObserving = false | ||
} | ||
} | ||
} | ||
|
||
/// Adds an observer to inform when state events are posted. | ||
func add(observer: AppStateObservable) { | ||
sync { | ||
PKLog.trace("add observer, \(observer)") | ||
// if no observers were available start observing now | ||
if observers.count == 0 && !isObserving { | ||
startObservingAppState() | ||
} | ||
observers.append(observer) | ||
} | ||
} | ||
|
||
/// Removes an observer to stop being inform when state events are posted. | ||
func remove(observer: AppStateObservable) { | ||
sync { | ||
for i in 0..<observers.count { | ||
if observers[i] === observer { | ||
let removedObserver = observers.remove(at: i) | ||
PKLog.trace("removed observer, \(removedObserver)") | ||
// if no more observers available stop observing | ||
if observers.count == 0 && isObserving { | ||
stopObservingAppState() | ||
} | ||
break | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// Removes all observers and stop observing. | ||
func removeAllObservers() { | ||
sync { | ||
if observers.count > 0 { | ||
PKLog.trace("remove all observers") | ||
observers.removeAll() | ||
stopObservingAppState() | ||
} | ||
} | ||
} | ||
|
||
/************************************************************/ | ||
// MARK: AppStateProviderDelegate | ||
/************************************************************/ | ||
|
||
func appStateEventPosted(name: ObservationName) { | ||
sync { | ||
PKLog.trace("app state event posted with name: \(name.rawValue)") | ||
for observer in self.observers { | ||
let filteredObservations = observer.observations.filter { $0.name == name } | ||
for observation in filteredObservations { | ||
observation.onObserve() | ||
} | ||
} | ||
} | ||
} | ||
|
||
// MARK: Private | ||
/// synchornized function | ||
private func sync(block: () -> ()) { | ||
objc_sync_enter(lock) | ||
block() | ||
objc_sync_exit(lock) | ||
} | ||
|
||
} | ||
|
||
/************************************************************/ | ||
// MARK: - AppStateSubject | ||
/************************************************************/ | ||
|
||
/// The `AppStateSubject` class provides a way to add/remove application state observers. | ||
/// | ||
/// - note: Subject is a class that is both observing and being observered. | ||
/// In our case listening to events using the provider and posting using the obervations onObserve. | ||
/// | ||
/// **For Unit-Testing:** When mocking this object just conform to the `AppStateSubjectProtocol`. | ||
/// For firing events to observers manually use `appStateEventPosted(name: ObservationName)` with the observation name. | ||
final class AppStateSubject: AppStateSubjectProtocol { | ||
|
||
// singleton object and private init to prevent unwanted creation of more objects. | ||
static let sharedInstance = AppStateSubject() | ||
private init() { | ||
self.appStateProvider = AppStateProvider() | ||
self.appStateProvider.delegate = self | ||
} | ||
|
||
let lock: AnyObject = UUID().uuidString as AnyObject | ||
|
||
var observers = [AppStateObservable]() | ||
var appStateProvider: AppStateProvider | ||
var isObserving = false | ||
} | ||
|
||
/************************************************************/ | ||
// MARK: - Types | ||
/************************************************************/ | ||
|
||
/// Used to specify observation name | ||
typealias ObservationName = Notification.Name // used as typealias in case we will change type in the future. | ||
|
||
/// represents a single observation with observation name as the type, and a block to perform when observing. | ||
struct NotificationObservation: Hashable { | ||
var name: ObservationName | ||
var onObserve: () -> Void | ||
|
||
var hashValue: Int { | ||
return name.rawValue.hash | ||
} | ||
} | ||
|
||
func == (lhs: NotificationObservation, rhs: NotificationObservation) -> Bool { | ||
return lhs.name.rawValue == rhs.name.rawValue | ||
} | ||
|
||
/// A type that provides a set of NotificationObservation to observe. | ||
/// This interface defines the observations we would want in our class, for example a set of [willTerminate, didEnterBackground etc.] | ||
protocol AppStateObservable: AnyObject { | ||
var observations: Set<NotificationObservation> { get } | ||
} |
Oops, something went wrong.