From c51f4fda5e58bdde625522b5958a40f7b5333960 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Mon, 3 Mar 2025 17:38:13 +1100 Subject: [PATCH 1/6] Fixed a number of bugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Added a 'requireAllRequestsSucceed' flag to the ConfigurationSyncJob (so it'll report a failure if any individual request fails) • Updated the 'unknownMessage' error to include some info about the data contained in the protobuf • Fixed an issue where the logger wasn't correctly respecting the log level settings • Fixed an issue where the path status indicator wouldn't default to unknown • Fixed an issue where the generic database error didn't replace the 'app_name' variable • Fixed an issue where a group could be partially created due to one of it's configs failing to be stored (we now consider that a failure so the user can try again) • Fixed an issue where the background pollers could get released before they finish polling • Fixed an issue where the community poller would only ever fetch the most recent 100 messages (instead of everything since the last poll) • Fixed an issue where we could incorrectly clear the app badge number in some cases • Fixed an issue where processing a config message in the BackgroundPoller could result in attempting to fetch from communities after the process completed • Fixed a crash where a database query could incorrectly be interrupted after it completed if both happened at just the right time --- Session/Meta/AppDelegate.swift | 27 +++++++----- SessionMessagingKit/Messages/Message.swift | 2 +- .../Errors/MessageReceiverError.swift | 43 +++++++++++++++++-- .../Sending & Receiving/MessageReceiver.swift | 4 +- .../NSENotificationPresenter.swift | 28 +++++++++--- .../NotificationServiceExtension.swift | 30 ++++++++++--- .../Models/SnodeRecursiveResponse.swift | 2 +- SessionSnodeKit/Types/BatchResponse.swift | 1 + SessionUtilitiesKit/Database/Storage.swift | 5 ++- 9 files changed, 110 insertions(+), 32 deletions(-) diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index 726e5bcd6..25b860eee 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -381,19 +381,18 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD // Ensure we haven't timed out yet guard timer.isCancelled == false else { return } - // Immediately cancel the timer to prevent the timeout being triggered - timer.cancel() - - // Update the unread count badge - let unreadCount: Int = dependencies[singleton: .storage] - .read { db in try Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) } - .defaulting(to: 0) - - DispatchQueue.main.async(using: dependencies) { + /// Update the app badge in case the unread count changed (but only if the database is valid and + /// not suspended) + if + dependencies[singleton: .storage].isValid && + !dependencies[singleton: .storage].isSuspended + { + let unreadCount: Int = dependencies[singleton: .storage] + .read { db in try Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) } + .defaulting(to: 0) UIApplication.shared.applicationIconBadgeNumber = unreadCount } - // If we are still running in the background then suspend the network & database if dependencies[singleton: .appContext].isInBackground { dependencies.mutate(cache: .libSessionNetwork) { $0.suspendNetworkAccess() } dependencies[singleton: .storage].suspendDatabaseAccess() @@ -784,7 +783,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD /// On application startup the `Storage.read` can be slightly slow while GRDB spins up it's database /// read pools (up to a few seconds), since this read is blocking we want to dispatch it to run async to ensure /// we don't block user interaction while it's running + /// + /// **Note:** Only do this if the database is still valid and not suspended (otherwise we will just reset the badge + /// number incorrectly) DispatchQueue.global(qos: .default).async { + guard + dependencies[singleton: .storage].isValid && + !dependencies[singleton: .storage].isSuspended + else { return } + let unreadCount: Int = dependencies[singleton: .storage] .read { db in try Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) } .defaulting(to: 0) diff --git a/SessionMessagingKit/Messages/Message.swift b/SessionMessagingKit/Messages/Message.swift index cba6af01a..8073ca13e 100644 --- a/SessionMessagingKit/Messages/Message.swift +++ b/SessionMessagingKit/Messages/Message.swift @@ -354,7 +354,7 @@ public extension Message { return variant.messageType.fromProto(proto, sender: sender, using: dependencies) } - return try decodedMessage ?? { throw MessageReceiverError.unknownMessage }() + return try decodedMessage ?? { throw MessageReceiverError.unknownMessage(proto) }() } static func requiresExistingConversation(message: Message, threadVariant: SessionThread.Variant) -> Bool { diff --git a/SessionMessagingKit/Sending & Receiving/Errors/MessageReceiverError.swift b/SessionMessagingKit/Sending & Receiving/Errors/MessageReceiverError.swift index aa6376066..f4fbc0708 100644 --- a/SessionMessagingKit/Sending & Receiving/Errors/MessageReceiverError.swift +++ b/SessionMessagingKit/Sending & Receiving/Errors/MessageReceiverError.swift @@ -4,13 +4,13 @@ import Foundation -public enum MessageReceiverError: LocalizedError { +public enum MessageReceiverError: Error, CustomStringConvertible { case duplicateMessage case duplicateMessageNewSnode case duplicateControlMessage case invalidMessage case invalidSender - case unknownMessage + case unknownMessage(SNProtoContent?) case unknownEnvelopeType case noUserX25519KeyPair case noUserED25519KeyPair @@ -55,14 +55,49 @@ public enum MessageReceiverError: LocalizedError { } } - public var errorDescription: String? { + public var description: String { switch self { case .duplicateMessage: return "Duplicate message." case .duplicateMessageNewSnode: return "Duplicate message from different service node." case .duplicateControlMessage: return "Duplicate control message." case .invalidMessage: return "Invalid message." case .invalidSender: return "Invalid sender." - case .unknownMessage: return "Unknown message type." + case .unknownMessage(let content): + switch content { + case .none: return "Unknown message type (no content)." + case .some(let content): + let protoInfo: [(String, Bool)] = [ + ("hasDataMessage", (content.dataMessage != nil)), + ("hasProfile", (content.dataMessage?.profile != nil)), + ("hasBody", (content.dataMessage?.hasBody == true)), + ("hasAttachments", (content.dataMessage?.attachments.isEmpty == false)), + ("hasReaction", (content.dataMessage?.reaction != nil)), + ("hasQuote", (content.dataMessage?.quote != nil)), + ("hasLinkPreview", (content.dataMessage?.preview != nil)), + ("hasOpenGroupInvitation", (content.dataMessage?.openGroupInvitation != nil)), + ("hasLegacyGroupControlMessage", (content.dataMessage?.closedGroupControlMessage != nil)), + ("hasGroupV2ControlMessage", (content.dataMessage?.groupUpdateMessage != nil)), + ("hasTimestamp", (content.dataMessage?.hasTimestamp == true)), + ("hasSyncTarget", (content.dataMessage?.hasSyncTarget == true)), + ("hasBlocksCommunityMessageRequests", (content.dataMessage?.hasBlocksCommunityMessageRequests == true)), + ("hasCallMessage", (content.callMessage != nil)), + ("hasReceiptMessage", (content.receiptMessage != nil)), + ("hasTypingMessage", (content.typingMessage != nil)), + ("hasDataExtractionMessage", (content.dataExtractionNotification != nil)), + ("hasUnsendRequest", (content.unsendRequest != nil)), + ("hasMessageRequestResponse", (content.messageRequestResponse != nil)), + ("hasExpirationTimer", (content.hasExpirationTimer == true)), + ("hasExpirationType", (content.hasExpirationType == true)), + ("hasSigTimestamp", (content.hasSigTimestamp == true)) + ] + + let protoInfoString: String = protoInfo + .filter { _, val in val } + .map { name, _ in name } + .joined(separator: ", ") + return "Unknown message type (\(protoInfoString))." + } + case .unknownEnvelopeType: return "Unknown envelope type." case .noUserX25519KeyPair: return "Couldn't find user X25519 key pair." case .noUserED25519KeyPair: return "Couldn't find user ED25519 key pair." diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift index cf1eef906..a7dd2e1fa 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift @@ -234,7 +234,7 @@ public enum MessageReceiver { case .all, .unknown: Log.warn(.messageReceiver, "Couldn't process message due to invalid namespace.") - throw MessageReceiverError.unknownMessage + throw MessageReceiverError.unknownMessage(nil) } } @@ -440,7 +440,7 @@ public enum MessageReceiver { using: dependencies ) - default: throw MessageReceiverError.unknownMessage + default: throw MessageReceiverError.unknownMessage(proto) } // Perform any required post-handling logic diff --git a/SessionNotificationServiceExtension/NSENotificationPresenter.swift b/SessionNotificationServiceExtension/NSENotificationPresenter.swift index 94f820907..cbd389b16 100644 --- a/SessionNotificationServiceExtension/NSENotificationPresenter.swift +++ b/SessionNotificationServiceExtension/NSENotificationPresenter.swift @@ -89,9 +89,17 @@ public class NSENotificationPresenter: NotificationsManagerType { notificationContent.sound = thread.notificationSound .defaulting(to: db[.defaultNotificationSound] ?? Preferences.Sound.defaultNotificationSound) .notificationSound(isQuiet: false) - notificationContent.badge = (try? Interaction.fetchAppBadgeUnreadCount(db, using: dependencies)) - .map { NSNumber(value: $0) } - .defaulting(to: NSNumber(value: 0)) + + /// Update the app badge in case the unread count changed (but only if the database is valid and + /// not suspended) + if + dependencies[singleton: .storage].isValid && + !dependencies[singleton: .storage].isSuspended + { + notificationContent.badge = (try? Interaction.fetchAppBadgeUnreadCount(db, using: dependencies)) + .map { NSNumber(value: $0) } + .defaulting(to: NSNumber(value: 0)) + } // Title & body let previewType: Preferences.NotificationPreviewType = db[.preferencesNotificationPreviewType] @@ -198,9 +206,17 @@ public class NSENotificationPresenter: NotificationsManagerType { notificationContent.sound = thread.notificationSound .defaulting(to: db[.defaultNotificationSound] ?? Preferences.Sound.defaultNotificationSound) .notificationSound(isQuiet: false) - notificationContent.badge = (try? Interaction.fetchAppBadgeUnreadCount(db, using: dependencies)) - .map { NSNumber(value: $0) } - .defaulting(to: NSNumber(value: 0)) + + /// Update the app badge in case the unread count changed (but only if the database is valid and + /// not suspended) + if + dependencies[singleton: .storage].isValid && + !dependencies[singleton: .storage].isSuspended + { + notificationContent.badge = (try? Interaction.fetchAppBadgeUnreadCount(db, using: dependencies)) + .map { NSNumber(value: $0) } + .defaulting(to: NSNumber(value: 0)) + } notificationContent.title = Constants.app_name notificationContent.body = "" diff --git a/SessionNotificationServiceExtension/NotificationServiceExtension.swift b/SessionNotificationServiceExtension/NotificationServiceExtension.swift index 759182def..44575f94e 100644 --- a/SessionNotificationServiceExtension/NotificationServiceExtension.swift +++ b/SessionNotificationServiceExtension/NotificationServiceExtension.swift @@ -478,10 +478,18 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension switch resolution { case .ignoreDueToMainAppRunning: break default: - silentContent.badge = dependencies[singleton: .storage] - .read { [dependencies] db in try Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) } - .map { NSNumber(value: $0) } - .defaulting(to: NSNumber(value: 0)) + /// Update the app badge in case the unread count changed (but only if the database is valid and + /// not suspended) + if + dependencies[singleton: .storage].isValid && + !dependencies[singleton: .storage].isSuspended + { + silentContent.badge = dependencies[singleton: .storage] + .read { [dependencies] db in try Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) } + .map { NSNumber(value: $0) } + .defaulting(to: NSNumber(value: 0)) + } + dependencies[singleton: .storage].suspendDatabaseAccess() } @@ -538,9 +546,17 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension let notificationContent = UNMutableNotificationContent() notificationContent.userInfo = [ NotificationServiceExtension.isFromRemoteKey : true ] notificationContent.title = Constants.app_name - notificationContent.badge = (try? Interaction.fetchAppBadgeUnreadCount(db, using: dependencies)) - .map { NSNumber(value: $0) } - .defaulting(to: NSNumber(value: 0)) + + /// Update the app badge in case the unread count changed (but only if the database is valid and + /// not suspended) + if + dependencies[singleton: .storage].isValid && + !dependencies[singleton: .storage].isSuspended + { + notificationContent.badge = (try? Interaction.fetchAppBadgeUnreadCount(db, using: dependencies)) + .map { NSNumber(value: $0) } + .defaulting(to: NSNumber(value: 0)) + } if let sender: String = callMessage.sender { let senderDisplayName: String = Profile.displayName(db, id: sender, threadVariant: .contact, using: dependencies) diff --git a/SessionSnodeKit/Models/SnodeRecursiveResponse.swift b/SessionSnodeKit/Models/SnodeRecursiveResponse.swift index 91e2d2616..fdb729744 100644 --- a/SessionSnodeKit/Models/SnodeRecursiveResponse.swift +++ b/SessionSnodeKit/Models/SnodeRecursiveResponse.swift @@ -7,7 +7,7 @@ public class SnodeRecursiveResponse: SnodeResponse { case swarm } - internal let swarm: [String: T] + public let swarm: [String: T] // MARK: - Initialization diff --git a/SessionSnodeKit/Types/BatchResponse.swift b/SessionSnodeKit/Types/BatchResponse.swift index cc2919571..e9af2affd 100644 --- a/SessionSnodeKit/Types/BatchResponse.swift +++ b/SessionSnodeKit/Types/BatchResponse.swift @@ -150,6 +150,7 @@ extension Network.BatchSubResponse: Decodable { // MARK: - ErasedBatchSubResponse public protocol ErasedBatchSubResponse: ResponseInfoType { + var code: Int { get } var erasedBody: Any? { get } var failedToParseBody: Bool { get } } diff --git a/SessionUtilitiesKit/Database/Storage.swift b/SessionUtilitiesKit/Database/Storage.swift index 8a2da7c24..f1734bf6f 100644 --- a/SessionUtilitiesKit/Database/Storage.swift +++ b/SessionUtilitiesKit/Database/Storage.swift @@ -578,7 +578,10 @@ open class Storage { switch error { case DatabaseError.SQLITE_ABORT, DatabaseError.SQLITE_INTERRUPT, DatabaseError.SQLITE_ERROR: let message: String = ((error as? DatabaseError)?.message ?? "Unknown") - Log.error(.storage, "Database \(action) failed due to error: \(message) - [ \(info.callInfo) ]") + Log.error(.storage, "Database \(action) failed due to error: \(message)") + + case StorageError.databaseInvalid: + Log.error(.storage, "Database \(action) failed as the database is invalid.") case StorageError.databaseInvalid: Log.error(.storage, "Database \(action) failed as the database is invalid - [ \(info.callInfo) ]") From 9ed91f2eeba946a310db53bf4d0a11befcdb8b7e Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Mon, 24 Mar 2025 09:52:47 +1100 Subject: [PATCH 2/6] Update the badge icon number on the main thread --- Session/Meta/AppDelegate.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index 25b860eee..f677ca9fb 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -390,9 +390,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD let unreadCount: Int = dependencies[singleton: .storage] .read { db in try Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) } .defaulting(to: 0) - UIApplication.shared.applicationIconBadgeNumber = unreadCount + + DispatchQueue.main.async(using: dependencies) { + UIApplication.shared.applicationIconBadgeNumber = unreadCount + } } + // If we are still running in the background then suspend the network & database if dependencies[singleton: .appContext].isInBackground { dependencies.mutate(cache: .libSessionNetwork) { $0.suspendNetworkAccess() } dependencies[singleton: .storage].suspendDatabaseAccess() From f8863a12a104fc8b10d9c9acabecb73735a275dd Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Mon, 24 Mar 2025 10:11:29 +1100 Subject: [PATCH 3/6] Tweaked unread count logic, reverted another change --- Session/Meta/AppDelegate.swift | 21 ++++++---------- .../NSENotificationPresenter.swift | 24 +++++------------- .../NotificationServiceExtension.swift | 25 ++++++------------- .../Models/SnodeRecursiveResponse.swift | 2 +- 4 files changed, 22 insertions(+), 50 deletions(-) diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index f677ca9fb..15dac97e8 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -381,16 +381,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD // Ensure we haven't timed out yet guard timer.isCancelled == false else { return } - /// Update the app badge in case the unread count changed (but only if the database is valid and - /// not suspended) + /// Update the app badge in case the unread count changed if - dependencies[singleton: .storage].isValid && - !dependencies[singleton: .storage].isSuspended + let unreadCount: Int = dependencies[singleton: .storage].read({ db in + try Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) + }) { - let unreadCount: Int = dependencies[singleton: .storage] - .read { db in try Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) } - .defaulting(to: 0) - DispatchQueue.main.async(using: dependencies) { UIApplication.shared.applicationIconBadgeNumber = unreadCount } @@ -792,14 +788,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD /// number incorrectly) DispatchQueue.global(qos: .default).async { guard - dependencies[singleton: .storage].isValid && - !dependencies[singleton: .storage].isSuspended + let unreadCount: Int = dependencies[singleton: .storage].read({ db in try + Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) + }) else { return } - let unreadCount: Int = dependencies[singleton: .storage] - .read { db in try Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) } - .defaulting(to: 0) - DispatchQueue.main.async(using: dependencies) { UIApplication.shared.applicationIconBadgeNumber = unreadCount } diff --git a/SessionNotificationServiceExtension/NSENotificationPresenter.swift b/SessionNotificationServiceExtension/NSENotificationPresenter.swift index cbd389b16..f0741a19c 100644 --- a/SessionNotificationServiceExtension/NSENotificationPresenter.swift +++ b/SessionNotificationServiceExtension/NSENotificationPresenter.swift @@ -90,15 +90,9 @@ public class NSENotificationPresenter: NotificationsManagerType { .defaulting(to: db[.defaultNotificationSound] ?? Preferences.Sound.defaultNotificationSound) .notificationSound(isQuiet: false) - /// Update the app badge in case the unread count changed (but only if the database is valid and - /// not suspended) - if - dependencies[singleton: .storage].isValid && - !dependencies[singleton: .storage].isSuspended - { - notificationContent.badge = (try? Interaction.fetchAppBadgeUnreadCount(db, using: dependencies)) - .map { NSNumber(value: $0) } - .defaulting(to: NSNumber(value: 0)) + /// Update the app badge in case the unread count changed + if let unreadCount: Int = try? Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) { + notificationContent.badge = NSNumber(value: unreadCount) } // Title & body @@ -207,15 +201,9 @@ public class NSENotificationPresenter: NotificationsManagerType { .defaulting(to: db[.defaultNotificationSound] ?? Preferences.Sound.defaultNotificationSound) .notificationSound(isQuiet: false) - /// Update the app badge in case the unread count changed (but only if the database is valid and - /// not suspended) - if - dependencies[singleton: .storage].isValid && - !dependencies[singleton: .storage].isSuspended - { - notificationContent.badge = (try? Interaction.fetchAppBadgeUnreadCount(db, using: dependencies)) - .map { NSNumber(value: $0) } - .defaulting(to: NSNumber(value: 0)) + /// Update the app badge in case the unread count changed + if let unreadCount: Int = try? Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) { + notificationContent.badge = NSNumber(value: unreadCount) } notificationContent.title = Constants.app_name diff --git a/SessionNotificationServiceExtension/NotificationServiceExtension.swift b/SessionNotificationServiceExtension/NotificationServiceExtension.swift index 44575f94e..f15e149d7 100644 --- a/SessionNotificationServiceExtension/NotificationServiceExtension.swift +++ b/SessionNotificationServiceExtension/NotificationServiceExtension.swift @@ -478,16 +478,13 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension switch resolution { case .ignoreDueToMainAppRunning: break default: - /// Update the app badge in case the unread count changed (but only if the database is valid and - /// not suspended) + /// Update the app badge in case the unread count changed if - dependencies[singleton: .storage].isValid && - !dependencies[singleton: .storage].isSuspended + let unreadCount: Int = dependencies[singleton: .storage].read({ [dependencies] db in + try Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) + }) { - silentContent.badge = dependencies[singleton: .storage] - .read { [dependencies] db in try Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) } - .map { NSNumber(value: $0) } - .defaulting(to: NSNumber(value: 0)) + silentContent.badge = NSNumber(value: unreadCount) } dependencies[singleton: .storage].suspendDatabaseAccess() @@ -547,15 +544,9 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension notificationContent.userInfo = [ NotificationServiceExtension.isFromRemoteKey : true ] notificationContent.title = Constants.app_name - /// Update the app badge in case the unread count changed (but only if the database is valid and - /// not suspended) - if - dependencies[singleton: .storage].isValid && - !dependencies[singleton: .storage].isSuspended - { - notificationContent.badge = (try? Interaction.fetchAppBadgeUnreadCount(db, using: dependencies)) - .map { NSNumber(value: $0) } - .defaulting(to: NSNumber(value: 0)) + /// Update the app badge in case the unread count changed + if let unreadCount: Int = try? Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) { + notificationContent.badge = NSNumber(value: unreadCount) } if let sender: String = callMessage.sender { diff --git a/SessionSnodeKit/Models/SnodeRecursiveResponse.swift b/SessionSnodeKit/Models/SnodeRecursiveResponse.swift index fdb729744..91e2d2616 100644 --- a/SessionSnodeKit/Models/SnodeRecursiveResponse.swift +++ b/SessionSnodeKit/Models/SnodeRecursiveResponse.swift @@ -7,7 +7,7 @@ public class SnodeRecursiveResponse: SnodeResponse { case swarm } - public let swarm: [String: T] + internal let swarm: [String: T] // MARK: - Initialization From 990e63db53779bf8433b58ce8a470c51afb72957 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Mon, 24 Mar 2025 10:12:37 +1100 Subject: [PATCH 4/6] Revert an unintended change --- Session/Meta/AppDelegate.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index 15dac97e8..0dfefa7c5 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -381,7 +381,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD // Ensure we haven't timed out yet guard timer.isCancelled == false else { return } - /// Update the app badge in case the unread count changed + // Immediately cancel the timer to prevent the timeout being triggered + timer.cancel() + + // Update the app badge in case the unread count changed if let unreadCount: Int = dependencies[singleton: .storage].read({ db in try Interaction.fetchAppBadgeUnreadCount(db, using: dependencies) From 9d79181d3d526435c4462d081f04ac0a67cef98c Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Mon, 24 Mar 2025 10:18:41 +1100 Subject: [PATCH 5/6] Removed an unneeded comment --- Session/Meta/AppDelegate.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index 0dfefa7c5..790061d03 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -786,9 +786,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD /// On application startup the `Storage.read` can be slightly slow while GRDB spins up it's database /// read pools (up to a few seconds), since this read is blocking we want to dispatch it to run async to ensure /// we don't block user interaction while it's running - /// - /// **Note:** Only do this if the database is still valid and not suspended (otherwise we will just reset the badge - /// number incorrectly) DispatchQueue.global(qos: .default).async { guard let unreadCount: Int = dependencies[singleton: .storage].read({ db in try From dbb5bf5bb182717a2c070baa39d9309e735b42d5 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Thu, 3 Apr 2025 15:48:02 +1100 Subject: [PATCH 6/6] Updated to latest libSession and updated build/version numbers --- Session.xcodeproj/project.pbxproj | 36 ++++++++----------- .../xcshareddata/swiftpm/Package.resolved | 4 +-- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 95784c316..4caedb50a 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -801,13 +801,13 @@ FD848B9628422A2A000E298B /* MessageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD848B86283B844B000E298B /* MessageViewModel.swift */; }; FD848B9828422F1A000E298B /* Date+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD848B9728422F1A000E298B /* Date+Utilities.swift */; }; FD848B9A28442CE6000E298B /* StorageError.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD848B9928442CE6000E298B /* StorageError.swift */; }; - FD860CBC2D6E7A9F00BBE29C /* _024_FixBustedInteractionVariant.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD860CBB2D6E7A9400BBE29C /* _024_FixBustedInteractionVariant.swift */; }; - FD860CBE2D6E7DAA00BBE29C /* DeveloperSettingsViewModel+Testing.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD860CBD2D6E7DA000BBE29C /* DeveloperSettingsViewModel+Testing.swift */; }; - FD860CC92D6ED2ED00BBE29C /* DifferenceKit in Frameworks */ = {isa = PBXBuildFile; productRef = FD860CC82D6ED2ED00BBE29C /* DifferenceKit */; }; FD860CB42D668FD300BBE29C /* AppearanceViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD860CB32D668FD000BBE29C /* AppearanceViewModel.swift */; }; FD860CB62D66913F00BBE29C /* ThemePreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD860CB52D66913B00BBE29C /* ThemePreviewView.swift */; }; FD860CB82D66BC9900BBE29C /* AppIconViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD860CB72D66BC9500BBE29C /* AppIconViewModel.swift */; }; FD860CBA2D66BF2A00BBE29C /* AppIconGridView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD860CB92D66BF2300BBE29C /* AppIconGridView.swift */; }; + FD860CBC2D6E7A9F00BBE29C /* _024_FixBustedInteractionVariant.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD860CBB2D6E7A9400BBE29C /* _024_FixBustedInteractionVariant.swift */; }; + FD860CBE2D6E7DAA00BBE29C /* DeveloperSettingsViewModel+Testing.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD860CBD2D6E7DA000BBE29C /* DeveloperSettingsViewModel+Testing.swift */; }; + FD860CC92D6ED2ED00BBE29C /* DifferenceKit in Frameworks */ = {isa = PBXBuildFile; productRef = FD860CC82D6ED2ED00BBE29C /* DifferenceKit */; }; FD86FDA32BC5020600EC251B /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = FD86FDA22BC5020600EC251B /* PrivacyInfo.xcprivacy */; }; FD86FDA42BC51C5400EC251B /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = FD86FDA22BC5020600EC251B /* PrivacyInfo.xcprivacy */; }; FD86FDA52BC51C5500EC251B /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = FD86FDA22BC5020600EC251B /* PrivacyInfo.xcprivacy */; }; @@ -1990,12 +1990,12 @@ FD859EEF27BF207700510D0C /* SessionProtos.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = SessionProtos.proto; sourceTree = ""; }; FD859EF027BF207C00510D0C /* WebSocketResources.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = WebSocketResources.proto; sourceTree = ""; }; FD859EF127BF6BA200510D0C /* Data+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+Utilities.swift"; sourceTree = ""; }; - FD860CBB2D6E7A9400BBE29C /* _024_FixBustedInteractionVariant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _024_FixBustedInteractionVariant.swift; sourceTree = ""; }; - FD860CBD2D6E7DA000BBE29C /* DeveloperSettingsViewModel+Testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DeveloperSettingsViewModel+Testing.swift"; sourceTree = ""; }; FD860CB32D668FD000BBE29C /* AppearanceViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceViewModel.swift; sourceTree = ""; }; FD860CB52D66913B00BBE29C /* ThemePreviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemePreviewView.swift; sourceTree = ""; }; FD860CB72D66BC9500BBE29C /* AppIconViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIconViewModel.swift; sourceTree = ""; }; FD860CB92D66BF2300BBE29C /* AppIconGridView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIconGridView.swift; sourceTree = ""; }; + FD860CBB2D6E7A9400BBE29C /* _024_FixBustedInteractionVariant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _024_FixBustedInteractionVariant.swift; sourceTree = ""; }; + FD860CBD2D6E7DA000BBE29C /* DeveloperSettingsViewModel+Testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DeveloperSettingsViewModel+Testing.swift"; sourceTree = ""; }; FD86FDA22BC5020600EC251B /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; FD87DCF928B74DB300AF0F98 /* ConversationSettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationSettingsViewModel.swift; sourceTree = ""; }; FD87DCFD28B7582C00AF0F98 /* BlockedContactsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedContactsViewModel.swift; sourceTree = ""; }; @@ -6887,7 +6887,6 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.9.1; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -6957,7 +6956,6 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.9.1; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -7008,7 +7006,6 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.9.1; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension"; @@ -7081,7 +7078,6 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.9.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension"; @@ -7814,7 +7810,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; COMPILE_LIB_SESSION = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 563; + CURRENT_PROJECT_VERSION = 567; ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -7854,7 +7850,7 @@ HEADER_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)/include/**"; IPHONEOS_DEPLOYMENT_TARGET = 15.6; LIB_SESSION_SOURCE_DIR = "${SRCROOT}/../LibSession-Util"; - MARKETING_VERSION = 2.9.2; + MARKETING_VERSION = 2.10.0; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = "-Werror=protocol"; OTHER_SWIFT_FLAGS = "-D DEBUG -Xfrontend -warn-long-expression-type-checking=100"; @@ -7894,7 +7890,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Distribution"; COMPILE_LIB_SESSION = ""; - CURRENT_PROJECT_VERSION = 563; + CURRENT_PROJECT_VERSION = 567; ENABLE_BITCODE = NO; ENABLE_MODULE_VERIFIER = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -7929,7 +7925,7 @@ HEADER_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)/include/**"; IPHONEOS_DEPLOYMENT_TARGET = 15.6; LIB_SESSION_SOURCE_DIR = "${SRCROOT}/../LibSession-Util"; - MARKETING_VERSION = 2.9.2; + MARKETING_VERSION = 2.10.0; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = ( "-DNS_BLOCK_ASSERTIONS=1", @@ -7959,7 +7955,6 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 566; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -8024,7 +8019,6 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 566; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -8419,7 +8413,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; COMPILE_LIB_SESSION = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 563; + CURRENT_PROJECT_VERSION = 567; ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -8461,7 +8455,7 @@ ); IPHONEOS_DEPLOYMENT_TARGET = 15.6; LIB_SESSION_SOURCE_DIR = "${SRCROOT}/../LibSession-Util"; - MARKETING_VERSION = 2.9.2; + MARKETING_VERSION = 2.10.0; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = ( "-fobjc-arc-exceptions", @@ -8490,7 +8484,6 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 488; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -9058,7 +9051,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Distribution"; COMPILE_LIB_SESSION = YES; - CURRENT_PROJECT_VERSION = 563; + CURRENT_PROJECT_VERSION = 567; ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -9094,7 +9087,7 @@ ); IPHONEOS_DEPLOYMENT_TARGET = 15.6; LIB_SESSION_SOURCE_DIR = "${SRCROOT}/../LibSession-Util"; - MARKETING_VERSION = 2.9.2; + MARKETING_VERSION = 2.10.0; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = ( "-DNS_BLOCK_ASSERTIONS=1", @@ -9122,7 +9115,6 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 488; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -10063,7 +10055,7 @@ repositoryURL = "https://github.com/session-foundation/libsession-util-spm"; requirement = { kind = exactVersion; - version = 1.2.1; + version = 1.3.0; }; }; FD6A38E72C2A630E00762359 /* XCRemoteSwiftPackageReference "CocoaLumberjack" */ = { diff --git a/Session.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Session.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index bf1dbacc9..8d90dc6d3 100644 --- a/Session.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Session.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -51,8 +51,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/session-foundation/libsession-util-spm", "state" : { - "revision" : "dfa9ad8df694cde779323ffcd9c2426d71eb6bdc", - "version" : "1.2.1" + "revision" : "51580552aef35e52a3ae99ec72df2d70026ef415", + "version" : "1.3.0" } }, {