Skip to content

Commit

Permalink
Merge branch 'release/0.1.x' into release/widevine/0.1.x
Browse files Browse the repository at this point in the history
  • Loading branch information
Eliza Sapir committed Apr 23, 2017
2 parents eb0e564 + eca1995 commit 2fbb871
Show file tree
Hide file tree
Showing 72 changed files with 1,868 additions and 1,011 deletions.
31 changes: 23 additions & 8 deletions Classes/Managers/AppState/AppStateSubject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ protocol AppStateSubjectProtocol: class, AppStateProviderDelegate {
/// The app state events provider.
var appStateProvider: AppStateProvider { get }
/// The current app state observers.
var observers: [AppStateObservable] { get set }
var observers: [AppStateObserver] { get set }
/// States whether currently observing.
/// - note: when mocking set initial value to false.
var isObserving: Bool { get set }
Expand Down Expand Up @@ -50,20 +50,23 @@ extension AppStateSubjectProtocol {
/// Adds an observer to inform when state events are posted.
func add(observer: AppStateObservable) {
sync {
cleanObservers()
PKLog.trace("add observer, \(observer)")
// if no observers were available start observing now
if observers.count == 0 && !isObserving {
startObservingAppState()
}
observers.append(observer)
observers.append(AppStateObserver(observer))
}
}

/// Removes an observer to stop being inform when state events are posted.
func remove(observer: AppStateObservable) {
sync {
cleanObservers()
// search for the observer to remove
for i in 0..<observers.count {
if observers[i] === observer {
if observers[i].observer === observer {
let removedObserver = observers.remove(at: i)
PKLog.trace("removed observer, \(removedObserver)")
// if no more observers available stop observing
Expand Down Expand Up @@ -94,10 +97,11 @@ extension AppStateSubjectProtocol {
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()
for appStateObserver in self.observers {
if let filteredObservations = appStateObserver.observer?.observations.filter({ $0.name == name }) {
for observation in filteredObservations {
observation.onObserve()
}
}
}
}
Expand All @@ -111,6 +115,10 @@ extension AppStateSubjectProtocol {
objc_sync_exit(lock)
}

/// remove nil observers from our list
private func cleanObservers() {
self.observers = self.observers.filter { $0.observer != nil }
}
}

/************************************************************/
Expand All @@ -135,7 +143,7 @@ final class AppStateSubject: AppStateSubjectProtocol {

let lock: AnyObject = UUID().uuidString as AnyObject

var observers = [AppStateObservable]()
var observers = [AppStateObserver]()
var appStateProvider: AppStateProvider
var isObserving = false
}
Expand All @@ -161,6 +169,13 @@ func == (lhs: NotificationObservation, rhs: NotificationObservation) -> Bool {
return lhs.name.rawValue == rhs.name.rawValue
}

class AppStateObserver: AnyObject {
weak var observer: AppStateObservable?
init(_ observer: AppStateObservable) {
self.observer = observer
}
}

/// 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 {
Expand Down
10 changes: 7 additions & 3 deletions Classes/MessageBus.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
import Foundation

private struct Observation {
/// the observer of the event
weak var observer: AnyObject?
/// the dispatchQueue to observe the events on.
let observeOn: DispatchQueue
/// the block of code to be performed when event fires.
let block: (PKEvent) -> Void
}

/// `MessageBus` object handles all event message observing and posting
@objc public class MessageBus: NSObject {
private var observations = [String: [Observation]]()
private let lock: AnyObject = UUID().uuidString as AnyObject
Expand All @@ -28,7 +32,7 @@ private struct Observation {

private func add(observer: AnyObject, events: [PKEvent.Type], observeOn dispatchQueue: DispatchQueue = DispatchQueue.main, block: @escaping (PKEvent)->Void) {
sync {
PKLog.debug("Add observer: \(observer) for events: \(events)")
PKLog.debug("Add observer: \(String(describing: observer)) for events: \(String(describing: events))")
events.forEach { (et) in
let typeId = NSStringFromClass(et)
var observationList: [Observation] = observations[typeId] ?? []
Expand All @@ -40,7 +44,7 @@ private struct Observation {

@objc public func removeObserver(_ observer: AnyObject, events: [PKEvent.Type]) {
sync {
PKLog.debug("Remove observer: \(observer) for events: \(events)")
PKLog.debug("Remove observer: \(String(describing: observer)) for events: \(String(describing: events))")
events.forEach { (et) in
let typeId = NSStringFromClass(et)

Expand All @@ -55,7 +59,7 @@ private struct Observation {

@objc public func post(_ event: PKEvent) {
DispatchQueue.global().async { [weak self] in
PKLog.info("Post event: \(event)")
PKLog.info("Post event: \(String(describing: type(of: event)))")
let typeId = NSStringFromClass(type(of: event))

if let array = self?.observations[typeId] {
Expand Down
42 changes: 42 additions & 0 deletions Classes/Network/KalturaPlaybackRequestAdapter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// KalturaPlaybackRequestAdapter.swift
// Pods
//
// Created by Gal Orlanczyk on 05/04/2017.
//
//

import Foundation

class KalturaPlaybackRequestAdapter: PKRequestParamsAdapter {

private var playSessionId: UUID

init(playSessionId: UUID) {
self.playSessionId = playSessionId
}

public static func setup(player: Player) {
let adapter = KalturaPlaybackRequestAdapter(playSessionId: player.sessionId)
player.settings.set(contentRequestAdapter: adapter)
}

public func adapt(requestParams: PKRequestParams) -> PKRequestParams {
guard requestParams.url.path.contains("/playManifest/") else { return requestParams }
guard var urlComponents = URLComponents(url: requestParams.url, resolvingAgainstBaseURL: false) else { return requestParams }
// add query items to the request
let queryItems = [URLQueryItem(name: "playSessionId", value: self.playSessionId.uuidString), URLQueryItem(name: "clientTag", value: PlayKitManager.clientTag)]
if var urlQueryItems = urlComponents.queryItems {
urlQueryItems += queryItems
urlComponents.queryItems = urlQueryItems
} else {
urlComponents.queryItems = queryItems
}
// create the url
guard let url = urlComponents.url else {
PKLog.debug("failed to create url after appending query items")
return requestParams
}
return PKRequestParams(url: url, headers: requestParams.headers)
}
}
38 changes: 27 additions & 11 deletions Classes/PKError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ enum PlayerError: PKError {
case failedToLoadAssetFromKeys(rootError: NSError?)
case assetNotPlayable
case failedToPlayToEndTime(rootError: NSError)
case playerItemErrorLogEvent(errorLogEvent: AVPlayerItemErrorLogEvent)

static let domain = "com.kaltura.playkit.error.player"

Expand All @@ -28,7 +27,6 @@ enum PlayerError: PKError {
case .failedToLoadAssetFromKeys: return PKErrorCode.failedToLoadAssetFromKeys
case .assetNotPlayable: return PKErrorCode.assetNotPlayable
case .failedToPlayToEndTime: return PKErrorCode.failedToPlayToEndTime
case .playerItemErrorLogEvent: return PKErrorCode.playerItemErrorLogEvent
}
}

Expand All @@ -37,7 +35,6 @@ enum PlayerError: PKError {
case .failedToLoadAssetFromKeys: return "Can't use this AVAsset because one of it's keys failed to load"
case .assetNotPlayable: return "Can't use this AVAsset because it isn't playable"
case .failedToPlayToEndTime: return "Item failed to play to its end time"
case .playerItemErrorLogEvent(let errorLogEvent): return errorLogEvent.errorComment ?? ""
}
}

Expand All @@ -50,15 +47,33 @@ enum PlayerError: PKError {
return [:]
case .assetNotPlayable: return [:]
case .failedToPlayToEndTime(let rootError): return [PKErrorKeys.RootErrorKey: rootError]
case .playerItemErrorLogEvent(let errorLogEvent):
return [
PKErrorKeys.RootCodeKey: errorLogEvent.errorStatusCode,
PKErrorKeys.RootDomainKey: errorLogEvent.errorDomain
]
}
}
}

/// `PlayerErrorLog` represents an error log emitted from AVPlayer (usually non-fatal).
struct PlayerErrorLog: PKError {

static var domain = PlayerError.domain

let errorLogEvent: AVPlayerItemErrorLogEvent

var code: Int {
return PKErrorCode.playerItemErrorLogEvent
}

var errorDescription: String {
return errorLogEvent.errorComment ?? ""
}

var userInfo: [String: Any] {
return [
PKErrorKeys.RootCodeKey: errorLogEvent.errorStatusCode,
PKErrorKeys.RootDomainKey: errorLogEvent.errorDomain
]
}
}

/************************************************************/
// MARK: - PKPluginError
/************************************************************/
Expand Down Expand Up @@ -111,7 +126,7 @@ protocol PKError: Error, CustomStringConvertible {

/**
The error code.
use `switch self` to retrive the value in **enums**.
use `switch self` to retrieve the value in **enums**.

````
var code: Int {
Expand Down Expand Up @@ -160,7 +175,7 @@ protocol PKError: Error, CustomStringConvertible {

extension PKError {
/// description string
var description: String {
public var description: String {
return "\(type(of: self)) ,domain: \(type(of: self).domain), errorCode: \(self.code)"
}

Expand Down Expand Up @@ -222,7 +237,8 @@ struct PKErrorKeys {
@objc(FailedToLoadAssetFromKeys) public static let failedToLoadAssetFromKeys = 7000
@objc(AssetNotPlayable) public static let assetNotPlayable = 7001
@objc(FailedToPlayToEndTime) public static let failedToPlayToEndTime = 7002
@objc(PlayerItemErrorLogEvent) public static let playerItemErrorLogEvent = 7003
// PlayerErrorLog
@objc(PlayerItemErrorLogEvent) public static let playerItemErrorLogEvent = 7100
// PKPluginError
@objc(FailedToCreatePlugin) public static let failedToCreatePlugin = 2000
@objc(MissingPluginConfig) public static let missingPluginConfig = 2001
Expand Down
26 changes: 26 additions & 0 deletions Classes/PKRequestParams.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// PKRequestInfo.swift
// Pods
//
// Created by Gal Orlanczyk on 04/04/2017.
//
//

import Foundation

/// `PKRequestParamsDecorator` used for getting updated request info
@objc public protocol PKRequestParamsAdapter {
func adapt(requestParams: PKRequestParams) -> PKRequestParams
}

@objc public class PKRequestParams: NSObject {

public let url: URL
public let headers: [String: String]?

init(url: URL, headers: [String: String]?) {
self.url = url
self.headers = headers
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ extension AVPlayerEngine {
return
}

// When changing media (loading new asset) we want to reset isFirstReady in order to receive `CanPlay` & `LoadedMetadata` accuratly.
self.isFirstReady = true

/*
We can play this asset. Create a new `AVPlayerItem` and make
it our player's current item.
Expand Down
Loading

0 comments on commit 2fbb871

Please sign in to comment.