Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/ios task cancellation #36

Merged
merged 1 commit into from Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions .openapi-generator/FILES
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions ApiVideoClient.podspec
Expand Up @@ -4,8 +4,8 @@ Pod::Spec.new do |s|
s.osx.deployment_target = '10.12'
s.tvos.deployment_target = '10.0'
s.watchos.deployment_target = '3.0'
s.version = '1.0.6'
s.source = { :git => 'https://github.com/apivideo/api.video-ios-client', :tag => 'v1.0.6' }
s.version = '1.1.0'
s.source = { :git => 'https://github.com/apivideo/api.video-ios-client', :tag => 'v1.1.0' }
s.authors = { 'Ecosystem Team' => 'ecosystem@api.video' }
s.license = { :type => 'MIT' }
s.homepage = 'https://docs.api.video'
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,6 +1,10 @@
# Changelog
All changes to this project will be documented in this file.

## [1.1.0] - 2022-12-06
- Refactor upload by chunk and progressive upload. It is now possible to cancel an upload.
- Add timeout API

## [1.0.6] - 2022-09-13
- period parameter is now mandatory in analytics endpoints

Expand Down
24 changes: 14 additions & 10 deletions Example/Example/Controller/UploaderViewController.swift
Expand Up @@ -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 {
Expand Down
22 changes: 13 additions & 9 deletions README.md
Expand Up @@ -42,14 +42,14 @@ api.video's iOS streamlines the coding process. Chunking files is handled for y
Specify it in your `Cartfile`:

```
github "apivideo/api.video-ios-client" ~> 1.0.6
github "apivideo/api.video-ios-client" ~> 1.1.0
```

Run `carthage update`

### CocoaPods

Add `pod 'ApiVideoClient', '1.0.6'` in your `Podfile`
Add `pod 'ApiVideoClient', '1.1.0'` in your `Podfile`

Run `pod install`

Expand All @@ -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 {
Expand Down
21 changes: 9 additions & 12 deletions Sources/APIs.swift
Expand Up @@ -5,19 +5,15 @@
//

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"
internal static var customHeaders:[String: String] = ["AV-Origin-Client": "ios:1.0.6"]
internal static var customHeaders:[String: String] = ["AV-Origin-Client": "ios:1.1.0"]
private static var chunkSize: Int = 50 * 1024 * 1024
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) {
Expand Down Expand Up @@ -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
}
Expand All @@ -77,12 +73,13 @@ public class ApiVideoClient {

open class RequestBuilder<T> {
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
Expand All @@ -101,8 +98,8 @@ open class RequestBuilder<T> {
}

@discardableResult
open func execute(_ apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, _ completion: @escaping (_ result: Swift.Result<Response<T>, ErrorResponse>) -> Void) -> URLSessionTask? {
return nil
open func execute(_ apiResponseQueue: DispatchQueue = ApiVideoClient.apiResponseQueue, _ completion: @escaping (_ result: Swift.Result<Response<T>, ErrorResponse>) -> Void) -> RequestTask {
return requestTask
}

public func addHeader(name: String, value: String) -> Self {
Expand Down
4 changes: 2 additions & 2 deletions Sources/APIs/AuthenticationAPI.swift
Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down
10 changes: 5 additions & 5 deletions Sources/APIs/CaptionsAPI.swift
Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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):
Expand Down
8 changes: 4 additions & 4 deletions Sources/APIs/ChaptersAPI.swift
Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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):
Expand Down