Cleaned up some config sync logic and allowed migrations to trigger them
Updated the migrations so they can specify whether a configuration sync is required Moved the config sync logic into a MessageSender extension (makes far more sense than AppDelegate) Fixed a bug where the ShareVC was triggering the 'versionMigrationsDidComplete' twice Removed a couple of imports for files that had been deleted
This commit is contained in:
parent
78c0d000be
commit
5bb3bd7bc1
|
@ -622,7 +622,7 @@ NSString *const kOWSBackup_ImportDatabaseKeySpec = @"kOWSBackup_ImportDatabaseKe
|
|||
// complete, they'll be run the next time the app launches.
|
||||
AnyPromise *promise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[[OWSDatabaseMigrationRunner alloc] init] runAllOutstandingWithCompletion:^{
|
||||
[[[OWSDatabaseMigrationRunner alloc] init] runAllOutstandingWithCompletion:^(BOOL successful, BOOL needsConfigSync){
|
||||
resolve(@(1));
|
||||
}];
|
||||
});
|
||||
|
|
|
@ -174,8 +174,7 @@ final class NewClosedGroupVC : BaseVC, UITableViewDataSource, UITableViewDelegat
|
|||
promise = MessageSender.createClosedGroup(name: name, members: selectedContacts, transaction: transaction)
|
||||
}
|
||||
let _ = promise.done(on: DispatchQueue.main) { thread in
|
||||
let appDelegate = UIApplication.shared.delegate as! AppDelegate
|
||||
appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete() // FIXME: It's probably cleaner to do this inside createClosedGroup(...)
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
|
||||
self?.presentingViewController?.dismiss(animated: true, completion: nil)
|
||||
SignalApp.shared().presentConversation(for: thread, action: .compose, animated: false)
|
||||
}
|
||||
|
|
|
@ -54,11 +54,7 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
|
|||
Storage.shared.setContact(contact, using: transaction)
|
||||
},
|
||||
completion: {
|
||||
DispatchQueue.main.async {
|
||||
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
|
||||
appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete()
|
||||
}
|
||||
}
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -1188,9 +1184,7 @@ extension ConversationVC {
|
|||
}
|
||||
|
||||
// Send a sync message with the details of the contact
|
||||
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
|
||||
appDelegate.forceSyncConfigurationNowIfNeeded(with: transaction).retainUntilComplete()
|
||||
}
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1254,11 +1248,9 @@ extension ConversationVC {
|
|||
},
|
||||
completion: { [weak self] in
|
||||
// Force a config sync and pop to the previous screen (both must run on the main thread)
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
|
||||
|
||||
DispatchQueue.main.async {
|
||||
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
|
||||
appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete()
|
||||
}
|
||||
|
||||
self?.navigationController?.popViewController(animated: true)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -883,10 +883,7 @@ CGFloat kIconViewLength = 24;
|
|||
|
||||
// If we successfully blocked then force a config sync
|
||||
if (isBlocked) {
|
||||
if ([[UIApplication sharedApplication].delegate isKindOfClass:[AppDelegate class]]) {
|
||||
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
|
||||
[appDelegate forceSyncConfigurationNowIfNeeded];
|
||||
}
|
||||
[SNMessageSender forceSyncConfigurationNow];
|
||||
}
|
||||
|
||||
[weakSelf updateTableContents];
|
||||
|
@ -905,10 +902,7 @@ CGFloat kIconViewLength = 24;
|
|||
|
||||
// If we successfully unblocked then force a config sync
|
||||
if (!isBlocked) {
|
||||
if ([[UIApplication sharedApplication].delegate isKindOfClass:[AppDelegate class]]) {
|
||||
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
|
||||
[appDelegate forceSyncConfigurationNowIfNeeded];
|
||||
}
|
||||
[SNMessageSender forceSyncConfigurationNow];
|
||||
}
|
||||
|
||||
[weakSelf updateTableContents];
|
||||
|
|
|
@ -75,11 +75,7 @@ final class BlockedModal : Modal {
|
|||
Storage.shared.setContact(contact, using: transaction)
|
||||
},
|
||||
completion: {
|
||||
DispatchQueue.main.async {
|
||||
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
|
||||
appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete()
|
||||
}
|
||||
}
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -72,8 +72,7 @@ final class JoinOpenGroupModal : Modal {
|
|||
Storage.shared.write { [presentingViewController = self.presentingViewController!] transaction in
|
||||
OpenGroupManagerV2.shared.add(room: room, server: server, publicKey: publicKey, using: transaction)
|
||||
.done(on: DispatchQueue.main) { _ in
|
||||
let appDelegate = UIApplication.shared.delegate as! AppDelegate
|
||||
appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete() // FIXME: It's probably cleaner to do this inside addOpenGroup(...)
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete() // FIXME: It's probably cleaner to do this inside addOpenGroup(...)
|
||||
}
|
||||
.catch(on: DispatchQueue.main) { error in
|
||||
let alert = UIAlertController(title: "Couldn't Join", message: error.localizedDescription, preferredStyle: .alert)
|
||||
|
|
|
@ -521,11 +521,9 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv
|
|||
completion: {
|
||||
DispatchQueue.main.async {
|
||||
tableView.reloadRows(at: [ indexPath ], with: UITableView.RowAnimation.fade)
|
||||
|
||||
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
|
||||
appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete()
|
||||
}
|
||||
}
|
||||
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -543,11 +541,9 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv
|
|||
completion: {
|
||||
DispatchQueue.main.async {
|
||||
tableView.reloadRows(at: [ indexPath ], with: UITableView.RowAnimation.fade)
|
||||
|
||||
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
|
||||
appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete()
|
||||
}
|
||||
}
|
||||
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -362,13 +362,9 @@ class MessageRequestsViewController: BaseVC, UITableViewDelegate, UITableViewDat
|
|||
}
|
||||
},
|
||||
completion: {
|
||||
// Force a config sync (must run on the main thread)
|
||||
// Force a config sync
|
||||
if needsSync {
|
||||
DispatchQueue.main.async {
|
||||
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
|
||||
appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete()
|
||||
}
|
||||
}
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -398,12 +394,8 @@ class MessageRequestsViewController: BaseVC, UITableViewDelegate, UITableViewDat
|
|||
}
|
||||
},
|
||||
completion: {
|
||||
// Force a config sync (must run on the main thread)
|
||||
DispatchQueue.main.async {
|
||||
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
|
||||
appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete()
|
||||
}
|
||||
}
|
||||
// Force a config sync
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
|
|
@ -173,10 +173,10 @@ static NSTimeInterval launchStartedAt;
|
|||
[AppEnvironment.shared setup];
|
||||
[SignalApp.sharedApp setup];
|
||||
}
|
||||
migrationCompletion:^{
|
||||
migrationCompletion:^(BOOL successful, BOOL needsConfigSync){
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
[self versionMigrationsDidComplete];
|
||||
[self versionMigrationsDidCompleteNeedingConfigSync:needsConfigSync];
|
||||
}];
|
||||
|
||||
[SNConfiguration performMainSetup];
|
||||
|
@ -411,11 +411,16 @@ static NSTimeInterval launchStartedAt;
|
|||
}
|
||||
}
|
||||
|
||||
- (void)versionMigrationsDidComplete
|
||||
- (void)versionMigrationsDidCompleteNeedingConfigSync:(BOOL)needsConfigSync
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
self.areVersionMigrationsComplete = YES;
|
||||
|
||||
// If we need a config sync then trigger it now
|
||||
if (needsConfigSync) {
|
||||
[SNMessageSender forceSyncConfigurationNow];
|
||||
}
|
||||
|
||||
[self checkIfAppIsReady];
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import PromiseKit
|
||||
import SessionMessagingKit
|
||||
|
||||
extension AppDelegate {
|
||||
|
||||
|
@ -7,36 +8,17 @@ extension AppDelegate {
|
|||
guard Storage.shared.getUser()?.name != nil else { return }
|
||||
let userDefaults = UserDefaults.standard
|
||||
let lastSync = userDefaults[.lastConfigurationSync] ?? .distantPast
|
||||
guard Date().timeIntervalSince(lastSync) > 7 * 24 * 60 * 60,
|
||||
let configurationMessage = ConfigurationMessage.getCurrent() else { return } // Sync every 2 days
|
||||
let destination = Message.Destination.contact(publicKey: getUserHexEncodedPublicKey())
|
||||
Storage.shared.write { transaction in
|
||||
let job = MessageSendJob(message: configurationMessage, destination: destination)
|
||||
JobQueue.shared.add(job, using: transaction)
|
||||
}
|
||||
guard Date().timeIntervalSince(lastSync) > 7 * 24 * 60 * 60 else { return } // Sync every 2 days
|
||||
|
||||
// Only update the 'lastConfigurationSync' timestamp if we have done the first sync (Don't want
|
||||
// a new device config sync to override config syncs from other devices)
|
||||
if userDefaults[.hasSyncedInitialConfiguration] {
|
||||
userDefaults[.lastConfigurationSync] = Date()
|
||||
}
|
||||
}
|
||||
|
||||
func forceSyncConfigurationNowIfNeeded(with transaction: YapDatabaseReadWriteTransaction? = nil) -> Promise<Void> {
|
||||
guard Storage.shared.getUser()?.name != nil, let configurationMessage = ConfigurationMessage.getCurrent(with: transaction) else {
|
||||
return Promise.value(())
|
||||
}
|
||||
|
||||
let destination = Message.Destination.contact(publicKey: getUserHexEncodedPublicKey())
|
||||
let (promise, seal) = Promise<Void>.pending()
|
||||
Storage.writeSync { transaction in
|
||||
MessageSender.send(configurationMessage, to: destination, using: transaction).done {
|
||||
seal.fulfill(())
|
||||
}.catch { _ in
|
||||
seal.fulfill(()) // Fulfill even if this failed; the configuration in the swarm should be at most 2 days old
|
||||
}.retainUntilComplete()
|
||||
}
|
||||
return promise
|
||||
MessageSender.syncConfiguration(forceSyncNow: false)
|
||||
.done {
|
||||
// Only update the 'lastConfigurationSync' timestamp if we have done the first sync (Don't want
|
||||
// a new device config sync to override config syncs from other devices)
|
||||
if userDefaults[.hasSyncedInitialConfiguration] {
|
||||
userDefaults[.lastConfigurationSync] = Date()
|
||||
}
|
||||
}
|
||||
.retainUntilComplete()
|
||||
}
|
||||
|
||||
@objc func startClosedGroupPoller() {
|
||||
|
@ -48,10 +30,3 @@ extension AppDelegate {
|
|||
ClosedGroupPoller.shared.stop()
|
||||
}
|
||||
}
|
||||
|
||||
extension AppDelegate {
|
||||
@objc(forceSyncConfigurationNowIfNeeded)
|
||||
func objc_forceSyncConfigurationNowIfNeeded() {
|
||||
return forceSyncConfigurationNowIfNeeded(with: nil).retainUntilComplete()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -144,8 +144,7 @@ final class JoinOpenGroupVC : BaseVC, UIPageViewControllerDataSource, UIPageView
|
|||
OpenGroupManagerV2.shared.add(room: room, server: server, publicKey: publicKey, using: transaction)
|
||||
.done(on: DispatchQueue.main) { [weak self] _ in
|
||||
self?.presentingViewController?.dismiss(animated: true, completion: nil)
|
||||
let appDelegate = UIApplication.shared.delegate as! AppDelegate
|
||||
appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete() // FIXME: It's probably cleaner to do this inside addOpenGroup(...)
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete() // FIXME: It's probably cleaner to do this inside addOpenGroup(...)
|
||||
}
|
||||
.catch(on: DispatchQueue.main) { [weak self] error in
|
||||
self?.dismiss(animated: true, completion: nil) // Dismiss the loader
|
||||
|
|
|
@ -123,9 +123,8 @@ final class NukeDataModal : Modal {
|
|||
}
|
||||
|
||||
@objc private func clearDeviceOnly() {
|
||||
let appDelegate = UIApplication.shared.delegate as! AppDelegate
|
||||
ModalActivityIndicatorViewController.present(fromViewController: self, canCancel: false) { [weak self] _ in
|
||||
appDelegate.forceSyncConfigurationNowIfNeeded().ensure(on: DispatchQueue.main) {
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).ensure(on: DispatchQueue.main) {
|
||||
self?.dismiss(animated: true, completion: nil) // Dismiss the loader
|
||||
UserDefaults.removeAll() // Not done in the nuke data implementation as unlinking requires this to happen later
|
||||
General.Cache.cachedEncodedPublicKey = nil // Remove the cached key so it gets re-cached on next access
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import UIKit
|
||||
import SessionMessagingKit
|
||||
|
||||
final class SettingsVC : BaseVC, AvatarViewHelperDelegate {
|
||||
private var profilePictureToBeUploaded: UIImage?
|
||||
|
@ -367,8 +368,7 @@ final class SettingsVC : BaseVC, AvatarViewHelperDelegate {
|
|||
if profilePictureToBeUploaded != nil {
|
||||
userDefaults[.lastProfilePictureUpdate] = Date()
|
||||
}
|
||||
let appDelegate = UIApplication.shared.delegate as! AppDelegate
|
||||
appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete()
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
|
||||
DispatchQueue.main.async {
|
||||
modalActivityIndicator.dismiss {
|
||||
guard let self = self else { return }
|
||||
|
|
|
@ -800,21 +800,10 @@ extension MessageReceiver {
|
|||
Storage.shared.setContact(contact, using: transaction)
|
||||
}
|
||||
|
||||
// Force a config sync to ensure all devices know the contact approval state if desired (Note: This logic
|
||||
// should match the behaviour in AppDelegate.forceSyncConfigurationNowIfNeeded())
|
||||
// Force a config sync to ensure all devices know the contact approval state if desired
|
||||
guard forceConfigSync else { return }
|
||||
|
||||
// Note: We MUST run this async as we need to ensure the database `transaction` has finished before we generate
|
||||
// a new configuration message (otherwise the `contact` will be loaded direct from the database and the
|
||||
// `didApproveMe` value won't have been updated)
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
guard Storage.shared.getUser()?.name != nil, let configurationMessage = ConfigurationMessage.getCurrent() else {
|
||||
return
|
||||
}
|
||||
|
||||
let destination: Message.Destination = Message.Destination.contact(publicKey: userPublicKey)
|
||||
MessageSender.send(configurationMessage, to: destination, using: transaction).retainUntilComplete()
|
||||
}
|
||||
MessageSender.syncConfiguration(forceSyncNow: true, with: transaction).retainUntilComplete()
|
||||
}
|
||||
|
||||
public static func handleMessageRequestResponse(_ message: MessageRequestResponse, using transaction: Any) {
|
||||
|
|
|
@ -109,8 +109,8 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension
|
|||
appSpecificSingletonBlock: {
|
||||
SSKEnvironment.shared.notificationsManager = NSENotificationPresenter()
|
||||
},
|
||||
migrationCompletion: { [weak self] in
|
||||
self?.versionMigrationsDidComplete()
|
||||
migrationCompletion: { [weak self] _, needsConfigSync in
|
||||
self?.versionMigrationsDidComplete(needsConfigSync: needsConfigSync)
|
||||
completion()
|
||||
}
|
||||
)
|
||||
|
@ -119,10 +119,15 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension
|
|||
}
|
||||
|
||||
@objc
|
||||
private func versionMigrationsDidComplete() {
|
||||
private func versionMigrationsDidComplete(needsConfigSync: Bool) {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
areVersionMigrationsComplete = true
|
||||
|
||||
// If we need a config sync then trigger it now
|
||||
if needsConfigSync {
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
|
||||
}
|
||||
|
||||
checkIsAppReady()
|
||||
}
|
||||
|
|
|
@ -46,14 +46,12 @@ final class ShareVC : UINavigationController, ShareViewDelegate, AppModeManagerD
|
|||
appSpecificSingletonBlock: {
|
||||
SSKEnvironment.shared.notificationsManager = NoopNotificationsManager()
|
||||
},
|
||||
migrationCompletion: { [weak self] in
|
||||
migrationCompletion: { [weak self] _, needsConfigSync in
|
||||
AssertIsOnMainThread()
|
||||
|
||||
self?.versionMigrationsDidComplete()
|
||||
|
||||
// performUpdateCheck must be invoked after Environment has been initialized because
|
||||
// upgrade process may depend on Environment.
|
||||
self?.versionMigrationsDidComplete()
|
||||
self?.versionMigrationsDidComplete(needsConfigSync: needsConfigSync)
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -74,12 +72,17 @@ final class ShareVC : UINavigationController, ShareViewDelegate, AppModeManagerD
|
|||
}
|
||||
|
||||
@objc
|
||||
func versionMigrationsDidComplete() {
|
||||
func versionMigrationsDidComplete(needsConfigSync: Bool) {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
Logger.debug("")
|
||||
|
||||
areVersionMigrationsComplete = true
|
||||
|
||||
// If we need a config sync then trigger it now
|
||||
if needsConfigSync {
|
||||
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
|
||||
}
|
||||
|
||||
checkIsAppReady()
|
||||
}
|
||||
|
|
|
@ -40,8 +40,7 @@ public class BlockingManagerRemovalMigration: OWSDatabaseMigration {
|
|||
self.save(with: transaction) // Intentionally capture self
|
||||
},
|
||||
completion: {
|
||||
// FIXME: Need to force a config sync after this migration
|
||||
completion()
|
||||
completion(true, true)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ public class ContactsMigration : OWSDatabaseMigration {
|
|||
}
|
||||
self.save(with: transaction) // Intentionally capture self
|
||||
}, completion: {
|
||||
completion()
|
||||
completion(true, false)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ public class MessageRequestsMigration : OWSDatabaseMigration {
|
|||
}
|
||||
self.save(with: transaction) // Intentionally capture self
|
||||
}, completion: {
|
||||
completion()
|
||||
completion(true, true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef void (^OWSDatabaseMigrationCompletion)(void);
|
||||
typedef void (^OWSDatabaseMigrationCompletion)(BOOL success, BOOL requiresConfigurationSync);
|
||||
|
||||
@class OWSPrimaryStorage;
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
OWSLogInfo(@"Completed migration %@", self.uniqueId);
|
||||
[self save];
|
||||
|
||||
completion();
|
||||
completion(true, false);
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef void (^OWSDatabaseMigrationCompletion)(void);
|
||||
typedef void (^OWSDatabaseMigrationCompletion)(BOOL success, BOOL requiresConfigurationSync);
|
||||
|
||||
@interface OWSDatabaseMigrationRunner : NSObject
|
||||
|
||||
|
|
|
@ -44,7 +44,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
{
|
||||
[self removeUnknownMigrations];
|
||||
|
||||
[self runMigrations:[self.allMigrations mutableCopy] completion:completion];
|
||||
[self runMigrations:[self.allMigrations mutableCopy]
|
||||
prevWasSuccessful: true
|
||||
prevNeedsConfigSync:false
|
||||
completion:completion];
|
||||
}
|
||||
|
||||
// Some users (especially internal users) will move back and forth between
|
||||
|
@ -77,6 +80,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
// * Ensure predictable ordering.
|
||||
// * Prevent them from interfering with each other (e.g. deadlock).
|
||||
- (void)runMigrations:(NSMutableArray<OWSDatabaseMigration *> *)migrations
|
||||
prevWasSuccessful:(BOOL)prevWasSuccessful
|
||||
prevNeedsConfigSync:(BOOL)prevNeedsConfigSync
|
||||
completion:(OWSDatabaseMigrationCompletion)completion
|
||||
{
|
||||
OWSAssertDebug(migrations);
|
||||
|
@ -85,7 +90,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
// If there are no more migrations to run, complete.
|
||||
if (migrations.count < 1) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion();
|
||||
completion(prevWasSuccessful, prevNeedsConfigSync);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -96,14 +101,20 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
// If migration has already been run, skip it.
|
||||
if ([OWSDatabaseMigration fetchObjectWithUniqueID:migration.uniqueId] != nil) {
|
||||
[self runMigrations:migrations completion:completion];
|
||||
[self runMigrations:migrations
|
||||
prevWasSuccessful:prevWasSuccessful
|
||||
prevNeedsConfigSync:prevNeedsConfigSync
|
||||
completion:completion];
|
||||
return;
|
||||
}
|
||||
|
||||
OWSLogInfo(@"Running migration: %@", migration);
|
||||
[migration runUpWithCompletion:^{
|
||||
[migration runUpWithCompletion:^(BOOL successful, BOOL needsConfigSync){
|
||||
OWSLogInfo(@"Migration complete: %@", migration);
|
||||
[self runMigrations:migrations completion:completion];
|
||||
[self runMigrations:migrations
|
||||
prevWasSuccessful:(prevWasSuccessful && successful)
|
||||
prevNeedsConfigSync:(prevNeedsConfigSync || needsConfigSync)
|
||||
completion:completion];
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
OWSLogVerbose(@"%lu", (unsigned long)recordIds.count);
|
||||
|
||||
if (recordIds.count < 1) {
|
||||
completion();
|
||||
completion(true, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,4 +104,46 @@ extension MessageSender {
|
|||
}
|
||||
return promise
|
||||
}
|
||||
|
||||
public static func syncConfiguration(forceSyncNow: Bool = true, with transaction: YapDatabaseReadWriteTransaction? = nil) -> Promise<Void> {
|
||||
guard Storage.shared.getUser()?.name != nil, let configurationMessage = ConfigurationMessage.getCurrent(with: transaction) else {
|
||||
return Promise.value(())
|
||||
}
|
||||
|
||||
let (promise, seal) = Promise<Void>.pending()
|
||||
let sendMessage: (YapDatabaseReadTransaction) -> () = { transaction in
|
||||
let destination: Message.Destination = Message.Destination.contact(publicKey: getUserHexEncodedPublicKey())
|
||||
|
||||
if forceSyncNow {
|
||||
MessageSender.send(configurationMessage, to: destination, using: transaction).done {
|
||||
seal.fulfill(())
|
||||
}.catch { _ in
|
||||
seal.fulfill(()) // Fulfill even if this failed; the configuration in the swarm should be at most 2 days old
|
||||
}.retainUntilComplete()
|
||||
}
|
||||
else {
|
||||
let job = MessageSendJob(message: configurationMessage, destination: destination)
|
||||
JobQueue.shared.add(job, using: transaction)
|
||||
seal.fulfill(())
|
||||
}
|
||||
}
|
||||
|
||||
// If we are provided with a transaction then read the data based on the state of the database
|
||||
// from within the transaction rather than the state in disk
|
||||
if let transaction: YapDatabaseReadWriteTransaction = transaction {
|
||||
sendMessage(transaction)
|
||||
}
|
||||
else {
|
||||
Storage.writeSync { transaction in sendMessage(transaction) }
|
||||
}
|
||||
|
||||
return promise
|
||||
}
|
||||
}
|
||||
|
||||
extension MessageSender {
|
||||
@objc(forceSyncConfigurationNow)
|
||||
public static func objc_forceSyncConfigurationNow() {
|
||||
return syncConfiguration(forceSyncNow: true, with: nil).retainUntilComplete()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@ FOUNDATION_EXPORT const unsigned char SignalUtilitiesKitVersionString[];
|
|||
#import <SignalUtilitiesKit/OWSUnreadIndicator.h>
|
||||
#import <SignalUtilitiesKit/OWSViewController.h>
|
||||
#import <SignalUtilitiesKit/ScreenLockViewController.h>
|
||||
#import <SignalUtilitiesKit/SelectRecipientViewController.h>
|
||||
#import <SignalUtilitiesKit/SignalAccount.h>
|
||||
#import <SignalUtilitiesKit/SSKAsserts.h>
|
||||
#import <SignalUtilitiesKit/Theme.h>
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef void (^OWSDatabaseMigrationCompletion)(BOOL success, BOOL requiresConfigurationSync);
|
||||
|
||||
// This is _NOT_ a singleton and will be instantiated each time that the SAE is used.
|
||||
@interface AppSetup : NSObject
|
||||
|
||||
+ (void)setupEnvironmentWithAppSpecificSingletonBlock:(dispatch_block_t)appSpecificSingletonBlock
|
||||
migrationCompletion:(dispatch_block_t)migrationCompletion;
|
||||
migrationCompletion:(OWSDatabaseMigrationCompletion)migrationCompletion;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#import <SignalUtilitiesKit/OWSDatabaseMigration.h>
|
||||
#import <SignalUtilitiesKit/OWSProfileManager.h>
|
||||
#import <SessionMessagingKit/OWSBackgroundTask.h>
|
||||
#import <SessionMessagingKit/OWSBlockingManager.h>
|
||||
#import <SessionMessagingKit/OWSDisappearingMessagesJob.h>
|
||||
#import <SessionMessagingKit/OWSIdentityManager.h>
|
||||
#import <SessionMessagingKit/OWSOutgoingReceiptManager.h>
|
||||
|
@ -23,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@implementation AppSetup
|
||||
|
||||
+ (void)setupEnvironmentWithAppSpecificSingletonBlock:(dispatch_block_t)appSpecificSingletonBlock
|
||||
migrationCompletion:(dispatch_block_t)migrationCompletion
|
||||
migrationCompletion:(OWSDatabaseMigrationCompletion)migrationCompletion
|
||||
{
|
||||
OWSAssertDebug(appSpecificSingletonBlock);
|
||||
OWSAssertDebug(migrationCompletion);
|
||||
|
@ -97,10 +96,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[OWSStorage registerExtensionsWithMigrationBlock:^() {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// Don't start database migrations until storage is ready.
|
||||
[VersionMigrations performUpdateCheckWithCompletion:^() {
|
||||
[VersionMigrations performUpdateCheckWithCompletion:^(BOOL successful, BOOL needsConfigSync) {
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
migrationCompletion();
|
||||
migrationCompletion(successful, needsConfigSync);
|
||||
|
||||
OWSAssertDebug(backgroundTask);
|
||||
backgroundTask = nil;
|
||||
|
|
|
@ -6,7 +6,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
#define RECENT_CALLS_DEFAULT_KEY @"RPRecentCallsDefaultKey"
|
||||
|
||||
typedef void (^VersionMigrationCompletion)(void);
|
||||
typedef void (^VersionMigrationCompletion)(BOOL success, BOOL requiresConfigurationSync);
|
||||
|
||||
@interface VersionMigrations : NSObject
|
||||
|
||||
|
|
Loading…
Reference in New Issue