diff --git a/Riot.xcodeproj/project.pbxproj b/Riot.xcodeproj/project.pbxproj index 5d27863ad..e3b76eae8 100644 --- a/Riot.xcodeproj/project.pbxproj +++ b/Riot.xcodeproj/project.pbxproj @@ -787,9 +787,10 @@ EC3B066A24AC6ADE000DF9BF /* CrossSigningSetupBannerCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC3B066624AC6ADD000DF9BF /* CrossSigningSetupBannerCell.xib */; }; EC3B066B24AC6ADE000DF9BF /* CrossSigningBannerPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3B066724AC6ADD000DF9BF /* CrossSigningBannerPreferences.swift */; }; EC3B066C24AC6ADE000DF9BF /* CrossSigningSetupBannerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3B066824AC6ADD000DF9BF /* CrossSigningSetupBannerCell.swift */; }; - EC45DB1725344B8A006911C1 /* MXSyncResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC45DB1525344B89006911C1 /* MXSyncResponse.swift */; }; EC45DB1825344B8A006911C1 /* SyncResponseStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC45DB1625344B89006911C1 /* SyncResponseStore.swift */; }; EC45DB1925344B8E006911C1 /* SyncResponseStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC45DB1625344B89006911C1 /* SyncResponseStore.swift */; }; + EC45DB992534969E006911C1 /* NSDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC45DB982534969E006911C1 /* NSDictionary.swift */; }; + EC45DB9A253499FE006911C1 /* NSDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC45DB982534969E006911C1 /* NSDictionary.swift */; }; EC49F5F92515016F003894A6 /* RoomInfoBasicViewData.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC49F5F82515016F003894A6 /* RoomInfoBasicViewData.swift */; }; EC51E78D250FC15000AAE7DB /* RoomCreationEventRowViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC51E78C250FC15000AAE7DB /* RoomCreationEventRowViewModel.swift */; }; EC51E7902510B7C700AAE7DB /* AutosizedTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC51E78F2510B7C700AAE7DB /* AutosizedTableView.swift */; }; @@ -2014,8 +2015,8 @@ EC3B066624AC6ADD000DF9BF /* CrossSigningSetupBannerCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CrossSigningSetupBannerCell.xib; sourceTree = ""; }; EC3B066724AC6ADD000DF9BF /* CrossSigningBannerPreferences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CrossSigningBannerPreferences.swift; sourceTree = ""; }; EC3B066824AC6ADD000DF9BF /* CrossSigningSetupBannerCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CrossSigningSetupBannerCell.swift; sourceTree = ""; }; - EC45DB1525344B89006911C1 /* MXSyncResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MXSyncResponse.swift; sourceTree = ""; }; EC45DB1625344B89006911C1 /* SyncResponseStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyncResponseStore.swift; sourceTree = ""; }; + EC45DB982534969E006911C1 /* NSDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSDictionary.swift; sourceTree = ""; }; EC49F5F82515016F003894A6 /* RoomInfoBasicViewData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomInfoBasicViewData.swift; sourceTree = ""; }; EC51E78C250FC15000AAE7DB /* RoomCreationEventRowViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomCreationEventRowViewModel.swift; sourceTree = ""; }; EC51E78F2510B7C700AAE7DB /* AutosizedTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutosizedTableView.swift; sourceTree = ""; }; @@ -5144,7 +5145,7 @@ EC85D74E2477E614002C44C9 /* RiotNSE.entitlements */, EC85D7452477E5F7002C44C9 /* NotificationService.swift */, EC85D756247E700F002C44C9 /* NSEMemoryStore.swift */, - EC45DB1525344B89006911C1 /* MXSyncResponse.swift */, + EC45DB982534969E006911C1 /* NSDictionary.swift */, EC45DB1625344B89006911C1 /* SyncResponseStore.swift */, EC85D7472477E5F7002C44C9 /* Info.plist */, EC1CA8D924D811B400DE9EBF /* NSE-Common.xcconfig */, @@ -6168,9 +6169,9 @@ EC31F0952521FC4600D407DA /* PinCodePreferences.swift in Sources */, 32FD757424D2BEF700BA7B37 /* InfoPlist.swift in Sources */, EC31F09C2524AE1400D407DA /* BiometricsAuthenticationPresenter.swift in Sources */, + EC45DB992534969E006911C1 /* NSDictionary.swift in Sources */, EC85D752247C0F52002C44C9 /* UNUserNotificationCenter.swift in Sources */, EC9A3EC724E1634100A8CFAE /* KeyValueStore.swift in Sources */, - EC45DB1725344B8A006911C1 /* MXSyncResponse.swift in Sources */, 32FD757A24D2C9BA00BA7B37 /* Bundle.swift in Sources */, EC31F0962521FC5300D407DA /* Strings.swift in Sources */, EC31F0972521FC6300D407DA /* Images.swift in Sources */, @@ -6734,6 +6735,7 @@ B1B558FA20EF768F00210D55 /* RoomMembershipBubbleCell.m in Sources */, B157FAA223264AE900EBFBD4 /* SettingsDiscoveryThreePidDetailsViewAction.swift in Sources */, EC85D6AE2477DC89002C44C9 /* RoundedButton.swift in Sources */, + EC45DB9A253499FE006911C1 /* NSDictionary.swift in Sources */, B1CE83D72422817200D07506 /* KeyVerificationVerifyByScanningViewModelType.swift in Sources */, 3232ABA1225730E100AD6A5C /* KeyVerificationCoordinatorType.swift in Sources */, B1C562D9228C0B760037F12A /* RoomContextualMenuItem.swift in Sources */, diff --git a/Riot/Modules/Application/LegacyAppDelegate.m b/Riot/Modules/Application/LegacyAppDelegate.m index ee3286608..149e11758 100644 --- a/Riot/Modules/Application/LegacyAppDelegate.m +++ b/Riot/Modules/Application/LegacyAppDelegate.m @@ -721,8 +721,9 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni { [account.mxSession handleSyncResponse:syncResponse]; } + [syncResponseStore deleteData]; // Do not resume for now, to test we've really fetched the events - [account resume]; +// [account resume]; } _isAppForeground = YES; diff --git a/RiotNSE/MXSyncResponse.swift b/RiotNSE/MXSyncResponse.swift deleted file mode 100644 index 2240b86fc..000000000 --- a/RiotNSE/MXSyncResponse.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright 2020 New Vector Ltd -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Foundation -import MatrixSDK - -extension MXSyncResponse { - - func update(with response: MXSyncResponse) { - // TODO: To be implemented - } - -} diff --git a/RiotNSE/NSDictionary.swift b/RiotNSE/NSDictionary.swift new file mode 100644 index 000000000..b0f220461 --- /dev/null +++ b/RiotNSE/NSDictionary.swift @@ -0,0 +1,55 @@ +// +// Copyright 2020 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +extension NSDictionary { + + public static func + (lhs: NSDictionary, rhs: NSDictionary) -> NSDictionary { + let dictionary = NSMutableDictionary(dictionary: lhs) + for (key, valueR) in rhs { + if let key = key as? NSCopying { + if let valueL = dictionary[key] { + switch (valueL, valueR) { + case (let dictionaryL as NSDictionary, let dictionaryR as NSDictionary): + dictionary[key] = dictionaryL + dictionaryR + break + case (let arrayL as NSArray, let arrayR as NSArray): + dictionary[key] = arrayL + arrayR + default: + dictionary[key] = valueR + } + } + else { + dictionary[key] = valueR + } + } + } + return dictionary + } + +} + +extension NSArray { + + public static func + (lhs: NSArray, rhs: NSArray) -> NSArray { + let array = NSMutableArray() + lhs.forEach { array.add($0) } + rhs.forEach { array.add($0) } + return array + } + +} diff --git a/RiotNSE/NotificationService.swift b/RiotNSE/NotificationService.swift index c720e9dc0..446f2c984 100644 --- a/RiotNSE/NotificationService.swift +++ b/RiotNSE/NotificationService.swift @@ -228,37 +228,13 @@ class NotificationService: UNNotificationServiceExtension { // handle encryption for this event handleEncryption(forEvent: event) - } else { + } else if allowSync { NSLog("[NotificationService] fetchEvent: We don't have the event in store. Launch a background sync to fetch it.") self.launchBackgroundSync(forEventId: eventId, roomId: roomId) + } else { + NSLog("[NotificationService] fetchEvent: We don't have the event in store. Do not sync anymore.") + self.fallbackToBestAttemptContent(forEventId: eventId) } -// -// // attempt to fetch the event -// mxSession.event(withEventId: eventId, inRoom: roomId, success: { [weak self] (event) in -// guard let self = self else { -// NSLog("[NotificationService] fetchEvent: MXSession.event method returned too late successfully.") -// return -// } -// -// guard let event = event else { -// NSLog("[NotificationService] fetchEvent: MXSession.event method returned successfully with no event.") -// self.fallbackToBestAttemptContent(forEventId: eventId) -// return -// } -// -// // cache this event -// self.cachedEvents[eventId] = event -// -// // handle encryption for this event -// handleEncryption(forEvent: event) -// }) { [weak self] (error) in -// guard let self = self else { -// NSLog("[NotificationService] fetchEvent: MXSession.event method returned too late with error: \(String(describing: error))") -// return -// } -// NSLog("[NotificationService] fetchEvent: MXSession.event method returned error: \(String(describing: error))") -// self.fallbackToBestAttemptContent(forEventId: eventId) -// } } } @@ -268,23 +244,18 @@ class NotificationService: UNNotificationServiceExtension { self.fallbackToBestAttemptContent(forEventId: eventId) return } - - // launch an initial background sync - mxSession.backgroundSync(withTimeout: 20, ignoreSessionState: true) { [weak self] (response) in + + // launch a background sync, set serverTimeout as 0.1 to avoid session to decide continue catching up + mxSession.backgroundSync(withTimeout: 20, serverTimeout: 0.1, ignoreSessionState: true) { [weak self] (response) in switch response { case .success(let syncResponse): guard let self = self else { NSLog("[NotificationService] launchBackgroundSync: MXSession.initialBackgroundSync returned too late successfully") return } - - if let oldSyncResponse = NotificationService.syncResponseStore?.syncResponse { - oldSyncResponse.update(with: syncResponse) - NotificationService.syncResponseStore?.syncResponse = oldSyncResponse - } else { - NotificationService.syncResponseStore?.syncResponse = syncResponse - } - + + NotificationService.syncResponseStore?.update(with: syncResponse) + // do not allow to sync anymore self.fetchEvent(withEventId: eventId, roomId: roomId, allowSync: false) break diff --git a/RiotNSE/SyncResponseStore.swift b/RiotNSE/SyncResponseStore.swift index d316baf8e..f3dbe0db3 100644 --- a/RiotNSE/SyncResponseStore.swift +++ b/RiotNSE/SyncResponseStore.swift @@ -18,7 +18,9 @@ import Foundation import MatrixSDK @objc protocol SyncResponseStore: NSObjectProtocol { - var syncResponse: MXSyncResponse? { get set } + var syncResponse: MXSyncResponse? { get } + func update(with response: MXSyncResponse?) + func deleteData() } @objcMembers @@ -96,11 +98,27 @@ class SyncResponseFileStore: NSObject { extension SyncResponseFileStore: SyncResponseStore { var syncResponse: MXSyncResponse? { - get { - return readSyncResponse() - } set { - saveSyncResponse(newValue) + return readSyncResponse() + } + + func update(with response: MXSyncResponse?) { + guard let response = response else { + // Return if no new response + return + } + if let syncResponse = syncResponse { + // current sync response exists, merge it with the new response + var dictionary = NSDictionary(dictionary: syncResponse.jsonDictionary()) + dictionary = dictionary + NSDictionary(dictionary: response.jsonDictionary()) + saveSyncResponse(MXSyncResponse(fromJSON: dictionary as? [AnyHashable : Any])) + } else { + // no current sync response, directly save the new one + saveSyncResponse(response) } } + func deleteData() { + saveSyncResponse(nil) + } + }