From f722c8a17967b775ba89bb8865066c496925caeb Mon Sep 17 00:00:00 2001 From: ThibaultBee Date: Mon, 27 Nov 2023 11:39:41 +0000 Subject: [PATCH] swift5: upload in background --- .openapi-generator/FILES | 4 +- ApiVideoClient.podspec | 7 +- Cartfile | 1 - .../Controller/VideosViewController.swift | 85 ++ Example/Example/MainViewController.swift | 2 +- Package.swift | 9 +- Sources/APIs.swift | 44 +- Sources/APIs/VideosAPI.swift | 8 +- Sources/AlamofireImplementations.swift | 418 ---------- Sources/Auth/ApiVideoAuthenticator.swift | 52 -- Sources/Auth/ApiVideoCredential.swift | 31 - Sources/Extensions.swift | 6 + Sources/Models.swift | 28 +- Sources/URLSessionImplementations.swift | 763 ++++++++++++++++++ Sources/Upload/FileChunkInputStream.swift | 3 - .../ProgressiveUploadSessionProtocol.swift | 3 - Sources/Upload/RequestTaskQueue.swift | 34 +- .../Upload/UploadChunkRequestTaskQueue.swift | 19 +- .../Integration/VideosApiTests.swift | 10 +- project.yml | 1 - 20 files changed, 938 insertions(+), 590 deletions(-) create mode 100644 Example/Example/Controller/VideosViewController.swift delete mode 100644 Sources/AlamofireImplementations.swift delete mode 100644 Sources/Auth/ApiVideoAuthenticator.swift delete mode 100644 Sources/Auth/ApiVideoCredential.swift create mode 100644 Sources/URLSessionImplementations.swift diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index 39d2d96..29c65c0 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -15,9 +15,6 @@ Sources/APIs/UploadTokensAPI.swift Sources/APIs/VideosAPI.swift Sources/APIs/WatermarksAPI.swift Sources/APIs/WebhooksAPI.swift -Sources/AlamofireImplementations.swift -Sources/Auth/ApiVideoAuthenticator.swift -Sources/Auth/ApiVideoCredential.swift Sources/CodableHelper.swift Sources/Configuration.swift Sources/Extensions.swift @@ -99,6 +96,7 @@ Sources/Models/WebhooksCreationPayload.swift Sources/Models/WebhooksListResponse.swift Sources/OpenISO8601DateFormatter.swift Sources/SynchronizedDictionary.swift +Sources/URLSessionImplementations.swift Sources/Upload/FileChunkInputStream.swift Sources/Upload/ProgressiveUploadSessionProtocol.swift Sources/Upload/RequestTaskQueue.swift diff --git a/ApiVideoClient.podspec b/ApiVideoClient.podspec index 244a0d6..07848e3 100644 --- a/ApiVideoClient.podspec +++ b/ApiVideoClient.podspec @@ -1,8 +1,8 @@ Pod::Spec.new do |s| s.name = 'ApiVideoClient' - s.ios.deployment_target = '10.0' - s.osx.deployment_target = '10.12' - s.tvos.deployment_target = '10.0' + s.ios.deployment_target = '9.0' + s.osx.deployment_target = '10.11' + s.tvos.deployment_target = '9.0' # Add back when CocoaPods/CocoaPods#11558 is released #s.watchos.deployment_target = '3.0' s.version = '1.2.1' @@ -13,5 +13,4 @@ Pod::Spec.new do |s| s.summary = 'The official Swift api.video client for iOS, macOS and tvOS' s.source_files = 'Sources/**/*.swift' s.dependency 'AnyCodable-FlightSchool', '~> 0.6.1' - s.dependency 'Alamofire', '~> 5.4.3' end diff --git a/Cartfile b/Cartfile index 4fdc3a6..3f7e630 100644 --- a/Cartfile +++ b/Cartfile @@ -1,2 +1 @@ github "Flight-School/AnyCodable" ~> 0.6.1 -github "Alamofire/Alamofire" ~> 5.4.3 diff --git a/Example/Example/Controller/VideosViewController.swift b/Example/Example/Controller/VideosViewController.swift new file mode 100644 index 0000000..256e4ab --- /dev/null +++ b/Example/Example/Controller/VideosViewController.swift @@ -0,0 +1,85 @@ +// +// ViewController.swift +// Example +// + +import UIKit +import ApiVideoClient + +struct VideosOption{ + let title:String + let videoId: String + let thumbnail: String? + let handler: (()->Void) +} + +class VideosViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { + var models = [VideosOption]() + + private func configure(){ + + ApiVideoClient.setApiKey(ClientManager.apiKey) + ApiVideoClient.basePath = ClientManager.environment.rawValue + + VideosAPI.list(title: nil, tags: nil, metadata: nil, description: nil, liveStreamId: nil, sortBy: nil, sortOrder: nil, currentPage: nil, pageSize: nil) { (response, error) in + guard error == nil else { + print(error ?? "error") + return + } + + if ((response) != nil) { + for item in response!.data { + self.models.append(VideosOption(title: item.title ?? "error title", videoId: item.videoId, thumbnail: item.assets?.thumbnail){ + + }) + self.tableView.reloadData() + } + } + } + } + + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + let headerView = UIView() + headerView.backgroundColor = UIColor.clear + return headerView + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return models.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let model = models[indexPath.row] + + + guard let cell = tableView.dequeueReusableCell(withIdentifier: VideoTableViewCell.identifier, for: indexPath) as? VideoTableViewCell else{ + return UITableViewCell() + } + cell.layer.cornerRadius = 8 + cell.configure(with: model) + return cell + } + + + private let tableView: UITableView = { + let table = UITableView(frame: .zero, style: .grouped) + table.register(VideoTableViewCell.self, forCellReuseIdentifier: VideoTableViewCell.identifier) + return table + }() + + override func viewDidLoad() { + super.viewDidLoad() + configure() + title = "Videos" + view.addSubview(tableView) + tableView.delegate = self + tableView.dataSource = self + tableView.frame = view.bounds + tableView.rowHeight = 310.0 + } + + + + +} + diff --git a/Example/Example/MainViewController.swift b/Example/Example/MainViewController.swift index e1d3bd6..1fe2f9b 100644 --- a/Example/Example/MainViewController.swift +++ b/Example/Example/MainViewController.swift @@ -157,7 +157,7 @@ extension MainViewController: UIImagePickerControllerDelegate, UINavigationContr progressView.isHidden = false // Set client configuration - ApiVideoClient.apiKey = SettingsManager.apiKey + ApiVideoClient.setApiKey(SettingsManager.apiKey) ApiVideoClient.basePath = SettingsManager.environment.rawValue // Upload diff --git a/Package.swift b/Package.swift index 267f9ea..b7f7d3f 100644 --- a/Package.swift +++ b/Package.swift @@ -5,9 +5,9 @@ import PackageDescription let package = Package( name: "ApiVideoClient", platforms: [ - .iOS(.v10), - .macOS(.v10_12), - .tvOS(.v10), + .iOS(.v9), + .macOS(.v10_11), + .tvOS(.v9), .watchOS(.v3), ], products: [ @@ -20,14 +20,13 @@ let package = Package( dependencies: [ // Dependencies declare other packages that this package depends on. .package(url: "https://github.com/Flight-School/AnyCodable", from: "0.6.1"), - .package(url: "https://github.com/Alamofire/Alamofire", from: "5.4.3"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages which this package depends on. .target( name: "ApiVideoClient", - dependencies: ["AnyCodable", "Alamofire", ], + dependencies: ["AnyCodable", ], path: "Sources" ), // Targets for tests diff --git a/Sources/APIs.swift b/Sources/APIs.swift index 5f8883e..c2dbff2 100644 --- a/Sources/APIs.swift +++ b/Sources/APIs.swift @@ -6,16 +6,31 @@ import Foundation public class ApiVideoClient { - public static var apiKey: String? = nil + private static var apiKey: String? = nil public static var basePath = "https://ws.api.video" - internal static var customHeaders:[String: String] = ["AV-Origin-Client": "swift:1.2.1"] + internal static var defaultHeaders:[String: String] = ["AV-Origin-Client": "swift:1.2.1"] + internal static var credential: URLCredential? private static var chunkSize: Int = 50 * 1024 * 1024 - internal static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() - internal static var credential = ApiVideoCredential() + internal static var requestBuilderFactory: RequestBuilderFactory = URLSessionRequestBuilderFactory() public static var apiResponseQueue: DispatchQueue = .main public static var timeout: TimeInterval = 60 + internal static var customHeaders:[String: String] { + var headers = defaultHeaders + if let apiKey = apiKey { + headers["Authorization"] = apiKey + } + return headers + } + + public static func setApiKey(_ apiKey: String?) { + if let apiKey = apiKey { + self.apiKey = "Basic " + "\(apiKey):".toBase64() + } else { + self.apiKey = nil + } + } - public static func setChunkSize(chunkSize: Int) throws { + public static func setChunkSize(_ chunkSize: Int) throws { if (chunkSize > 128 * 1024 * 1024) { throw ParameterError.outOfRange } else if (chunkSize < 5 * 1024 * 1024) { @@ -40,25 +55,25 @@ public class ApiVideoClient { } } - static func isValidVersion(version: String) -> Bool { + static func isValidVersion(_ version: String) -> Bool { let pattern = #"^\d{1,3}(\.\d{1,3}(\.\d{1,3})?)?$"# return isValid(pattern: pattern, field: version) } - static func isValidName(name: String) -> Bool { + static func isValidName(_ name: String) -> Bool { let pattern = #"^[\w\-]{1,50}$"# return isValid(pattern: pattern, field: name) } static func setName(key: String, name: String, version: String) throws { - if(!isValidName(name: name)) { + if(!isValidName(name)) { throw ParameterError.invalidName } - if(!isValidVersion(version: version)) { + if(!isValidVersion(version)) { throw ParameterError.invalidVersion } - ApiVideoClient.customHeaders[key] = name + ":" + version + ApiVideoClient.defaultHeaders[key] = name + ":" + version } public static func setSdkName(name: String, version: String) throws { @@ -68,10 +83,10 @@ public class ApiVideoClient { public static func setApplicationName(name: String, version: String) throws { try setName(key: "AV-Origin-App", name: name, version: version) } - } open class RequestBuilder { + var credential: URLCredential? var headers: [String: String] public var parameters: [String: Any]? public let method: String @@ -79,6 +94,8 @@ open class RequestBuilder { public let requestTask: RequestTask = RequestTask() /// Optional block to obtain a reference to the request's progress instance when available. + /// With the URLSession http client the request's progress only works on iOS 11.0, macOS 10.13, macCatalyst 13.0, tvOS 11.0, watchOS 4.0. + /// If you need to get the request's progress in older OS versions, please use Alamofire http client. public var onProgressReady: ((Progress) -> Void)? required public init(method: String, URLString: String, parameters: [String: Any]?, headers: [String: String] = [:], onProgressReady: ((Progress) -> Void)? = nil) { @@ -108,6 +125,11 @@ open class RequestBuilder { } return self } + + open func addCredential() -> Self { + credential = ApiVideoClient.credential + return self + } } public protocol RequestBuilderFactory { diff --git a/Sources/APIs/VideosAPI.swift b/Sources/APIs/VideosAPI.swift index 5bcd506..14f8190 100644 --- a/Sources/APIs/VideosAPI.swift +++ b/Sources/APIs/VideosAPI.swift @@ -190,7 +190,7 @@ The latter allows you to split a video source into X chunks and send those chunk let localVariableHeaderParameters = APIHelper.rejectNilHeaders(localVariableNillableHeaders) - let localVariableRequestBuilder: RequestBuilder