diff --git a/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ShareExtensionScene.swift b/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ShareExtensionScene.swift index d3fa98d5f..1566bcf91 100644 --- a/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ShareExtensionScene.swift +++ b/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ShareExtensionScene.swift @@ -26,6 +26,7 @@ final class ShareExtensionViewModel: ObservableObject { @Published var debugText: String? var subscriptions = Set() + var backgroundTask: UIBackgroundTaskIdentifier? let requestID = UUID().uuidString.lowercased() init() {} @@ -41,11 +42,16 @@ final class ShareExtensionViewModel: ObservableObject { } func savePage(extensionContext: NSExtensionContext?) { + backgroundTask = UIApplication.shared.beginBackgroundTask(withName: "BACKGROUND") + PageScraper.scrape(extensionContext: extensionContext) { [weak self] result in switch result { case let .success(payload): self?.persist(pageScrapePayload: payload, requestId: self?.requestID ?? "") case let .failure(error): + if let backgroundTask = self?.backgroundTask { + UIApplication.shared.endBackgroundTask(backgroundTask) + } self?.debugText = error.message } } @@ -59,7 +65,6 @@ final class ShareExtensionViewModel: ObservableObject { return } - let backgroundTask = UIApplication.shared.beginBackgroundTask(withName: requestId) let saveLinkPublisher: AnyPublisher = { if case let .pdf(data) = pageScrapePayload.contentType { return services.dataService.uploadPDFPublisher(pageScrapePayload: pageScrapePayload, @@ -80,10 +85,14 @@ final class ShareExtensionViewModel: ObservableObject { guard case let .failure(error) = completion else { return } self?.debugText = "saveArticleError: \(error)" self?.status = .failed(error: error) - UIApplication.shared.endBackgroundTask(backgroundTask) + if let backgroundTask = self?.backgroundTask { + UIApplication.shared.endBackgroundTask(backgroundTask) + } } receiveValue: { [weak self] _ in self?.status = .success - UIApplication.shared.endBackgroundTask(backgroundTask) + if let backgroundTask = self?.backgroundTask { + UIApplication.shared.endBackgroundTask(backgroundTask) + } } .store(in: &subscriptions) diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/SavePDF.swift b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/SavePDF.swift index 4267b5a6f..df0511ed6 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/SavePDF.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/SavePDF.swift @@ -64,6 +64,7 @@ private extension DataService { return Deferred { Future { promise in send(mutation, to: path, headers: headers) { result in + print("result of upload file request", result) switch result { case let .success(payload): if let graphqlError = payload.errors { @@ -100,29 +101,43 @@ private extension DataService { request.addValue("application/pdf", forHTTPHeaderField: "content-type") request.httpBody = data - return networker.urlSession.dataTaskPublisher(for: request) - .tryMap { data, response -> String in - let serverResponse = ServerResponse(data: data, response: response) - if serverResponse.httpUrlResponse?.statusCode == 200, let fileUploadID = fileUploadConfig.uploadID { - return fileUploadID - } + // TODO: Maybe better to copy into this directory immediately + // instead of loading and writing the data + let tempDir = FileManager.default.temporaryDirectory + let localURL = tempDir.appendingPathComponent(fileUploadConfig.uploadFileID ?? "temporary") + try? data.write(to: localURL) - throw ServerError(serverResponse: serverResponse) - } - .mapError { error -> SaveArticleError in - let serverResponse = ServerResponse(error: error) - NetworkRequestLogger.log(request: request, serverResponse: serverResponse) - let serverError = ServerError(serverResponse: serverResponse) - switch serverError { - case .noConnection, .timeout: - return .network - case .unauthenticated: - return .unauthorized - case .unknown: - return .unknown(description: "upload to file server failed") - } - } - .eraseToAnyPublisher() + print("STARTING UPLOAD TASK WITH LOCAL URL", localURL) + + let task = networker.backgroundSession.uploadTask(with: request, fromFile: localURL) + task.resume() + + // Just return immediately at this point. + return Empty(completeImmediately: true).eraseToAnyPublisher() +// return "".publisher.eraseToAnyPublisher() +// return networker.urlSession.dataTaskPublisher(for: request) +// .tryMap { data, response -> String in +// let serverResponse = ServerResponse(data: data, response: response) +// if serverResponse.httpUrlResponse?.statusCode == 200, let fileUploadID = fileUploadConfig.uploadID { +// return fileUploadID +// } +// +// throw ServerError(serverResponse: serverResponse) +// } +// .mapError { error -> SaveArticleError in +// let serverResponse = ServerResponse(error: error) +// NetworkRequestLogger.log(request: request, serverResponse: serverResponse) +// let serverError = ServerError(serverResponse: serverResponse) +// switch serverError { +// case .noConnection, .timeout: +// return .network +// case .unauthenticated: +// return .unauthorized +// case .unknown: +// return .unknown(description: "upload to file server failed") +// } +// } +// .eraseToAnyPublisher() } // swiftlint:disable:next line_length diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Networking/Networker.swift b/apple/OmnivoreKit/Sources/Services/DataService/Networking/Networker.swift index 4f2869e23..cdf683d3e 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Networking/Networker.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Networking/Networker.swift @@ -1,7 +1,7 @@ import Foundation import Models -public final class Networker { +public final class Networker: NSObject, URLSessionTaskDelegate { let urlSession: URLSession let appEnvironment: AppEnvironment @@ -15,9 +15,28 @@ public final class Networker { return headers } - public init(appEnvironment: AppEnvironment, urlSession: URLSession = .shared) { + public init(appEnvironment: AppEnvironment) { self.appEnvironment = appEnvironment - self.urlSession = urlSession + self.urlSession = .shared + } + + lazy var backgroundSession: URLSession = { + let sessionConfig = URLSessionConfiguration.background(withIdentifier: "app.omnivoreapp.BackgroundSessionConfig") + sessionConfig.sharedContainerIdentifier = "group.app.omnivoreapp" + return URLSession(configuration: sessionConfig, delegate: self, delegateQueue: nil) + }() + + public func urlSession(_: URLSession, task: URLSessionTask, didCompleteWithError _: Error?) { + print("finished upload of file:", task.taskIdentifier) + } + + public func urlSession(_: URLSession, + task: URLSessionTask, + didSendBodyData _: Int64, + totalBytesSent: Int64, + totalBytesExpectedToSend _: Int64) + { + print("sent background data:", task.taskIdentifier, totalBytesSent) } }