From a5de53f93debf86bcd80b082ce255abf6ee31028 Mon Sep 17 00:00:00 2001 From: ThibaultBee Date: Tue, 6 Dec 2022 10:43:53 +0000 Subject: [PATCH] Feature/ios task cancellation --- .openapi-generator/FILES | 8 +- .../Controller/UploaderViewController.swift | 24 +- README.md | 18 +- Sources/APIs.swift | 19 +- Sources/APIs/AuthenticationAPI.swift | 4 +- Sources/APIs/CaptionsAPI.swift | 10 +- Sources/APIs/ChaptersAPI.swift | 8 +- Sources/APIs/LiveStreamsAPI.swift | 14 +- Sources/APIs/PlayerThemesAPI.swift | 14 +- Sources/APIs/RawStatisticsAPI.swift | 6 +- Sources/APIs/UploadTokensAPI.swift | 8 +- Sources/APIs/VideosAPI.swift | 263 +++++++----------- Sources/APIs/WatermarksAPI.swift | 6 +- Sources/APIs/WebhooksAPI.swift | 8 +- Sources/AlamofireImplementations.swift | 16 +- Sources/Extensions.swift | 16 ++ Sources/Models.swift | 35 +++ Sources/Upload/ChunkInputStream.swift | 49 ---- Sources/Upload/FileChunkInputStream.swift | 69 +++++ Sources/Upload/FileChunksBuilder.swift | 23 -- Sources/Upload/FileReaders.swift | 82 ------ .../ProgressiveUploadSessionProtocol.swift | 12 + .../Upload/ProgressiveUploadSessioning.swift | 9 - Sources/Upload/RequestTaskQueue.swift | 102 +++++++ .../Upload/UploadChunkRequestTaskQueue.swift | 118 ++++++++ .../Integration/VideosApiTests.swift | 36 ++- 26 files changed, 566 insertions(+), 411 deletions(-) delete mode 100644 Sources/Upload/ChunkInputStream.swift create mode 100644 Sources/Upload/FileChunkInputStream.swift delete mode 100644 Sources/Upload/FileChunksBuilder.swift delete mode 100644 Sources/Upload/FileReaders.swift create mode 100644 Sources/Upload/ProgressiveUploadSessionProtocol.swift delete mode 100644 Sources/Upload/ProgressiveUploadSessioning.swift create mode 100644 Sources/Upload/RequestTaskQueue.swift create mode 100644 Sources/Upload/UploadChunkRequestTaskQueue.swift diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index f59fb3e..3a2ac86 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -95,10 +95,10 @@ Sources/Models/WebhooksCreationPayload.swift Sources/Models/WebhooksListResponse.swift Sources/OpenISO8601DateFormatter.swift Sources/SynchronizedDictionary.swift -Sources/Upload/ChunkInputStream.swift -Sources/Upload/FileChunksBuilder.swift -Sources/Upload/FileReaders.swift -Sources/Upload/ProgressiveUploadSessioning.swift +Sources/Upload/FileChunkInputStream.swift +Sources/Upload/ProgressiveUploadSessionProtocol.swift +Sources/Upload/RequestTaskQueue.swift +Sources/Upload/UploadChunkRequestTaskQueue.swift docs/AccessToken.md docs/AuthenticatePayload.md docs/AuthenticationAPI.md diff --git a/Example/Example/Controller/UploaderViewController.swift b/Example/Example/Controller/UploaderViewController.swift index f28e74f..99864af 100644 --- a/Example/Example/Controller/UploaderViewController.swift +++ b/Example/Example/Controller/UploaderViewController.swift @@ -194,18 +194,22 @@ class UploaderViewController: UIViewController, UIImagePickerControllerDelegate, func upload(url: URL) { VideosAPI.create(videoCreationPayload: VideoCreationPayload(title: "my video")) { video, error in if let video = video { - VideosAPI.upload( - videoId: video.videoId, - file: url, - onProgressReady: { progress in - print("Progress: \(progress)") - }) { video, error in + do { + try VideosAPI.upload( + videoId: video.videoId, + file: url, + onProgressReady: { progress in + print("Progress: \(progress)") + }) { video, error in if video != nil { - self.thumbnailImageView.image = nil - } - if let error = error { - print("Upload error: \(error)") + self.thumbnailImageView.image = nil + } + if let error = error { + print("Upload error: \(error)") + } } + } catch { + print("Upload error: \(error)") } } if let error = error { diff --git a/README.md b/README.md index 99789ab..dc3d510 100644 --- a/README.md +++ b/README.md @@ -67,14 +67,18 @@ import ApiVideoClient VideosAPI.create(videoCreationPayload: VideoCreationPayload(title: "my video")) { video, error in if let video = video { - VideosAPI.upload(videoId: video.videoId, - file: url) { video, error in - if let video = video { - // Manage upload success here - } - if let error = error { - // Manage upload error here + do { + try VideosAPI.upload(videoId: video.videoId, + file: url) { video, error in + if let video = video { + // Manage upload success here + } + if let error = error { + // Manage upload error here + } } + } catch { + // Manage error on file here } } if let error = error { diff --git a/Sources/APIs.swift b/Sources/APIs.swift index a80d68f..ab61cae 100644 --- a/Sources/APIs.swift +++ b/Sources/APIs.swift @@ -5,11 +5,6 @@ // import Foundation -enum ApiVideoClientError: Error { - case invalidName - case invalidVersion -} - public class ApiVideoClient { public static var apiKey: String? = nil public static var basePath = "https://ws.api.video" @@ -18,6 +13,7 @@ public class ApiVideoClient { internal static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() internal static var credential = ApiVideoCredential() public static var apiResponseQueue: DispatchQueue = .main + public static var timeout: TimeInterval = 60 public static func setChunkSize(chunkSize: Int) throws { if (chunkSize > 128 * 1024 * 1024) { @@ -56,11 +52,11 @@ public class ApiVideoClient { static func setName(key: String, name: String, version: String) throws { if(!isValidName(name: name)) { - throw ApiVideoClientError.invalidName + throw ParameterError.invalidName } if(!isValidVersion(version: version)) { - throw ApiVideoClientError.invalidVersion + throw ParameterError.invalidVersion } ApiVideoClient.customHeaders[key] = name + ":" + version } @@ -77,12 +73,13 @@ public class ApiVideoClient { open class RequestBuilder { var headers: [String: String] - public let parameters: [String: Any]? + public var parameters: [String: Any]? public let method: String public let URLString: String + public let requestTask: RequestTask = RequestTask() /// Optional block to obtain a reference to the request's progress instance when available. - public let onProgressReady: ((Progress) -> Void)? + public var onProgressReady: ((Progress) -> Void)? required public init(method: String, URLString: String, parameters: [String: Any]?, headers: [String: String] = [:], onProgressReady: ((Progress) -> Void)? = nil) { self.method = method @@ -101,8 +98,8 @@ open class RequestBuilder { } @discardableResult - open func execute(_ apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, _ completion: @escaping (_ result: Swift.Result, ErrorResponse>) -> Void) -> URLSessionTask? { - return nil + open func execute(_ apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, _ completion: @escaping (_ result: Swift.Result, ErrorResponse>) -> Void) -> RequestTask { + return requestTask } public func addHeader(name: String, value: String) -> Self { diff --git a/Sources/APIs/AuthenticationAPI.swift b/Sources/APIs/AuthenticationAPI.swift index e09d88c..b84d3d4 100644 --- a/Sources/APIs/AuthenticationAPI.swift +++ b/Sources/APIs/AuthenticationAPI.swift @@ -20,7 +20,7 @@ open class AuthenticationAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func authenticate(authenticatePayload: AuthenticatePayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: AccessToken?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func authenticate(authenticatePayload: AuthenticatePayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: AccessToken?, _ error: Error?) -> Void)) -> RequestTask { return authenticateWithRequestBuilder(authenticatePayload: authenticatePayload).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -66,7 +66,7 @@ open class AuthenticationAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func refresh(refreshTokenPayload: RefreshTokenPayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: AccessToken?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func refresh(refreshTokenPayload: RefreshTokenPayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: AccessToken?, _ error: Error?) -> Void)) -> RequestTask { return refreshWithRequestBuilder(refreshTokenPayload: refreshTokenPayload).execute(apiResponseQueue) { result in switch result { case let .success(response): diff --git a/Sources/APIs/CaptionsAPI.swift b/Sources/APIs/CaptionsAPI.swift index 1d290a6..901c709 100644 --- a/Sources/APIs/CaptionsAPI.swift +++ b/Sources/APIs/CaptionsAPI.swift @@ -22,7 +22,7 @@ open class CaptionsAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func upload(videoId: String, language: String, file: URL, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Caption?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func upload(videoId: String, language: String, file: URL, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Caption?, _ error: Error?) -> Void)) -> RequestTask { return uploadWithRequestBuilder(videoId: videoId, language: language, file: file).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -81,7 +81,7 @@ open class CaptionsAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func get(videoId: String, language: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Caption?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func get(videoId: String, language: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Caption?, _ error: Error?) -> Void)) -> RequestTask { return getWithRequestBuilder(videoId: videoId, language: language).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -138,7 +138,7 @@ Tutorials that use the [captions endpoint](https://api.video/blog/endpoints/capt - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func update(videoId: String, language: String, captionsUpdatePayload: CaptionsUpdatePayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Caption?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func update(videoId: String, language: String, captionsUpdatePayload: CaptionsUpdatePayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Caption?, _ error: Error?) -> Void)) -> RequestTask { return updateWithRequestBuilder(videoId: videoId, language: language, captionsUpdatePayload: captionsUpdatePayload).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -193,7 +193,7 @@ Tutorials that use the [captions endpoint](https://api.video/blog/endpoints/capt - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func delete(videoId: String, language: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func delete(videoId: String, language: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> RequestTask { return deleteWithRequestBuilder(videoId: videoId, language: language).execute(apiResponseQueue) { result in switch result { case .success: @@ -248,7 +248,7 @@ Tutorials that use the [captions endpoint](https://api.video/blog/endpoints/capt - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func list(videoId: String, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: CaptionsListResponse?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func list(videoId: String, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: CaptionsListResponse?, _ error: Error?) -> Void)) -> RequestTask { return listWithRequestBuilder(videoId: videoId, currentPage: currentPage, pageSize: pageSize).execute(apiResponseQueue) { result in switch result { case let .success(response): diff --git a/Sources/APIs/ChaptersAPI.swift b/Sources/APIs/ChaptersAPI.swift index 42c1476..a631da4 100644 --- a/Sources/APIs/ChaptersAPI.swift +++ b/Sources/APIs/ChaptersAPI.swift @@ -22,7 +22,7 @@ open class ChaptersAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func upload(videoId: String, language: String, file: URL, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Chapter?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func upload(videoId: String, language: String, file: URL, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Chapter?, _ error: Error?) -> Void)) -> RequestTask { return uploadWithRequestBuilder(videoId: videoId, language: language, file: file).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -81,7 +81,7 @@ open class ChaptersAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func get(videoId: String, language: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Chapter?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func get(videoId: String, language: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Chapter?, _ error: Error?) -> Void)) -> RequestTask { return getWithRequestBuilder(videoId: videoId, language: language).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -135,7 +135,7 @@ open class ChaptersAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func delete(videoId: String, language: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func delete(videoId: String, language: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> RequestTask { return deleteWithRequestBuilder(videoId: videoId, language: language).execute(apiResponseQueue) { result in switch result { case .success: @@ -190,7 +190,7 @@ open class ChaptersAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func list(videoId: String, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: ChaptersListResponse?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func list(videoId: String, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: ChaptersListResponse?, _ error: Error?) -> Void)) -> RequestTask { return listWithRequestBuilder(videoId: videoId, currentPage: currentPage, pageSize: pageSize).execute(apiResponseQueue) { result in switch result { case let .success(response): diff --git a/Sources/APIs/LiveStreamsAPI.swift b/Sources/APIs/LiveStreamsAPI.swift index 7183d2d..fb066fd 100644 --- a/Sources/APIs/LiveStreamsAPI.swift +++ b/Sources/APIs/LiveStreamsAPI.swift @@ -20,7 +20,7 @@ open class LiveStreamsAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func create(liveStreamCreationPayload: LiveStreamCreationPayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: LiveStream?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func create(liveStreamCreationPayload: LiveStreamCreationPayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: LiveStream?, _ error: Error?) -> Void)) -> RequestTask { return createWithRequestBuilder(liveStreamCreationPayload: liveStreamCreationPayload).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -66,7 +66,7 @@ open class LiveStreamsAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func get(liveStreamId: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: LiveStream?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func get(liveStreamId: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: LiveStream?, _ error: Error?) -> Void)) -> RequestTask { return getWithRequestBuilder(liveStreamId: liveStreamId).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -116,7 +116,7 @@ open class LiveStreamsAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func update(liveStreamId: String, liveStreamUpdatePayload: LiveStreamUpdatePayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: LiveStream?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func update(liveStreamId: String, liveStreamUpdatePayload: LiveStreamUpdatePayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: LiveStream?, _ error: Error?) -> Void)) -> RequestTask { return updateWithRequestBuilder(liveStreamId: liveStreamId, liveStreamUpdatePayload: liveStreamUpdatePayload).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -166,7 +166,7 @@ open class LiveStreamsAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func delete(liveStreamId: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func delete(liveStreamId: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> RequestTask { return deleteWithRequestBuilder(liveStreamId: liveStreamId).execute(apiResponseQueue) { result in switch result { case .success: @@ -228,7 +228,7 @@ open class LiveStreamsAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func list(streamKey: String? = nil, name: String? = nil, sortBy: String? = nil, sortOrder: SortOrder_list? = nil, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: LiveStreamListResponse?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func list(streamKey: String? = nil, name: String? = nil, sortBy: String? = nil, sortOrder: SortOrder_list? = nil, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: LiveStreamListResponse?, _ error: Error?) -> Void)) -> RequestTask { return listWithRequestBuilder(streamKey: streamKey, name: name, sortBy: sortBy, sortOrder: sortOrder, currentPage: currentPage, pageSize: pageSize).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -288,7 +288,7 @@ open class LiveStreamsAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func uploadThumbnail(liveStreamId: String, file: URL, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: LiveStream?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func uploadThumbnail(liveStreamId: String, file: URL, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: LiveStream?, _ error: Error?) -> Void)) -> RequestTask { return uploadThumbnailWithRequestBuilder(liveStreamId: liveStreamId, file: file).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -342,7 +342,7 @@ open class LiveStreamsAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func deleteThumbnail(liveStreamId: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: LiveStream?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func deleteThumbnail(liveStreamId: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: LiveStream?, _ error: Error?) -> Void)) -> RequestTask { return deleteThumbnailWithRequestBuilder(liveStreamId: liveStreamId).execute(apiResponseQueue) { result in switch result { case let .success(response): diff --git a/Sources/APIs/PlayerThemesAPI.swift b/Sources/APIs/PlayerThemesAPI.swift index e3ad841..a2d0255 100644 --- a/Sources/APIs/PlayerThemesAPI.swift +++ b/Sources/APIs/PlayerThemesAPI.swift @@ -20,7 +20,7 @@ open class PlayerThemesAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func create(playerThemeCreationPayload: PlayerThemeCreationPayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: PlayerTheme?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func create(playerThemeCreationPayload: PlayerThemeCreationPayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: PlayerTheme?, _ error: Error?) -> Void)) -> RequestTask { return createWithRequestBuilder(playerThemeCreationPayload: playerThemeCreationPayload).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -66,7 +66,7 @@ open class PlayerThemesAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func get(playerId: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: PlayerTheme?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func get(playerId: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: PlayerTheme?, _ error: Error?) -> Void)) -> RequestTask { return getWithRequestBuilder(playerId: playerId).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -116,7 +116,7 @@ open class PlayerThemesAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func update(playerId: String, playerThemeUpdatePayload: PlayerThemeUpdatePayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: PlayerTheme?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func update(playerId: String, playerThemeUpdatePayload: PlayerThemeUpdatePayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: PlayerTheme?, _ error: Error?) -> Void)) -> RequestTask { return updateWithRequestBuilder(playerId: playerId, playerThemeUpdatePayload: playerThemeUpdatePayload).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -166,7 +166,7 @@ open class PlayerThemesAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func delete(playerId: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func delete(playerId: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> RequestTask { return deleteWithRequestBuilder(playerId: playerId).execute(apiResponseQueue) { result in switch result { case .success: @@ -235,7 +235,7 @@ open class PlayerThemesAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func list(sortBy: SortBy_list? = nil, sortOrder: SortOrder_list? = nil, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: PlayerThemesListResponse?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func list(sortBy: SortBy_list? = nil, sortOrder: SortOrder_list? = nil, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: PlayerThemesListResponse?, _ error: Error?) -> Void)) -> RequestTask { return listWithRequestBuilder(sortBy: sortBy, sortOrder: sortOrder, currentPage: currentPage, pageSize: pageSize).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -292,7 +292,7 @@ open class PlayerThemesAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func uploadLogo(playerId: String, file: URL, link: String? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: PlayerTheme?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func uploadLogo(playerId: String, file: URL, link: String? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: PlayerTheme?, _ error: Error?) -> Void)) -> RequestTask { return uploadLogoWithRequestBuilder(playerId: playerId, file: file, link: link).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -348,7 +348,7 @@ open class PlayerThemesAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func deleteLogo(playerId: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func deleteLogo(playerId: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> RequestTask { return deleteLogoWithRequestBuilder(playerId: playerId).execute(apiResponseQueue) { result in switch result { case .success: diff --git a/Sources/APIs/RawStatisticsAPI.swift b/Sources/APIs/RawStatisticsAPI.swift index edb27bd..d0638ad 100644 --- a/Sources/APIs/RawStatisticsAPI.swift +++ b/Sources/APIs/RawStatisticsAPI.swift @@ -23,7 +23,7 @@ open class RawStatisticsAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func listLiveStreamSessions(liveStreamId: String, period: String, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: RawStatisticsListLiveStreamAnalyticsResponse?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func listLiveStreamSessions(liveStreamId: String, period: String, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: RawStatisticsListLiveStreamAnalyticsResponse?, _ error: Error?) -> Void)) -> RequestTask { return listLiveStreamSessionsWithRequestBuilder(liveStreamId: liveStreamId, period: period, currentPage: currentPage, pageSize: pageSize).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -81,7 +81,7 @@ open class RawStatisticsAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func listSessionEvents(sessionId: String, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: RawStatisticsListPlayerSessionEventsResponse?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func listSessionEvents(sessionId: String, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: RawStatisticsListPlayerSessionEventsResponse?, _ error: Error?) -> Void)) -> RequestTask { return listSessionEventsWithRequestBuilder(sessionId: sessionId, currentPage: currentPage, pageSize: pageSize).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -140,7 +140,7 @@ open class RawStatisticsAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func listVideoSessions(videoId: String, period: String, metadata: [String: String]? = nil, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: RawStatisticsListSessionsResponse?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func listVideoSessions(videoId: String, period: String, metadata: [String: String]? = nil, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: RawStatisticsListSessionsResponse?, _ error: Error?) -> Void)) -> RequestTask { return listVideoSessionsWithRequestBuilder(videoId: videoId, period: period, metadata: metadata, currentPage: currentPage, pageSize: pageSize).execute(apiResponseQueue) { result in switch result { case let .success(response): diff --git a/Sources/APIs/UploadTokensAPI.swift b/Sources/APIs/UploadTokensAPI.swift index f67ba7c..16b4723 100644 --- a/Sources/APIs/UploadTokensAPI.swift +++ b/Sources/APIs/UploadTokensAPI.swift @@ -20,7 +20,7 @@ open class UploadTokensAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func createToken(tokenCreationPayload: TokenCreationPayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: UploadToken?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func createToken(tokenCreationPayload: TokenCreationPayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: UploadToken?, _ error: Error?) -> Void)) -> RequestTask { return createTokenWithRequestBuilder(tokenCreationPayload: tokenCreationPayload).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -66,7 +66,7 @@ open class UploadTokensAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func getToken(uploadToken: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: UploadToken?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func getToken(uploadToken: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: UploadToken?, _ error: Error?) -> Void)) -> RequestTask { return getTokenWithRequestBuilder(uploadToken: uploadToken).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -115,7 +115,7 @@ open class UploadTokensAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func deleteToken(uploadToken: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func deleteToken(uploadToken: String, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> RequestTask { return deleteTokenWithRequestBuilder(uploadToken: uploadToken).execute(apiResponseQueue) { result in switch result { case .success: @@ -183,7 +183,7 @@ open class UploadTokensAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func list(sortBy: SortBy_list? = nil, sortOrder: SortOrder_list? = nil, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: TokenListResponse?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func list(sortBy: SortBy_list? = nil, sortOrder: SortOrder_list? = nil, currentPage: Int? = nil, pageSize: Int? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: TokenListResponse?, _ error: Error?) -> Void)) -> RequestTask { return listWithRequestBuilder(sortBy: sortBy, sortOrder: sortOrder, currentPage: currentPage, pageSize: pageSize).execute(apiResponseQueue) { result in switch result { case let .success(response): diff --git a/Sources/APIs/VideosAPI.swift b/Sources/APIs/VideosAPI.swift index ac9c61a..383aab8 100644 --- a/Sources/APIs/VideosAPI.swift +++ b/Sources/APIs/VideosAPI.swift @@ -20,7 +20,7 @@ open class VideosAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func create(videoCreationPayload: VideoCreationPayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Video?, _ error: Error?) -> Void)) -> URLSessionTask? { + open class func create(videoCreationPayload: VideoCreationPayload, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Video?, _ error: Error?) -> Void)) -> RequestTask { return createWithRequestBuilder(videoCreationPayload: videoCreationPayload).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -68,15 +68,10 @@ open class VideosAPI { - parameter completion: completion handler to receive the data and the error objects. */ @discardableResult - open class func upload(videoId: String, file: URL, onProgressReady: ((Progress) -> Void)? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Video?, _ error: Error?) -> Void)) -> URLSessionTask? { - let fileReader: FileChunksReader - do { - fileReader = try FileChunksReader(fileURL: file.encodeToJSON() as! URL) - } catch { - completion(nil, error) - return nil - } - if (fileReader.getTotalNumberOfChunks() == 1) { + open class func upload(videoId: String, file: URL, onProgressReady: ((Progress) -> Void)? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Video?, _ error: Error?) -> Void)) throws -> RequestTask { + if (try file.isMultiChunk) { + return try UploadChunkRequestTaskQueue(videoId: videoId, file: file, onProgressReady: onProgressReady, apiResponseQueue: apiResponseQueue, completion: completion) + } else { return uploadWithRequestBuilder(videoId: videoId, file: file, onProgressReady: onProgressReady).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -85,33 +80,6 @@ open class VideosAPI { completion(nil, error) } } - } else { - return upload(videoId: videoId, file: fileReader, onProgressReady: onProgressReady, apiResponseQueue: apiResponseQueue, completion: completion) - } - } - - /** - Upload a video - - - parameter videoId: (path) Enter the videoId you want to use to upload your video. - - parameter file: (form) The reader that constains file chunks - - parameter onProgressReady: progress handler to receive request progress. - - parameter apiResponseQueue: The queue on which api response is dispatched. - - parameter completion: completion handler to receive the data and the error objects. - */ - @discardableResult - private class func upload(videoId: String, file: ChunksReader, onProgressReady: ((Progress) -> Void)? = nil, apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, completion: @escaping ((_ data: Video?, _ error: Error?) -> Void)) -> URLSessionTask? { - return uploadWithRequestBuilder(videoId: videoId, file: file, onProgressReady: onProgressReady).execute(apiResponseQueue) { result in - switch result { - case let .success(response): - if (file.remainingNumberOfChunks == 0) { - completion(response.body, nil) - } else { - upload(videoId: videoId, file: file, onProgressReady: onProgressReady, apiResponseQueue: apiResponseQueue, completion: completion) - } - case let .failure(error): - completion(nil, error) - } } } @@ -120,36 +88,48 @@ open class VideosAPI { * * - returns: a progressive upload session */ - open class func buildProgressiveUploadSession(videoId: String) -> ProgressiveUploadSession { - return ProgressiveUploadSession(videoId: videoId) + public class func buildProgressiveUploadSession(videoId: String) -> ProgressiveUploadSession { + ProgressiveUploadSession(videoId: videoId) } - open class ProgressiveUploadSession: ProgressiveUploadSessioning { + public class ProgressiveUploadSession: RequestTaskQueue