diff --git a/iOS/Layover/Layover/DesignSystem/LOTagStackView.swift b/iOS/Layover/Layover/DesignSystem/LOTagStackView.swift index 95f5b47..df6e2b8 100644 --- a/iOS/Layover/Layover/DesignSystem/LOTagStackView.swift +++ b/iOS/Layover/Layover/DesignSystem/LOTagStackView.swift @@ -17,6 +17,12 @@ final class LOTagStackView: UIStackView { // MARK: - Properties + var tags: [String] { + arrangedSubviews + .map { $0 as? UIButton } + .compactMap(\.?.titleLabel?.text) + } + private let style: Style // MARK: - Initializer diff --git a/iOS/Layover/Layover/Extensions/Notification.Name+.swift b/iOS/Layover/Layover/Extensions/Notification.Name+.swift index d48a1b0..bec37cf 100644 --- a/iOS/Layover/Layover/Extensions/Notification.Name+.swift +++ b/iOS/Layover/Layover/Extensions/Notification.Name+.swift @@ -10,4 +10,6 @@ import Foundation extension Notification.Name { static let refreshTokenDidExpired = Notification.Name("refreshTokenDidExpired") + static let uploadTaskStart = Notification.Name("uploadTaskStart") + static let progressChanged = Notification.Name("progressChanged") } diff --git a/iOS/Layover/Layover/Network/DTOs/UploadPostDTO.swift b/iOS/Layover/Layover/Network/DTOs/UploadPostDTO.swift index 74158e4..62016db 100644 --- a/iOS/Layover/Layover/Network/DTOs/UploadPostDTO.swift +++ b/iOS/Layover/Layover/Network/DTOs/UploadPostDTO.swift @@ -10,7 +10,7 @@ import Foundation struct UploadPostDTO: Decodable { let id: Int - let title + let title: String let content: String? let latitude, longitude: Double let tag: [String] diff --git a/iOS/Layover/Layover/Network/DTOs/UploadVideoDTO.swift b/iOS/Layover/Layover/Network/DTOs/UploadVideoDTO.swift index 9426621..0d8160a 100644 --- a/iOS/Layover/Layover/Network/DTOs/UploadVideoDTO.swift +++ b/iOS/Layover/Layover/Network/DTOs/UploadVideoDTO.swift @@ -9,10 +9,19 @@ import Foundation struct UploadVideoDTO: Decodable { - let presignedUrl: String + let preSignedURL: String + + enum CodingKeys: String, CodingKey { + case preSignedURL = "preSignedUrl" + } } struct UploadVideoRequestDTO: Encodable { let boardID: Int let filetype: String + + enum CodingKeys: String, CodingKey { + case boardID = "boardId" + case filetype + } } diff --git a/iOS/Layover/Layover/Network/Provider/Provider.swift b/iOS/Layover/Layover/Network/Provider/Provider.swift index c11f94d..eec9b1c 100644 --- a/iOS/Layover/Layover/Network/Provider/Provider.swift +++ b/iOS/Layover/Layover/Network/Provider/Provider.swift @@ -145,7 +145,8 @@ class Provider: ProviderType { guard let url = URL(string: url) else { throw NetworkError.components } var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData) request.httpMethod = method.rawValue - let backgroundSession = URLSession(configuration: .background(withIdentifier: UUID().uuidString), + request.setValue("video/\(fromFile.pathExtension)", forHTTPHeaderField: "Content-Type") + let backgroundSession = URLSession(configuration: .default, delegate: sessionTaskDelegate, delegateQueue: delegateQueue) let (data, response) = try await backgroundSession.upload(for: request, fromFile: fromFile) diff --git a/iOS/Layover/Layover/SceneDelegate.swift b/iOS/Layover/Layover/SceneDelegate.swift index 41a0756..fb149ad 100644 --- a/iOS/Layover/Layover/SceneDelegate.swift +++ b/iOS/Layover/Layover/SceneDelegate.swift @@ -11,6 +11,7 @@ import KakaoSDKUser class SceneDelegate: UIResponder, UIWindowSceneDelegate { + var progressView: UIProgressView = UIProgressView(progressViewStyle: .bar) var window: UIWindow? @@ -19,7 +20,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { let window = UIWindow(windowScene: windowScene) let rootViewController = AuthManager.shared.isLoggedIn ? MainTabBarViewController() : LoginViewController() - window.rootViewController = UINavigationController(rootViewController: rootViewController) + window.rootViewController = MainTabBarViewController() self.window = window addNotificationObservers() window.makeKeyAndVisible() @@ -70,12 +71,26 @@ extension SceneDelegate { selector: #selector(routeToLoginViewController), name: .refreshTokenDidExpired, object: nil) + NotificationCenter.default.addObserver(self, + selector: #selector(uploadTaskStart), + name: .uploadTaskStart, + object: nil) + NotificationCenter.default.addObserver(self, + selector: #selector(progressChanged), + name: .progressChanged, + object: nil) } private func removeNotificationObservers() { NotificationCenter.default.removeObserver(self, - name: .refreshTokenDidExpired, - object: nil) + name: .refreshTokenDidExpired, + object: nil) + NotificationCenter.default.removeObserver(self, + name: .refreshTokenDidExpired, + object: nil) + NotificationCenter.default.removeObserver(self, + name: .progressChanged, + object: nil) } @objc private func routeToLoginViewController() { @@ -84,5 +99,29 @@ extension SceneDelegate { rootNavigationViewController.setNavigationBarHidden(false, animated: false) rootNavigationViewController.setViewControllers([LoginViewController()], animated: true) } + + @objc private func uploadTaskStart() { + guard let progressViewWidth = window?.screen.bounds.width, + let windowHeight = window?.screen.bounds.height, + let tabBarViewController = window?.rootViewController as? UITabBarController else { return } + let tabBarHeight: CGFloat = tabBarViewController.tabBar.frame.height + progressView.progress = 0 + progressView.tintColor = .primaryPurple + progressView.frame = CGRect(x: 0, + y: (windowHeight - tabBarHeight - 2), + width: progressViewWidth, + height: 2) + window?.addSubview(progressView) + } + + + @objc private func progressChanged(_ notification: Notification) { + guard let progress = notification.userInfo?["progress"] as? Float else { return } + progressView.setProgress(progress, animated: true) + if progress == 1 { + progressView.removeFromSuperview() + Toast.shared.showToast(message: "업로드가 완료되었습니다 ✨") + } + } } diff --git a/iOS/Layover/Layover/Scenes/EditTag/EditTagRouter.swift b/iOS/Layover/Layover/Scenes/EditTag/EditTagRouter.swift index bb65454..d499382 100644 --- a/iOS/Layover/Layover/Scenes/EditTag/EditTagRouter.swift +++ b/iOS/Layover/Layover/Scenes/EditTag/EditTagRouter.swift @@ -16,7 +16,7 @@ protocol EditTagDataPassing { var dataStore: EditTagDataStore? { get } } -class EditTagRouter: NSObject, EditTagRoutingLogic, EditTagDataPassing { +final class EditTagRouter: NSObject, EditTagRoutingLogic, EditTagDataPassing { // MARK: - Properties @@ -27,10 +27,12 @@ class EditTagRouter: NSObject, EditTagRoutingLogic, EditTagDataPassing { // MARK: - Routing func routeToBack() { - guard let navigationController = viewController?.presentingViewController as? UINavigationController, - let destination = navigationController.viewControllers.last as? UploadPostViewController, - var destinationDataStore = destination.router?.dataStore else { return } - destinationDataStore.tags = dataStore?.tags + guard let presentingViewController = viewController?.presentingViewController as? UITabBarController, + let selectedViewController = presentingViewController.selectedViewController as? UINavigationController, + let previousViewController = selectedViewController.viewControllers.last as? UploadPostViewController, + var destination = previousViewController.router?.dataStore + else { return } + destination.tags = dataStore?.tags viewController?.dismiss(animated: true) } diff --git a/iOS/Layover/Layover/Scenes/EditTag/EditTagViewController.swift b/iOS/Layover/Layover/Scenes/EditTag/EditTagViewController.swift index 9d93cf3..dd82629 100644 --- a/iOS/Layover/Layover/Scenes/EditTag/EditTagViewController.swift +++ b/iOS/Layover/Layover/Scenes/EditTag/EditTagViewController.swift @@ -91,9 +91,8 @@ final class EditTagViewController: BaseViewController { // MARK: - Methods @objc private func closeButtonDidTap() { - let buttons = tagStackView.arrangedSubviews.map { $0 as? UIButton } - let tags = buttons.compactMap(\.?.titleLabel?.text) - interactor?.editTag(request: EditTagModels.EditTag.Request(tags: tags)) + let request = EditTagModels.EditTag.Request(tags: tagStackView.tags) + interactor?.editTag(request: request) router?.routeToBack() } @@ -110,7 +109,6 @@ extension EditTagViewController: UITextFieldDelegate { } } - extension EditTagViewController: EditTagDisplayLogic { func displayTags(viewModel: EditTagModels.FetchTags.ViewModel) { diff --git a/iOS/Layover/Layover/Scenes/EditVideo/EditVideoViewController.swift b/iOS/Layover/Layover/Scenes/EditVideo/EditVideoViewController.swift index 0f9754c..e62532c 100644 --- a/iOS/Layover/Layover/Scenes/EditVideo/EditVideoViewController.swift +++ b/iOS/Layover/Layover/Scenes/EditVideo/EditVideoViewController.swift @@ -34,7 +34,7 @@ final class EditVideoViewController: BaseViewController { return button }() - private let nextButton: LOButton = { + private lazy var nextButton: LOButton = { let button = LOButton(style: .basic) button.setTitle("다음", for: .normal) button.addTarget(self, action: #selector(nextButtonDidTap), for: .touchUpInside) diff --git a/iOS/Layover/Layover/Scenes/UploadPost/UploadPostConfigurator.swift b/iOS/Layover/Layover/Scenes/UploadPost/UploadPostConfigurator.swift index e9215b2..85794a6 100644 --- a/iOS/Layover/Layover/Scenes/UploadPost/UploadPostConfigurator.swift +++ b/iOS/Layover/Layover/Scenes/UploadPost/UploadPostConfigurator.swift @@ -21,12 +21,15 @@ final class UploadPostConfigurator: Configurator { let interactor = UploadPostInteractor() let presenter = UploadPostPresenter() let router = UploadPostRouter() + let worker = UploadPostWorker() + worker.sessionTaskDelegate = interactor router.viewController = viewController router.dataStore = interactor viewController.interactor = interactor viewController.router = router interactor.presenter = presenter + interactor.worker = worker presenter.viewController = viewController } diff --git a/iOS/Layover/Layover/Scenes/UploadPost/UploadPostInteractor.swift b/iOS/Layover/Layover/Scenes/UploadPost/UploadPostInteractor.swift index b776105..37aebaf 100644 --- a/iOS/Layover/Layover/Scenes/UploadPost/UploadPostInteractor.swift +++ b/iOS/Layover/Layover/Scenes/UploadPost/UploadPostInteractor.swift @@ -17,7 +17,9 @@ protocol UploadPostBusinessLogic { func fetchThumbnailImage() func fetchCurrentAddress() func canUploadPost(request: UploadPostModels.CanUploadPost.Request) - func uploadPost(request: UploadPostModels.UploadPost.Request) + + @discardableResult + func uploadPost(request: UploadPostModels.UploadPost.Request) -> Task } protocol UploadPostDataStore { @@ -26,13 +28,13 @@ protocol UploadPostDataStore { var tags: [String]? { get set } } -final class UploadPostInteractor: UploadPostBusinessLogic, UploadPostDataStore { +final class UploadPostInteractor: NSObject, UploadPostBusinessLogic, UploadPostDataStore { // MARK: - Properties typealias Models = UploadPostModels - lazy var worker = UploadPostWorker() + var worker: UploadPostWorkerProtocol? var presenter: UploadPostPresentationLogic? private let fileManager: FileManager @@ -56,7 +58,7 @@ final class UploadPostInteractor: UploadPostBusinessLogic, UploadPostDataStore { func fetchTags() { guard let tags else { return } - presenter?.presentTags(with: UploadPostModels.FetchTags.Response(tags: tags)) + presenter?.presentTags(with: Models.FetchTags.Response(tags: tags)) } func fetchThumbnailImage() { @@ -68,7 +70,7 @@ final class UploadPostInteractor: UploadPostBusinessLogic, UploadPostDataStore { do { let image = try await generator.image(at: .zero).image await MainActor.run { - presenter?.presentThumnailImage(with: UploadPostModels.FetchThumbnail.Response(thumnailImage: image)) + presenter?.presentThumnailImage(with: Models.FetchThumbnail.Response(thumnailImage: image)) } } catch let error { os_log(.error, log: .default, "Failed to fetch Thumbnail Image with error: %@", error.localizedDescription) @@ -77,12 +79,7 @@ final class UploadPostInteractor: UploadPostBusinessLogic, UploadPostDataStore { } func fetchCurrentAddress() { - locationManager.desiredAccuracy = kCLLocationAccuracyBest - locationManager.startUpdatingLocation() - - guard let space = locationManager.location?.coordinate else { return } - let location = CLLocation(latitude: space.latitude, - longitude: space.longitude) + guard let location = getCurrentLocation() else { return } let locale = Locale(identifier: "ko_KR") Task { @@ -104,22 +101,42 @@ final class UploadPostInteractor: UploadPostBusinessLogic, UploadPostDataStore { } func canUploadPost(request: UploadPostModels.CanUploadPost.Request) { - let response = UploadPostModels.CanUploadPost.Response(isEmpty: request.title == nil) + let response = Models.CanUploadPost.Response(isEmpty: request.title == nil) presenter?.presentUploadButton(with: response) } - func uploadPost(request: UploadPostModels.UploadPost.Request) { - guard let videoURL, let isMuted else { return } - if isMuted { - exportVideoWithoutAudio(at: videoURL) + @discardableResult + func uploadPost(request: UploadPostModels.UploadPost.Request) -> Task { + Task { + guard let worker, + let videoURL, + let isMuted, + let coordinate = getCurrentLocation()?.coordinate else { return false } + if isMuted { + exportVideoWithoutAudio(at: videoURL) + } + await MainActor.run { + NotificationCenter.default.post(name: .uploadTaskStart, object: nil) + } + let response = await worker.uploadPost(with: UploadPost(title: request.title, + content: request.content, + latitude: coordinate.latitude, + longitude: coordinate.longitude, + tag: request.tags, + videoURL: videoURL)) + return response } + } + private func getCurrentLocation() -> CLLocation? { + locationManager.desiredAccuracy = kCLLocationAccuracyBest + locationManager.startUpdatingLocation() - - + guard let space = locationManager.location?.coordinate else { return nil } + let location = CLLocation(latitude: space.latitude, longitude: space.longitude) + return location } - // isMuted가 true인 경우, 새로운 Composition을 만들어서 영상 재추출해서 업로드 private func exportVideoWithoutAudio(at url: URL) { let composition = AVMutableComposition() let sourceAsset = AVURLAsset(url: url) @@ -145,9 +162,32 @@ final class UploadPostInteractor: UploadPostBusinessLogic, UploadPostDataStore { exporter?.outputFileType = AVFileType.mov await exporter?.export() } catch { - os_log(.error, log: .default, "Failed to extract Video Without Audio with error: %@", error.localizedDescription) + os_log(.error, log: .data, "Failed to extract Video Without Audio with error: %@", error.localizedDescription) } } } } + +extension UploadPostInteractor: URLSessionTaskDelegate { + + func urlSession( + _ session: URLSession, + task: URLSessionTask, + didSendBodyData bytesSent: Int64, + totalBytesSent: Int64, + totalBytesExpectedToSend: Int64 + ) { + let uploadProgress: Float = Float(Double(totalBytesSent) / Double(totalBytesExpectedToSend)) + DispatchQueue.main.async { + NotificationQueue.default.enqueue(Notification(name: .progressChanged, + userInfo: ["progress": uploadProgress]), + postingStyle: .now) + } + } + + func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { + // TODO: 완료 토스트 + + } +} diff --git a/iOS/Layover/Layover/Scenes/UploadPost/UploadPostModels.swift b/iOS/Layover/Layover/Scenes/UploadPost/UploadPostModels.swift index 246988b..e722fff 100644 --- a/iOS/Layover/Layover/Scenes/UploadPost/UploadPostModels.swift +++ b/iOS/Layover/Layover/Scenes/UploadPost/UploadPostModels.swift @@ -65,8 +65,6 @@ enum UploadPostModels { struct Request { let title: String let content: String? - let latitude: Double - let longitude: Double let tags: [String] } struct Response { diff --git a/iOS/Layover/Layover/Scenes/UploadPost/UploadPostPresenter.swift b/iOS/Layover/Layover/Scenes/UploadPost/UploadPostPresenter.swift index 20c86fa..f87cef8 100644 --- a/iOS/Layover/Layover/Scenes/UploadPost/UploadPostPresenter.swift +++ b/iOS/Layover/Layover/Scenes/UploadPost/UploadPostPresenter.swift @@ -13,6 +13,7 @@ protocol UploadPostPresentationLogic { func presentThumnailImage(with response: UploadPostModels.FetchThumbnail.Response) func presentCurrentAddress(with response: UploadPostModels.FetchCurrentAddress.Response) func presentUploadButton(with response: UploadPostModels.CanUploadPost.Response) +// func presentUploadProgress(with response: UploadPostModels.UploadPost.Response) } final class UploadPostPresenter: UploadPostPresentationLogic { @@ -23,25 +24,35 @@ final class UploadPostPresenter: UploadPostPresentationLogic { weak var viewController: UploadPostDisplayLogic? func presentTags(with response: UploadPostModels.FetchTags.Response) { - viewController?.displayTags(viewModel: UploadPostModels.FetchTags.ViewModel(tags: response.tags)) + viewController?.displayTags(viewModel: Models.FetchTags.ViewModel(tags: response.tags)) } func presentThumnailImage(with response: UploadPostModels.FetchThumbnail.Response) { let image = UIImage(cgImage: response.thumnailImage) - viewController?.displayThumbnail(viewModel: UploadPostModels.FetchThumbnail.ViewModel(thumnailImage: image)) + viewController?.displayThumbnail(viewModel: Models.FetchThumbnail.ViewModel(thumnailImage: image)) } func presentCurrentAddress(with response: UploadPostModels.FetchCurrentAddress.Response) { - let addressSet = Set([response.administrativeArea, response.locality, response.subLocality]) - let fullAddress: String = Array(addressSet) + let addresses: [String] = [ + response.administrativeArea, + response.locality, + response.subLocality] .compactMap { $0 } - .joined(separator: " ") - let viewModel = UploadPostModels.FetchCurrentAddress.ViewModel(fullAddress: fullAddress) + + var fullAddress: [String] = [] + + for address in addresses { + if !fullAddress.contains(address) { + fullAddress.append(address) + } + } + + let viewModel = Models.FetchCurrentAddress.ViewModel(fullAddress: fullAddress.joined(separator: " ")) viewController?.displayCurrentAddress(viewModel: viewModel) } func presentUploadButton(with response: UploadPostModels.CanUploadPost.Response) { - let viewModel = UploadPostModels.CanUploadPost.ViewModel(canUpload: !response.isEmpty) + let viewModel = Models.CanUploadPost.ViewModel(canUpload: !response.isEmpty) viewController?.displayUploadButton(viewModel: viewModel) } diff --git a/iOS/Layover/Layover/Scenes/UploadPost/UploadPostRouter.swift b/iOS/Layover/Layover/Scenes/UploadPost/UploadPostRouter.swift index 2d838ba..4b9b74f 100644 --- a/iOS/Layover/Layover/Scenes/UploadPost/UploadPostRouter.swift +++ b/iOS/Layover/Layover/Scenes/UploadPost/UploadPostRouter.swift @@ -10,13 +10,14 @@ import UIKit protocol UploadPostRoutingLogic { func routeToNext() + func routeToBack() } protocol UploadPostDataPassing { var dataStore: UploadPostDataStore? { get } } -class UploadPostRouter: NSObject, UploadPostRoutingLogic, UploadPostDataPassing { +final class UploadPostRouter: NSObject, UploadPostRoutingLogic, UploadPostDataPassing { // MARK: - Properties @@ -36,4 +37,8 @@ class UploadPostRouter: NSObject, UploadPostRoutingLogic, UploadPostDataPassing viewController?.present(nextViewController, animated: true) } + func routeToBack() { + viewController?.navigationController?.popToRootViewController(animated: true) + } + } diff --git a/iOS/Layover/Layover/Scenes/UploadPost/UploadPostViewController.swift b/iOS/Layover/Layover/Scenes/UploadPost/UploadPostViewController.swift index 4f8a972..f16890e 100644 --- a/iOS/Layover/Layover/Scenes/UploadPost/UploadPostViewController.swift +++ b/iOS/Layover/Layover/Scenes/UploadPost/UploadPostViewController.swift @@ -42,7 +42,7 @@ final class UploadPostViewController: BaseViewController { return imageLabel }() - private let titleTextField: LOTextField = { + private lazy var titleTextField: LOTextField = { let textField = LOTextField() textField.placeholder = "제목" textField.addTarget(self, action: #selector(titleTextChanged), for: .editingChanged) @@ -228,7 +228,7 @@ final class UploadPostViewController: BaseViewController { } @objc private func titleTextChanged() { - interactor?.canUploadPost(request: UploadPostModels.CanUploadPost.Request(title: titleTextField.text)) + interactor?.canUploadPost(request: Models.CanUploadPost.Request(title: titleTextField.text)) } @objc private func viewDidTap() { @@ -240,7 +240,12 @@ final class UploadPostViewController: BaseViewController { } @objc private func uploadButtonDidTap() { - interactor?.uploadPost() + guard let title = titleTextField.text else { return } + let request = Models.UploadPost.Request(title: title, + content: contentTextView.text, + tags: tagStackView.tags) + interactor?.uploadPost(request: request) + router?.routeToBack() } } diff --git a/iOS/Layover/Layover/Scenes/UploadPost/UploadPostWorker.swift b/iOS/Layover/Layover/Scenes/UploadPost/UploadPostWorker.swift index 24b3852..5ff3354 100644 --- a/iOS/Layover/Layover/Scenes/UploadPost/UploadPostWorker.swift +++ b/iOS/Layover/Layover/Scenes/UploadPost/UploadPostWorker.swift @@ -11,8 +11,7 @@ import UIKit import OSLog protocol UploadPostWorkerProtocol { - func uploadPost(with request: UploadPost, - url: URL) async -> UploadPostDTO? + func uploadPost(with request: UploadPost) async -> Bool } final class UploadPostWorker: NSObject, UploadPostWorkerProtocol { @@ -23,6 +22,8 @@ final class UploadPostWorker: NSObject, UploadPostWorkerProtocol { private let provider: ProviderType private let uploadPostEndPointFactory: UploadPostEndPointFactory + weak var sessionTaskDelegate: URLSessionTaskDelegate? + // MARK: - Methods init(provider: ProviderType = Provider(), @@ -31,8 +32,7 @@ final class UploadPostWorker: NSObject, UploadPostWorkerProtocol { self.uploadPostEndPointFactory = uploadPostEndPointFactory } - func uploadPost(with request: UploadPost, - url: URL) async -> UploadPostDTO? { + func uploadPost(with request: UploadPost) async -> Bool { let endPoint = uploadPostEndPointFactory.makeUploadPostEndPoint(title: request.title, content: request.content, latitude: request.latitude, @@ -40,38 +40,31 @@ final class UploadPostWorker: NSObject, UploadPostWorkerProtocol { tag: request.tag) do { let response = try await provider.request(with: endPoint) - - guard let boardID = response.data?.id else { return nil } - + guard let boardID = response.data?.id else { return false } let fileType = request.videoURL.pathExtension - let upload = await uploadVideo(with: UploadVideoRequestDTO(boardID: boardID, - filetype: fileType), - videoURL: url) - return response.data + let uploadResponse = await uploadVideo(with: UploadVideoRequestDTO(boardID: boardID, filetype: fileType), + videoURL: request.videoURL) + return uploadResponse } catch { - os_log(.error, log: .default, "Failed to fetch posts: %@", error.localizedDescription) - return nil + os_log(.error, log: .data, "Failed to fetch posts: %@", error.localizedDescription) + return false } } - private func uploadVideo(with request: UploadVideoRequestDTO, - videoURL: URL) async -> Bool { + private func uploadVideo(with request: UploadVideoRequestDTO, videoURL: URL) async -> Bool { let endPoint = uploadPostEndPointFactory.makeUploadVideoEndPoint(boardID: request.boardID, fileType: request.filetype) do { let response = try await provider.request(with: endPoint) - guard let presignedURLString = response.data?.presignedUrl else { return false } - let uploadResponse = try await provider.backgroundUpload(fromFile: videoURL, - to: presignedURLString, - sessionTaskDelegate: self) + guard let preSignedURLString = response.data?.preSignedURL else { return false } + let data = try await provider.backgroundUpload(fromFile: videoURL, + to: preSignedURLString, + sessionTaskDelegate: sessionTaskDelegate) return true } catch { + os_log(.error, log: .data, "Failed to upload Video: %@", error.localizedDescription) return false } } } - -extension UploadPostWorker: URLSessionTaskDelegate { - -}