Skip to content

Commit

Permalink
fix: ShareExtension fails to upload (#1123)
Browse files Browse the repository at this point in the history
* feat: DI is aware of context that starts it

* feat: New AppContextService

* refactor: Migrate isExtension to appContextService.isExtension

* fix: Prevent UploadQueue in ShareExtension mode

* chore: PR Feedback
  • Loading branch information
adrien-coye authored Feb 27, 2024
1 parent 3f687e1 commit fc0af91
Show file tree
Hide file tree
Showing 19 changed files with 210 additions and 28 deletions.
2 changes: 1 addition & 1 deletion kDrive/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import VersionChecker
@main
final class AppDelegate: UIResponder, UIApplicationDelegate, AccountManagerDelegate {
/// Making sure the DI is registered at a very early stage of the app launch.
private let dependencyInjectionHook = EarlyDIHook()
private let dependencyInjectionHook = EarlyDIHook(context: .app)

private var reachabilityListener: ReachabilityListener!
private static let currentStateVersion = 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ extension SaveFileViewController: FooterButtonDelegate {

private func processForUpload(files: [ImportedFile], directory: File, drive: Drive) async throws {
// We only schedule for uploading in main app target
let addToQueue = !Bundle.main.isExtension
let addToQueue = !appContextService.isExtension
try await fileImportHelper.saveForUpload(files, in: directory, drive: drive, addToQueue: addToQueue)
#if ISEXTENSION
showOpenAppToContinueNotification()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import UIKit
class SaveFileViewController: UIViewController {
@LazyInjectService var accountManager: AccountManageable
@LazyInjectService var fileImportHelper: FileImportHelper
@LazyInjectService var appContextService: AppContextServiceable

enum SaveFileSection {
case alert
Expand Down Expand Up @@ -184,7 +185,7 @@ class SaveFileViewController: UIViewController {
func dismiss(animated: Bool, clean: Bool = true, completion: (() -> Void)? = nil) {
Task {
// Cleanup file that were duplicated to appGroup on extension mode
if Bundle.main.isExtension && clean {
if appContextService.isExtension && clean {
await items.concurrentForEach { item in
try? FileManager.default.removeItem(at: item.path)
}
Expand Down
14 changes: 8 additions & 6 deletions kDrive/Utils/AppFactoryService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,16 @@ import os.log

/// Something that loads the DI on init
public struct EarlyDIHook {
public init() {
// setup DI ASAP
public init(context: DriveAppContext) {
os_log("EarlyDIHook")

let navigationManagerFactory = Factory(type: NavigationManageable.self) { _, _ in
let extraDependencies = [Factory(type: NavigationManageable.self) { _, _ in
NavigationManager()
}
}, Factory(type: AppContextServiceable.self) { _, _ in
AppContextService(context: context)
}]

os_log("EarlyDIHook")
FactoryService.setupDependencyInjection(other: [navigationManagerFactory])
// setup DI ASAP
FactoryService.setupDependencyInjection(other: extraDependencies)
}
}
2 changes: 1 addition & 1 deletion kDriveActionExtension/ActionNavigationController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import VersionChecker

final class ActionNavigationController: TitleSizeAdjustingNavigationController {
/// Making sure the DI is registered at a very early stage of the app launch.
private let dependencyInjectionHook = EarlyDIHook()
private let dependencyInjectionHook = EarlyDIHook(context: .actionExtension)

@LazyInjectService var accountManager: AccountManageable

Expand Down
3 changes: 2 additions & 1 deletion kDriveCore/Data/Api/DriveApiFetcher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ public class DriveApiFetcher: ApiFetcher {
class SyncedAuthenticator: OAuthAuthenticator {
@LazyInjectService var accountManager: AccountManageable
@LazyInjectService var tokenable: InfomaniakTokenable
@LazyInjectService var appContextService: AppContextServiceable

override func refresh(
_ credential: OAuthAuthenticator.Credential,
Expand Down Expand Up @@ -507,7 +508,7 @@ class SyncedAuthenticator: OAuthAuthenticator {
let group = DispatchGroup()
group.enter()
var taskIdentifier: UIBackgroundTaskIdentifier = .invalid
if !Bundle.main.isExtension {
if !self.appContextService.isExtension {
// It is absolutely necessary that the app stays awake while we refresh the token
taskIdentifier = UIApplication.shared.beginBackgroundTask(withName: "Refresh token") {
let message = "Refreshing token failed - Background task expired"
Expand Down
3 changes: 2 additions & 1 deletion kDriveCore/Data/DownloadQueue/DownloadArchiveOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class DownloadArchiveOperation: Operation {
// MARK: - Attributes

@LazyInjectService var accountManager: AccountManageable
@LazyInjectService var appContextService: AppContextServiceable

private let archiveId: String
private let driveFileManager: DriveFileManager
Expand Down Expand Up @@ -85,7 +86,7 @@ public class DownloadArchiveOperation: Operation {
return
}

if !Bundle.main.isExtension {
if !appContextService.isExtension {
backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(withName: "File Archive Downloader") {
DownloadQueue.instance.suspendAllOperations()
// We don't support task rescheduling for archive download but still need to pass error to differentiate from user
Expand Down
3 changes: 2 additions & 1 deletion kDriveCore/Data/DownloadQueue/DownloadOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class DownloadOperation: Operation, DownloadOperationable {

@LazyInjectService var accountManager: AccountManageable
@LazyInjectService var downloadManager: BackgroundDownloadSessionManager
@LazyInjectService var appContextService: AppContextServiceable

private let fileManager = FileManager.default
private let driveFileManager: DriveFileManager
Expand Down Expand Up @@ -116,7 +117,7 @@ public class DownloadOperation: Operation, DownloadOperationable {
return
}

if !Bundle.main.isExtension {
if !appContextService.isExtension {
backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(withName: "File Downloader") {
DownloadQueue.instance.suspendAllOperations()
DDLogInfo("[DownloadOperation] Background task expired")
Expand Down
11 changes: 6 additions & 5 deletions kDriveCore/Data/DownloadQueue/DownloadQueue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public final class DownloadQueue {
// MARK: - Attributes

@LazyInjectService var accountManager: AccountManageable
@LazyInjectService var appContextService: AppContextServiceable

public static let instance = DownloadQueue()
public static let backgroundIdentifier = "com.infomaniak.background.download"
Expand Down Expand Up @@ -90,7 +91,7 @@ public final class DownloadQueue {
)

private var bestSession: FileDownloadSession {
if Bundle.main.isExtension {
if appContextService.isExtension {
@InjectService var backgroundDownloadSessionManager: BackgroundDownloadSessionManager
return backgroundDownloadSessionManager
} else {
Expand Down Expand Up @@ -220,25 +221,25 @@ public final class DownloadQueue {
}

private func publishFileDownloaded(fileId: Int, error: DriveError?) {
observations.didDownloadFile.values.forEach { closure in
for closure in observations.didDownloadFile.values {
closure(fileId, error)
}
}

func publishProgress(_ progress: Double, for fileId: Int) {
observations.didChangeProgress.values.forEach { closure in
for closure in observations.didChangeProgress.values {
closure(fileId, progress)
}
}

private func publishArchiveDownloaded(archiveId: String, archiveUrl: URL?, error: DriveError?) {
observations.didDownloadArchive.values.forEach { closure in
for closure in observations.didDownloadArchive.values {
closure(archiveId, archiveUrl, error)
}
}

func publishProgress(_ progress: Double, for archiveId: String) {
observations.didChangeArchiveProgress.values.forEach { closure in
for closure in observations.didChangeArchiveProgress.values {
closure(archiveId, progress)
}
}
Expand Down
5 changes: 4 additions & 1 deletion kDriveCore/Data/UploadQueue/Chunk/RangeProviderGuts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

import Foundation
import InfomaniakDI

/// The internal methods of RangeProviderGuts, made testable
public protocol RangeProviderGutsable {
Expand Down Expand Up @@ -45,6 +46,8 @@ public protocol RangeProviderGutsable {

/// Subdivided **RangeProvider**, so it is easier to test
public struct RangeProviderGuts: RangeProviderGutsable {
@LazyInjectService private var appContextService: AppContextServiceable

/// The URL of the local file to scan
public let fileURL: URL

Expand Down Expand Up @@ -107,7 +110,7 @@ public struct RangeProviderGuts: RangeProviderGutsable {

public func preferredChunkSize(for fileSize: UInt64) -> UInt64 {
// In extension to reduce memory footprint, we reduce drastically chunk size
guard !Bundle.main.isExtension else {
guard !appContextService.isExtension else {
let capChunkSize = min(fileSize, RangeProvider.APIConstants.chunkMinSize)
return capChunkSize
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

import Foundation
import InfomaniakDI

/// Delegate protocol of UploadParallelismHeuristic
protocol ParallelismHeuristicDelegate: AnyObject {
Expand All @@ -33,6 +34,8 @@ final class UploadParallelismHeuristic {
/// With 2 Operations max, and a chuck of 1MiB max, the UploadQueue can spike to max 4MiB memory usage.
private static let reducedParallelism = 2

@LazyInjectService private var appContextService: AppContextServiceable

private weak var delegate: ParallelismHeuristicDelegate?

init(delegate: ParallelismHeuristicDelegate) {
Expand Down Expand Up @@ -80,7 +83,7 @@ final class UploadParallelismHeuristic {
}

// In extension, to reduce memory footprint, we reduce drastically parallelism
guard !Bundle.main.isExtension else {
guard !appContextService.isExtension else {
currentParallelism = Self.reducedParallelism
return
}
Expand Down
Loading

0 comments on commit fc0af91

Please sign in to comment.