From 0f2353aae6b7e58fd4fae34644e1f27537eaf0af Mon Sep 17 00:00:00 2001 From: Kiryl Kaveryn Date: Wed, 23 Jul 2025 18:36:22 +0400 Subject: [PATCH] [ios] Track the percentDownloaded for the downloaded from the cloud files Signed-off-by: Kiryl Kaveryn --- iphone/Maps/Core/iCloud/MetadataItem.swift | 10 ++++++++-- .../Core/iCloudTests/MetadataItemStubs.swift | 4 +++- .../SynchronizationStateManagerTests.swift | 16 ++++++++++++---- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/iphone/Maps/Core/iCloud/MetadataItem.swift b/iphone/Maps/Core/iCloud/MetadataItem.swift index 403993547..75e4c297d 100644 --- a/iphone/Maps/Core/iCloud/MetadataItem.swift +++ b/iphone/Maps/Core/iCloud/MetadataItem.swift @@ -14,6 +14,7 @@ struct CloudMetadataItem: MetadataItem { let fileName: String let fileUrl: URL var isDownloaded: Bool + var percentDownloaded: NSNumber var lastModificationDate: TimeInterval let downloadingError: NSError? let uploadingError: NSError? @@ -42,6 +43,7 @@ extension CloudMetadataItem { guard let fileName = metadataItem.value(forAttribute: NSMetadataItemFSNameKey) as? String, let fileUrl = metadataItem.value(forAttribute: NSMetadataItemURLKey) as? URL, let downloadStatus = metadataItem.value(forAttribute: NSMetadataUbiquitousItemDownloadingStatusKey) as? String, + let percentDownloaded = metadataItem.value(forAttribute: NSMetadataUbiquitousItemPercentDownloadedKey) as? NSNumber, let lastModificationDate = (metadataItem.value(forAttribute: NSMetadataItemFSContentChangeDateKey) as? Date)?.roundedTime, let hasUnresolvedConflicts = metadataItem.value(forAttribute: NSMetadataUbiquitousItemHasUnresolvedConflictsKey) as? Bool else { let allAttributes = metadataItem.values(forAttributes: metadataItem.attributes) @@ -51,6 +53,7 @@ extension CloudMetadataItem { self.fileName = fileName self.fileUrl = fileUrl.standardizedFileURL self.isDownloaded = downloadStatus == NSMetadataUbiquitousItemDownloadingStatusCurrent + self.percentDownloaded = percentDownloaded self.lastModificationDate = lastModificationDate self.hasUnresolvedConflicts = hasUnresolvedConflicts self.downloadingError = metadataItem.value(forAttribute: NSMetadataUbiquitousItemDownloadingErrorKey) as? NSError @@ -65,6 +68,7 @@ extension CloudMetadataItem { .ubiquitousItemDownloadingErrorKey, .ubiquitousItemUploadingErrorKey]) guard let downloadStatus = resources.ubiquitousItemDownloadingStatus, + let percentDownloaded = resources.ubiquitousItemDownloadingStatus, let lastModificationDate = resources.contentModificationDate?.roundedTime, let hasUnresolvedConflicts = resources.ubiquitousItemHasUnresolvedConflicts else { LOG(.error, "Failed to initialize CloudMetadataItem from \(fileUrl) resources: \(resources.allValues)") @@ -72,7 +76,9 @@ extension CloudMetadataItem { } self.fileName = fileUrl.lastPathComponent self.fileUrl = fileUrl.standardizedFileURL - self.isDownloaded = downloadStatus.rawValue == NSMetadataUbiquitousItemDownloadingStatusCurrent + let isDownloaded = downloadStatus.rawValue == NSMetadataUbiquitousItemDownloadingStatusCurrent + self.isDownloaded = isDownloaded + self.percentDownloaded = isDownloaded ? 0.0 : 100.0 self.lastModificationDate = lastModificationDate self.hasUnresolvedConflicts = hasUnresolvedConflicts self.downloadingError = resources.ubiquitousItemDownloadingError @@ -115,7 +121,7 @@ extension Array where Element == CloudMetadataItem { } var notDownloaded: Self { - filter { !$0.isDownloaded } + filter { !$0.isDownloaded && $0.percentDownloaded == 0.0 } } func withUnresolvedConflicts(_ hasUnresolvedConflicts: Bool) -> Self { diff --git a/iphone/Maps/Tests/Core/iCloudTests/MetadataItemStubs.swift b/iphone/Maps/Tests/Core/iCloudTests/MetadataItemStubs.swift index 38deb86a3..67f1bb279 100644 --- a/iphone/Maps/Tests/Core/iCloudTests/MetadataItemStubs.swift +++ b/iphone/Maps/Tests/Core/iCloudTests/MetadataItemStubs.swift @@ -12,13 +12,15 @@ extension LocalMetadataItem { } extension CloudMetadataItem { - static func stub(fileName: String, + static func stub(fileName: String, lastModificationDate: TimeInterval, isDownloaded: Bool = true, + percentDownloaded: NSNumber = 100.0, hasUnresolvedConflicts: Bool = false) -> CloudMetadataItem { let item = CloudMetadataItem(fileName: fileName, fileUrl: URL(string: "url")!, isDownloaded: isDownloaded, + percentDownloaded: percentDownloaded, lastModificationDate: lastModificationDate, downloadingError: nil, uploadingError: nil, diff --git a/iphone/Maps/Tests/Core/iCloudTests/SynchronizationStateManagerTests.swift b/iphone/Maps/Tests/Core/iCloudTests/SynchronizationStateManagerTests.swift index fbff8ab23..97167873d 100644 --- a/iphone/Maps/Tests/Core/iCloudTests/SynchronizationStateManagerTests.swift +++ b/iphone/Maps/Tests/Core/iCloudTests/SynchronizationStateManagerTests.swift @@ -103,7 +103,7 @@ final class SynchronizationtateManagerTests: XCTestCase { let localItem1 = LocalMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1)) let cloudItem1 = CloudMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(2)) - let cloudItem2 = CloudMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(3), isDownloaded: false) + let cloudItem2 = CloudMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(3), isDownloaded: false, percentDownloaded: 0.0) let cloudItem3 = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(4)) let localItems = LocalContents([localItem1]) @@ -530,7 +530,7 @@ final class SynchronizationtateManagerTests: XCTestCase { XCTAssertEqual(outgoingEvents.count, 0) - var cloudItem4 = CloudMetadataItem.stub(fileName: "file4", lastModificationDate: TimeInterval(3), isDownloaded: false) + var cloudItem4 = CloudMetadataItem.stub(fileName: "file4", lastModificationDate: TimeInterval(3), isDownloaded: false, percentDownloaded: 0.0) cloudItems.append(cloudItem4) var update = CloudContentsUpdate(added: [cloudItem4], updated: [], removed: []) outgoingEvents = syncStateManager.resolveEvent(.didUpdateCloudContents(contents: cloudItems, update: update)) @@ -544,8 +544,17 @@ final class SynchronizationtateManagerTests: XCTestCase { } } - cloudItem4.isDownloaded = true + cloudItem4.percentDownloaded = 50.0 + update = CloudContentsUpdate(added: [], updated: [cloudItem4], removed: []) + outgoingEvents = syncStateManager.resolveEvent(.didUpdateCloudContents(contents: cloudItems, update: update)) + XCTAssertEqual(outgoingEvents.count, 0) + cloudItem4.percentDownloaded = 100.0 + update = CloudContentsUpdate(added: [], updated: [cloudItem4], removed: []) + outgoingEvents = syncStateManager.resolveEvent(.didUpdateCloudContents(contents: cloudItems, update: update)) + XCTAssertEqual(outgoingEvents.count, 0) + + cloudItem4.isDownloaded = true // recreate collection cloudItems = [cloudItem1, cloudItem2, cloudItem3, cloudItem4] update = CloudContentsUpdate(added: [], updated: [cloudItem4], removed: []) @@ -562,4 +571,3 @@ final class SynchronizationtateManagerTests: XCTestCase { } } } -