Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Nextcloud.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -5946,7 +5946,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 0;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = NKUJUXUJ3B;
ENABLE_STRICT_OBJC_MSGSEND = YES;
Expand Down Expand Up @@ -6012,7 +6012,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 0;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = NKUJUXUJ3B;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
Expand Down
23 changes: 15 additions & 8 deletions iOSClient/Networking/NCNetworking+Download.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ extension NCNetworking {
downloadTask = task
} progressHandler: { progress in
Task {
guard await self.progressQuantizer.shouldEmit(serverUrlFileName: metadata.serverUrlFileName, fraction: progress.fractionCompleted) else {
return
}
await NCManageDatabase.shared.setMetadataProgress(ocId: metadata.ocId, progress: progress.fractionCompleted)
await self.transferDispatcher.notifyAllDelegates { delegate in
delegate.transferProgressDidUpdate(progress: Float(progress.fractionCompleted),
Expand All @@ -91,6 +94,10 @@ extension NCNetworking {
progressHandler(progress)
}

Task {
await progressQuantizer.clear(serverUrlFileName: metadata.serverUrlFileName)
}

if withDownloadComplete {
var error = NKError()
var dateLastModified: Date?
Expand All @@ -115,9 +122,7 @@ extension NCNetworking {
@discardableResult
func downloadFileInBackground(metadata: tableMetadata,
taskHandler: @escaping (_ task: URLSessionDownloadTask?) -> Void = { _ in },
start: @escaping () -> Void = { })
async -> NKError {

start: @escaping () -> Void = { }) async -> NKError {
let fileNameLocalPath = utilityFileSystem.getDirectoryProviderStorageOcId(metadata.ocId, fileName: metadata.fileNameView, userId: metadata.userId, urlBase: metadata.urlBase)

start()
Expand Down Expand Up @@ -164,9 +169,10 @@ extension NCNetworking {
length: Int64,
task: URLSessionTask,
error: NKError) {

#if EXTENSION_FILE_PROVIDER_EXTENSION
Task {
await progressQuantizer.clear(serverUrlFileName: serverUrl + "/" + fileName)

#if EXTENSION_FILE_PROVIDER_EXTENSION
await FileProviderData.shared.downloadComplete(fileName: fileName,
serverUrl: serverUrl,
etag: etag,
Expand All @@ -176,10 +182,8 @@ extension NCNetworking {
task: task,
error: error)
return
}
#endif
#endif

Task {
guard let metadata = await NCManageDatabase.shared.getMetadataAsync(predicate: NSPredicate(format: "serverUrl == %@ AND fileName == %@", serverUrl, fileName)) else {
return
}
Expand Down Expand Up @@ -288,6 +292,9 @@ extension NCNetworking {
task: URLSessionTask) {

Task {
guard await progressQuantizer.shouldEmit(serverUrlFileName: serverUrl + "/" + fileName, fraction: Double(progress)) else {
return
}
await NCManageDatabase.shared.setMetadataProgress(fileName: fileName, serverUrl: serverUrl, taskIdentifier: task.taskIdentifier, progress: Double(progress))
await self.transferDispatcher.notifyAllDelegates { delegate in
delegate.transferProgressDidUpdate(progress: progress,
Expand Down
40 changes: 27 additions & 13 deletions iOSClient/Networking/NCNetworking+Upload.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ extension NCNetworking {
taskHandler(task)
} progressHandler: { progress in
Task {
guard await self.progressQuantizer.shouldEmit(serverUrlFileName: serverUrlFileName, fraction: progress.fractionCompleted) else {
return
}

if let metadata {
await NCManageDatabase.shared.setMetadataProgress(ocId: metadata.ocId, progress: progress.fractionCompleted)
await self.transferDispatcher.notifyAllDelegates { delegate in
Expand All @@ -64,6 +68,10 @@ extension NCNetworking {
progressHandler(progress.completedUnitCount, progress.totalUnitCount, progress.fractionCompleted)
}

Task {
await progressQuantizer.clear(serverUrlFileName: serverUrlFileName)
}

if withUploadComplete, let metadata {
await self.uploadComplete(withMetadata: metadata, ocId: results.ocId, etag: results.etag, date: results.date, size: results.size, error: results.error)
}
Expand Down Expand Up @@ -138,6 +146,9 @@ extension NCNetworking {
taskHandler(task)
} progressHandler: { totalBytesExpected, totalBytes, fractionCompleted in
Task {
guard await self.progressQuantizer.shouldEmit(serverUrlFileName: metadata.serverUrlFileName, fraction: fractionCompleted) else {
return
}
await NCManageDatabase.shared.setMetadataProgress(ocId: metadata.ocId, progress: fractionCompleted)
await self.transferDispatcher.notifyAllDelegates { delegate in
delegate.transferProgressDidUpdate(progress: Float(fractionCompleted),
Expand Down Expand Up @@ -451,21 +462,21 @@ extension NCNetworking {
size: Int64,
task: URLSessionTask,
error: NKError) {
#if EXTENSION_FILE_PROVIDER_EXTENSION
Task {
await FileProviderData.shared.uploadComplete(fileName: fileName,
serverUrl: serverUrl,
ocId: ocId,
etag: etag,
date: date,
size: size,
task: task,
error: error)
return
}
#endif
await progressQuantizer.clear(serverUrlFileName: serverUrl + "/" + fileName)

#if EXTENSION_FILE_PROVIDER_EXTENSION
await FileProviderData.shared.uploadComplete(fileName: fileName,
serverUrl: serverUrl,
ocId: ocId,
etag: etag,
date: date,
size: size,
task: task,
error: error)
return
#endif

Task {
if let metadata = await NCManageDatabase.shared.getMetadataAsync(predicate: NSPredicate(format: "serverUrl == %@ AND fileName == %@", serverUrl, fileName)) {
await uploadComplete(withMetadata: metadata, ocId: ocId, etag: etag, date: date, size: size, error: error)
} else {
Expand All @@ -483,6 +494,9 @@ extension NCNetworking {
session: URLSession,
task: URLSessionTask) {
Task {
guard await progressQuantizer.shouldEmit(serverUrlFileName: serverUrl + "/" + fileName, fraction: Double(progress)) else {
return
}
await NCManageDatabase.shared.setMetadataProgress(fileName: fileName, serverUrl: serverUrl, taskIdentifier: task.taskIdentifier, progress: Double(progress))
await self.transferDispatcher.notifyAllDelegates { delegate in
delegate.transferProgressDidUpdate(progress: progress,
Expand Down
31 changes: 31 additions & 0 deletions iOSClient/Networking/NCNetworking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,35 @@ actor NetworkingTasks {
}
}

/// Quantizes per-task progress updates to integer percentages (0...100).
/// Each (serverUrlFileName) pair is tracked separately, so you get
/// at most one update per integer percent for each transfer.
actor ProgressQuantizer {
private var lastPercent: [String: Int] = [:]

/// Returns `true` only when integer percent changes (or hits 100).
///
/// - Parameters:
/// - serverUrlFileName: The name of the file being transferred.
/// - fraction: Progress fraction [0.0 ... 1.0].
func shouldEmit(serverUrlFileName: String, fraction: Double) -> Bool {
let percent = min(max(Int((fraction * 100).rounded(.down)), 0), 100)

let last = lastPercent[serverUrlFileName] ?? -1
guard percent != last || percent == 100 else {
return false
}

lastPercent[serverUrlFileName] = percent
return true
}

/// Clears stored state for a finished transfer.
func clear(serverUrlFileName: String) {
lastPercent.removeValue(forKey: serverUrlFileName)
}
}

class NCNetworking: @unchecked Sendable, NextcloudKitDelegate {
static let shared = NCNetworking()

Expand Down Expand Up @@ -265,6 +294,8 @@ class NCNetworking: @unchecked Sendable, NextcloudKitDelegate {

let transferDispatcher = NCTransferDelegateDispatcher()

let progressQuantizer = ProgressQuantizer()

// OPERATIONQUEUE
let downloadThumbnailQueue = Queuer(name: "downloadThumbnailQueue", maxConcurrentOperationCount: 10, qualityOfService: .default)
let downloadThumbnailActivityQueue = Queuer(name: "downloadThumbnailActivityQueue", maxConcurrentOperationCount: 10, qualityOfService: .default)
Expand Down
1 change: 0 additions & 1 deletion iOSClient/Networking/NCNetworkingProcess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@

await runMetadataPipelineAsync()

// TODO: Check temperature

Check warning on line 129 in iOSClient/Networking/NCNetworkingProcess.swift

View workflow job for this annotation

GitHub Actions / Lint

Todo Violation: TODOs should be resolved (Check temperature) (todo)

if lastUsedInterval != minInterval {
await startTimer(interval: minInterval)
Expand Down Expand Up @@ -585,7 +585,6 @@
} else {
await database.setMetadataSessionAsync(ocId: metadata.ocId,
status: global.metadataStatusNormal)

metadatasError[metadata] = resultDelete.error
returnError = resultDelete.error
}
Expand Down
3 changes: 2 additions & 1 deletion iOSClient/Networking/NCService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ class NCService: NSObject {
etag: metadata.etag,
metadatasInDownload: metadatasInDownload,
userId: metadata.userId,
urlBase: metadata.urlBase) {
urlBase: metadata.urlBase),
metadata.status == self.global.metadataStatusNormal {
await self.database.setMetadataSessionInWaitDownloadAsync(ocId: metadata.ocId,
session: NCNetworking.shared.sessionDownloadBackground,
selector: NCGlobal.shared.selectorSynchronizationOffline)
Expand Down
Loading