diff --git a/Configuration.swift b/Configuration.swift index 055bd318a..bdc23dc0d 100644 --- a/Configuration.swift +++ b/Configuration.swift @@ -1,17 +1,6 @@ import Foundation import SessionUtilitiesKit -@objc -public final class SNMessagingKitConfiguration : NSObject { - public let storage: SessionMessagingKitStorageProtocol - - @objc public static var shared: SNMessagingKitConfiguration! - - fileprivate init(storage: SessionMessagingKitStorageProtocol) { - self.storage = storage - } -} - public enum SNMessagingKit { // Just to make the external API nice public static func migrations() -> TargetMigrations { return TargetMigrations( @@ -28,7 +17,7 @@ public enum SNMessagingKit { // Just to make the external API nice ) } - public static func configure(storage: SessionMessagingKitStorageProtocol) { + public static func configure() { // Configure the job executors JobRunner.add(executor: DisappearingMessagesJob.self, for: .disappearingMessages) JobRunner.add(executor: FailedMessageSendsJob.self, for: .failedMessageSends) @@ -42,7 +31,5 @@ public enum SNMessagingKit { // Just to make the external API nice JobRunner.add(executor: SendReadReceiptsJob.self, for: .sendReadReceipts) JobRunner.add(executor: AttachmentDownloadJob.self, for: .attachmentDownload) JobRunner.add(executor: AttachmentUploadJob.self, for: .attachmentUpload) - - SNMessagingKitConfiguration.shared = SNMessagingKitConfiguration(storage: storage) } } diff --git a/Podfile b/Podfile index cfd179fd7..b1deaf9f6 100644 --- a/Podfile +++ b/Podfile @@ -21,7 +21,6 @@ abstract_target 'GlobalDependencies' do pod 'PureLayout', '~> 3.1.8' pod 'NVActivityIndicatorView' pod 'YYImage', git: 'https://github.com/signalapp/YYImage' - pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master' pod 'ZXingObjC' pod 'DifferenceKit' end @@ -38,7 +37,6 @@ abstract_target 'GlobalDependencies' do abstract_target 'ExtendedDependencies' do pod 'AFNetworking' pod 'PureLayout', '~> 3.1.8' - pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master' target 'SessionShareExtension' do pod 'NVActivityIndicatorView' diff --git a/Podfile.lock b/Podfile.lock index fc074549d..819153e15 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -29,9 +29,6 @@ PODS: - DifferenceKit/Core - GRDB.swift/SQLCipher (5.24.1): - SQLCipher (>= 3.4.0) - - Mantle (2.1.0): - - Mantle/extobjc (= 2.1.0) - - Mantle/extobjc (2.1.0) - NVActivityIndicatorView (5.1.1): - NVActivityIndicatorView/Base (= 5.1.1) - NVActivityIndicatorView/Base (5.1.1) @@ -133,7 +130,6 @@ DEPENDENCIES: - Curve25519Kit (from `https://github.com/signalapp/Curve25519Kit.git`) - DifferenceKit - GRDB.swift/SQLCipher - - Mantle (from `https://github.com/signalapp/Mantle`, branch `signal-master`) - NVActivityIndicatorView - PromiseKit - PureLayout (~> 3.1.8) @@ -168,9 +164,6 @@ SPEC REPOS: EXTERNAL SOURCES: Curve25519Kit: :git: https://github.com/signalapp/Curve25519Kit.git - Mantle: - :branch: signal-master - :git: https://github.com/signalapp/Mantle SignalCoreKit: :branch: session-version :git: https://github.com/oxen-io/session-ios-core-kit @@ -184,9 +177,6 @@ CHECKOUT OPTIONS: Curve25519Kit: :commit: 4fc1c10e98fff2534b5379a9bb587430fdb8e577 :git: https://github.com/signalapp/Curve25519Kit.git - Mantle: - :commit: e7e46253bb01ce39525d90aa69ed9e85e758bfc4 - :git: https://github.com/signalapp/Mantle SignalCoreKit: :commit: 4590c2737a2b5dc0ef4ace9f9019b581caccc1de :git: https://github.com/oxen-io/session-ios-core-kit @@ -204,7 +194,6 @@ SPEC CHECKSUMS: Curve25519Kit: e63f9859ede02438ae3defc5e1a87e09d1ec7ee6 DifferenceKit: 5659c430bb7fe45876fa32ce5cba5d6167f0c805 GRDB.swift: b3180ce2135fc06a453297889b746b1478c4d8c7 - Mantle: 2fa750afa478cd625a94230fbf1c13462f29395b NVActivityIndicatorView: 1f6c5687f1171810aa27a3296814dc2d7dec3667 OpenSSL-Universal: e7311447fd2419f57420c79524b641537387eff2 PromiseKit: 3b2b6995e51a954c46dbc550ce3da44fbfb563c5 @@ -219,6 +208,6 @@ SPEC CHECKSUMS: YYImage: f1ddd15ac032a58b78bbed1e012b50302d318331 ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb -PODFILE CHECKSUM: 9715c163fab54d487be0c32357d6d1729aa96a7b +PODFILE CHECKSUM: 05dc0000aee6d863406fc684884935594fcf14fa COCOAPODS: 1.11.2 diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index ef125b14f..87e8381e1 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -107,7 +107,6 @@ 4C9CA25D217E676900607C63 /* ZXingObjC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C9CA25C217E676900607C63 /* ZXingObjC.framework */; }; 4CA46F4C219CCC630038ABDE /* CaptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CA46F4B219CCC630038ABDE /* CaptionView.swift */; }; 4CA485BB2232339F004B9E7D /* PhotoCaptureViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CA485BA2232339F004B9E7D /* PhotoCaptureViewController.swift */; }; - 4CC1ECFB211A553000CC13BE /* AppUpdateNag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC1ECFA211A553000CC13BE /* AppUpdateNag.swift */; }; 4CC613362227A00400E21A3A /* ConversationSearch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC613352227A00400E21A3A /* ConversationSearch.swift */; }; 70377AAB1918450100CAF501 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70377AAA1918450100CAF501 /* MobileCoreServices.framework */; }; 768A1A2B17FC9CD300E00ED8 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 768A1A2A17FC9CD300E00ED8 /* libz.dylib */; }; @@ -176,8 +175,6 @@ B879D449247E1BE300DB3608 /* PathVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B879D448247E1BE300DB3608 /* PathVC.swift */; }; B87EF17126367CF800124B3C /* FileServerAPIV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B87EF17026367CF800124B3C /* FileServerAPIV2.swift */; }; B87EF18126377A1D00124B3C /* Features.swift in Sources */ = {isa = PBXBuildFile; fileRef = B87EF18026377A1D00124B3C /* Features.swift */; }; - B8856CA8256F0F42001CE70E /* OWSBackupFragment.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB07255A580700E217F9 /* OWSBackupFragment.m */; }; - B8856CB1256F0F47001CE70E /* OWSBackupFragment.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDAEA255A580500E217F9 /* OWSBackupFragment.h */; settings = {ATTRIBUTES = (Public, ); }; }; B8856CEE256F1054001CE70E /* OWSAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = C38EF2F7255B6DBC007E1867 /* OWSAudioPlayer.m */; }; B8856CF7256F105E001CE70E /* OWSAudioPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = C38EF2F5255B6DBC007E1867 /* OWSAudioPlayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; B8856D08256F10F1001CE70E /* DeviceSleepManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C38EF309255B6DBE007E1867 /* DeviceSleepManager.swift */; }; @@ -194,7 +191,6 @@ B8856DF8256F1633001CE70E /* NSString+SSK.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB12255A580800E217F9 /* NSString+SSK.h */; settings = {ATTRIBUTES = (Public, ); }; }; B8856E09256F1676001CE70E /* UIDevice+featureSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = C38EF237255B6D65007E1867 /* UIDevice+featureSupport.swift */; }; B8856E1A256F1700001CE70E /* OWSMath.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB14255A580800E217F9 /* OWSMath.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B8856E33256F18D5001CE70E /* OWSStorage+Subclass.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDAB9255A580100E217F9 /* OWSStorage+Subclass.h */; settings = {ATTRIBUTES = (Public, ); }; }; B8856ECE256F1E58001CE70E /* OWSPreferences.m in Sources */ = {isa = PBXBuildFile; fileRef = C38EF308255B6DBE007E1867 /* OWSPreferences.m */; }; B8856ED7256F1EB4001CE70E /* OWSPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = C38EF2F1255B6DBB007E1867 /* OWSPreferences.h */; settings = {ATTRIBUTES = (Public, ); }; }; B886B4A72398B23E00211ABE /* QRCodeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B886B4A62398B23E00211ABE /* QRCodeVC.swift */; }; @@ -276,8 +272,6 @@ C32C5B51256DC219003C73A2 /* NSNotificationCenter+OWS.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB3B255A580B00E217F9 /* NSNotificationCenter+OWS.h */; settings = {ATTRIBUTES = (Public, ); }; }; C32C5C3D256DCBAF003C73A2 /* AppReadiness.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB75255A581000E217F9 /* AppReadiness.m */; }; C32C5C46256DCBB2003C73A2 /* AppReadiness.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB01255A580700E217F9 /* AppReadiness.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C32C5C4F256DCC36003C73A2 /* Storage+OpenGroups.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8D8F18825661BA50092EF10 /* Storage+OpenGroups.swift */; }; - C32C5CF0256DD3E4003C73A2 /* Storage+Shared.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F0A5FD255C988A007BE2A3 /* Storage+Shared.swift */; }; C32C5D19256DD493003C73A2 /* LinkPreviewDraft.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBA8255A581500E217F9 /* LinkPreviewDraft.swift */; }; C32C5D83256DD5B6003C73A2 /* SSKKeychainStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBBC255A581600E217F9 /* SSKKeychainStorage.swift */; }; C32C5DBF256DD743003C73A2 /* ClosedGroupPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB34255A580B00E217F9 /* ClosedGroupPoller.swift */; }; @@ -286,16 +280,6 @@ C32C5DD2256DD9E5003C73A2 /* LRUCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAFD255A580600E217F9 /* LRUCache.swift */; }; C32C5DDB256DD9FF003C73A2 /* ContentProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB68255A580F00E217F9 /* ContentProxy.swift */; }; C32C5E0C256DDAFA003C73A2 /* NSRegularExpression+SSK.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA7A255A57FB00E217F9 /* NSRegularExpression+SSK.swift */; }; - C32C5E5B256DDF45003C73A2 /* OWSStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAB1255A580000E217F9 /* OWSStorage.m */; }; - C32C5E64256DDFD6003C73A2 /* OWSStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDAFE255A580600E217F9 /* OWSStorage.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C32C5E75256DE020003C73A2 /* YapDatabaseTransaction+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB5B255A580E00E217F9 /* YapDatabaseTransaction+OWS.m */; }; - C32C5E7E256DE023003C73A2 /* YapDatabaseTransaction+OWS.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDA88255A57FD00E217F9 /* YapDatabaseTransaction+OWS.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C32C5E97256DE0CB003C73A2 /* OWSPrimaryStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDC02255A581D00E217F9 /* OWSPrimaryStorage.m */; }; - C32C5EA0256DE0D6003C73A2 /* OWSPrimaryStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDA67255A57F900E217F9 /* OWSPrimaryStorage.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C32C5EDC256DF501003C73A2 /* YapDatabaseConnection+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB43255A580C00E217F9 /* YapDatabaseConnection+OWS.m */; }; - C32C5EE5256DF506003C73A2 /* YapDatabaseConnection+OWS.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB5F255A580E00E217F9 /* YapDatabaseConnection+OWS.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C32C5EEE256DF54E003C73A2 /* TSDatabaseView.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB46255A580C00E217F9 /* TSDatabaseView.m */; }; - C32C5EF7256DF567003C73A2 /* TSDatabaseView.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB2C255A580A00E217F9 /* TSDatabaseView.h */; settings = {ATTRIBUTES = (Public, ); }; }; C32C5FBB256E0206003C73A2 /* OWSBackgroundTask.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDC1B255A581F00E217F9 /* OWSBackgroundTask.m */; }; C32C5FC4256E0209003C73A2 /* OWSBackgroundTask.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB38255A580B00E217F9 /* OWSBackgroundTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; C32C600F256E07F5003C73A2 /* NSUserDefaults+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB77255A581000E217F9 /* NSUserDefaults+OWS.m */; }; @@ -331,7 +315,6 @@ C33FD9C2255A54EF00E217F9 /* SessionMessagingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A6F025539DE700C340D1 /* SessionMessagingKit.framework */; }; C33FD9C4255A54EF00E217F9 /* SessionSnodeKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A59F255385C100C340D1 /* SessionSnodeKit.framework */; }; C33FD9C5255A54EF00E217F9 /* SessionUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A679255388CC00C340D1 /* SessionUtilitiesKit.framework */; }; - C33FDC27255A581F00E217F9 /* YapDatabase+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA6D255A57FA00E217F9 /* YapDatabase+Promise.swift */; }; C33FDC29255A581F00E217F9 /* ReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA6F255A57FA00E217F9 /* ReachabilityManager.swift */; }; C33FDC45255A581F00E217F9 /* AppVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA8B255A57FD00E217F9 /* AppVersion.m */; }; C33FDC50255A582000E217F9 /* OWSDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDA96255A57FE00E217F9 /* OWSDispatch.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -475,8 +458,6 @@ C3A01E05261D24C400290BEB /* public-loki-foundation.der in Resources */ = {isa = PBXBuildFile; fileRef = C3A01E02261D24C400290BEB /* public-loki-foundation.der */; }; C3A01E06261D24C400290BEB /* storage-seed-1.der in Resources */ = {isa = PBXBuildFile; fileRef = C3A01E03261D24C400290BEB /* storage-seed-1.der */; }; C3A01E07261D24C400290BEB /* storage-seed-3.der in Resources */ = {isa = PBXBuildFile; fileRef = C3A01E04261D24C400290BEB /* storage-seed-3.der */; }; - C3A3A0FE256E1A3C004D228D /* TSDatabaseSecondaryIndexes.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB20255A580900E217F9 /* TSDatabaseSecondaryIndexes.m */; }; - C3A3A12B256E1AD5004D228D /* TSDatabaseSecondaryIndexes.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB25255A580900E217F9 /* TSDatabaseSecondaryIndexes.h */; settings = {ATTRIBUTES = (Public, ); }; }; C3A3A171256E1D25004D228D /* SSKReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A3A170256E1D25004D228D /* SSKReachabilityManager.swift */; }; C3A71D0B2558989C0043A11F /* MessageWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A71D0A2558989C0043A11F /* MessageWrapper.swift */; }; C3A71D1E25589AC30043A11F /* WebSocketProto.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A71D1C25589AC30043A11F /* WebSocketProto.swift */; }; @@ -490,7 +471,6 @@ C3AAFFF225AE99710089E6DD /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3AAFFF125AE99710089E6DD /* AppDelegate.swift */; }; C3ADC66126426688005F1414 /* ShareVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3ADC66026426688005F1414 /* ShareVC.swift */; }; C3BBE0762554CDA60050F1E3 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BBE0752554CDA60050F1E3 /* Configuration.swift */; }; - C3BBE0802554CDD70050F1E3 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BBE07F2554CDD70050F1E3 /* Storage.swift */; }; C3BBE0A72554D4DE0050F1E3 /* Promise+Retrying.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A5D62553860B00C340D1 /* Promise+Retrying.swift */; }; C3BBE0A82554D4DE0050F1E3 /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A5D92553860B00C340D1 /* JSON.swift */; }; C3BBE0A92554D4DE0050F1E3 /* HTTP.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A5BC255385EE00C340D1 /* HTTP.swift */; }; @@ -539,10 +519,6 @@ C3D9E38A256760390040E4F3 /* OWSFileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDBAB255A581500E217F9 /* OWSFileSystem.h */; settings = {ATTRIBUTES = (Public, ); }; }; C3D9E39B256763C20040E4F3 /* AppContext.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB85255A581100E217F9 /* AppContext.m */; }; C3D9E3A4256763DE0040E4F3 /* AppContext.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB8A255A581200E217F9 /* AppContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C3D9E3C925676AF30040E4F3 /* TSYapDatabaseObject.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA90255A57FD00E217F9 /* TSYapDatabaseObject.m */; }; - C3D9E3FA25676BCE0040E4F3 /* TSYapDatabaseObject.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDAA1255A57FF00E217F9 /* TSYapDatabaseObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C3D9E41525676C320040E4F3 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB36255A580B00E217F9 /* Storage.swift */; }; - C3D9E41F25676C870040E4F3 /* OWSPrimaryStorageProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D9E41E25676C870040E4F3 /* OWSPrimaryStorageProtocol.swift */; }; C3D9E43125676D3D0040E4F3 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D9E43025676D3D0040E4F3 /* Configuration.swift */; }; C3D9E4C02567767F0040E4F3 /* DataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBB6255A581600E217F9 /* DataSource.m */; }; C3D9E4D12567777D0040E4F3 /* OWSMediaUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB22255A580900E217F9 /* OWSMediaUtils.swift */; }; @@ -989,7 +965,6 @@ 4C9CA25C217E676900607C63 /* ZXingObjC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ZXingObjC.framework; path = ThirdParty/Carthage/Build/iOS/ZXingObjC.framework; sourceTree = ""; }; 4CA46F4B219CCC630038ABDE /* CaptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaptionView.swift; sourceTree = ""; }; 4CA485BA2232339F004B9E7D /* PhotoCaptureViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoCaptureViewController.swift; sourceTree = ""; }; - 4CC1ECFA211A553000CC13BE /* AppUpdateNag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUpdateNag.swift; sourceTree = ""; }; 4CC613352227A00400E21A3A /* ConversationSearch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationSearch.swift; sourceTree = ""; }; 5A3F440C6CC32A23AD67A2FD /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionUtilitiesKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionUtilitiesKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionUtilitiesKit/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionUtilitiesKit.debug.xcconfig"; sourceTree = ""; }; 5B7FDA4BA2DDFF4612600FB8 /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SignalUtilitiesKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SignalUtilitiesKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SignalUtilitiesKit/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SignalUtilitiesKit.debug.xcconfig"; sourceTree = ""; }; @@ -1147,7 +1122,6 @@ B8D0A26825E4A2C200C1835E /* Onboarding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Onboarding.swift; sourceTree = ""; }; B8D84EA225DF745A005A043E /* LinkPreviewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkPreviewState.swift; sourceTree = ""; }; B8D84ECE25E3108A005A043E /* ExpandingAttachmentsButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpandingAttachmentsButton.swift; sourceTree = ""; }; - B8D8F18825661BA50092EF10 /* Storage+OpenGroups.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Storage+OpenGroups.swift"; sourceTree = ""; }; B8EB20E6263F7E4B00773E52 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Localizable.strings; sourceTree = ""; }; B8EB20ED2640F28000773E52 /* VisibleMessage+OpenGroupInvitation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VisibleMessage+OpenGroupInvitation.swift"; sourceTree = ""; }; B8EB20EF2640F7F000773E52 /* OpenGroupInvitationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupInvitationView.swift; sourceTree = ""; }; @@ -1190,62 +1164,44 @@ C33FD9AB255A548A00E217F9 /* SignalUtilitiesKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SignalUtilitiesKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C33FD9AD255A548A00E217F9 /* SignalUtilitiesKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SignalUtilitiesKit.h; sourceTree = ""; }; C33FD9AE255A548A00E217F9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - C33FDA67255A57F900E217F9 /* OWSPrimaryStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSPrimaryStorage.h; sourceTree = ""; }; - C33FDA6D255A57FA00E217F9 /* YapDatabase+Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "YapDatabase+Promise.swift"; sourceTree = ""; }; C33FDA6F255A57FA00E217F9 /* ReachabilityManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReachabilityManager.swift; sourceTree = ""; }; C33FDA73255A57FA00E217F9 /* ECKeyPair+Hexadecimal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ECKeyPair+Hexadecimal.swift"; sourceTree = ""; }; C33FDA7A255A57FB00E217F9 /* NSRegularExpression+SSK.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSRegularExpression+SSK.swift"; sourceTree = ""; }; C33FDA87255A57FC00E217F9 /* TypingIndicators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypingIndicators.swift; sourceTree = ""; }; - C33FDA88255A57FD00E217F9 /* YapDatabaseTransaction+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "YapDatabaseTransaction+OWS.h"; sourceTree = ""; }; C33FDA8B255A57FD00E217F9 /* AppVersion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppVersion.m; sourceTree = ""; }; C33FDA8E255A57FD00E217F9 /* OWSFileSystem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSFileSystem.m; sourceTree = ""; }; - C33FDA90255A57FD00E217F9 /* TSYapDatabaseObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSYapDatabaseObject.m; sourceTree = ""; }; C33FDA96255A57FE00E217F9 /* OWSDispatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSDispatch.h; sourceTree = ""; }; C33FDA99255A57FE00E217F9 /* OutageDetection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutageDetection.swift; sourceTree = ""; }; C33FDA9E255A57FF00E217F9 /* ReverseDispatchQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReverseDispatchQueue.swift; sourceTree = ""; }; - C33FDAA1255A57FF00E217F9 /* TSYapDatabaseObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSYapDatabaseObject.h; sourceTree = ""; }; C33FDAA8255A57FF00E217F9 /* BuildConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BuildConfiguration.swift; sourceTree = ""; }; - C33FDAB1255A580000E217F9 /* OWSStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSStorage.m; sourceTree = ""; }; - C33FDAB9255A580100E217F9 /* OWSStorage+Subclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OWSStorage+Subclass.h"; sourceTree = ""; }; C33FDABE255A580100E217F9 /* TSConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSConstants.m; sourceTree = ""; }; C33FDAC3255A580200E217F9 /* OWSDispatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDispatch.m; sourceTree = ""; }; C33FDADE255A580400E217F9 /* SwiftSingletons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftSingletons.swift; sourceTree = ""; }; C33FDAE0255A580400E217F9 /* ByteParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ByteParser.m; sourceTree = ""; }; - C33FDAEA255A580500E217F9 /* OWSBackupFragment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupFragment.h; sourceTree = ""; }; C33FDAEF255A580500E217F9 /* NSData+Image.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Image.m"; sourceTree = ""; }; C33FDAF1255A580500E217F9 /* ThumbnailService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThumbnailService.swift; sourceTree = ""; }; C33FDAF2255A580500E217F9 /* ProxiedContentDownloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProxiedContentDownloader.swift; sourceTree = ""; }; C33FDAFC255A580600E217F9 /* MIMETypeUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIMETypeUtil.h; sourceTree = ""; }; C33FDAFD255A580600E217F9 /* LRUCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LRUCache.swift; sourceTree = ""; }; - C33FDAFE255A580600E217F9 /* OWSStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSStorage.h; sourceTree = ""; }; C33FDB01255A580700E217F9 /* AppReadiness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppReadiness.h; sourceTree = ""; }; - C33FDB07255A580700E217F9 /* OWSBackupFragment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupFragment.m; sourceTree = ""; }; C33FDB12255A580800E217F9 /* NSString+SSK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+SSK.h"; sourceTree = ""; }; C33FDB14255A580800E217F9 /* OWSMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMath.h; sourceTree = ""; }; C33FDB17255A580800E217F9 /* FunctionalUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FunctionalUtil.m; sourceTree = ""; }; C33FDB1C255A580900E217F9 /* UIImage+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+OWS.h"; sourceTree = ""; }; - C33FDB20255A580900E217F9 /* TSDatabaseSecondaryIndexes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSDatabaseSecondaryIndexes.m; sourceTree = ""; }; C33FDB22255A580900E217F9 /* OWSMediaUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSMediaUtils.swift; sourceTree = ""; }; - C33FDB25255A580900E217F9 /* TSDatabaseSecondaryIndexes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSDatabaseSecondaryIndexes.h; sourceTree = ""; }; C33FDB29255A580A00E217F9 /* NSData+Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Image.h"; sourceTree = ""; }; - C33FDB2C255A580A00E217F9 /* TSDatabaseView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSDatabaseView.h; sourceTree = ""; }; C33FDB34255A580B00E217F9 /* ClosedGroupPoller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClosedGroupPoller.swift; sourceTree = ""; }; - C33FDB36255A580B00E217F9 /* Storage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Storage.swift; sourceTree = ""; }; C33FDB38255A580B00E217F9 /* OWSBackgroundTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackgroundTask.h; sourceTree = ""; }; C33FDB3A255A580B00E217F9 /* Poller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Poller.swift; sourceTree = ""; }; C33FDB3B255A580B00E217F9 /* NSNotificationCenter+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNotificationCenter+OWS.h"; sourceTree = ""; }; C33FDB3F255A580C00E217F9 /* String+SSK.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+SSK.swift"; sourceTree = ""; }; C33FDB40255A580C00E217F9 /* SignalIOSProto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalIOSProto.swift; sourceTree = ""; }; C33FDB41255A580C00E217F9 /* MIMETypeUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MIMETypeUtil.m; sourceTree = ""; }; - C33FDB43255A580C00E217F9 /* YapDatabaseConnection+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "YapDatabaseConnection+OWS.m"; sourceTree = ""; }; C33FDB45255A580C00E217F9 /* NSString+SSK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+SSK.m"; sourceTree = ""; }; - C33FDB46255A580C00E217F9 /* TSDatabaseView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSDatabaseView.m; sourceTree = ""; }; C33FDB49255A580C00E217F9 /* WeakTimer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeakTimer.swift; sourceTree = ""; }; C33FDB4C255A580D00E217F9 /* AppVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppVersion.h; sourceTree = ""; }; C33FDB51255A580D00E217F9 /* NSUserDefaults+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSUserDefaults+OWS.h"; sourceTree = ""; }; C33FDB54255A580D00E217F9 /* DataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataSource.h; sourceTree = ""; }; - C33FDB5B255A580E00E217F9 /* YapDatabaseTransaction+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "YapDatabaseTransaction+OWS.m"; sourceTree = ""; }; - C33FDB5F255A580E00E217F9 /* YapDatabaseConnection+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "YapDatabaseConnection+OWS.h"; sourceTree = ""; }; C33FDB68255A580F00E217F9 /* ContentProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentProxy.swift; sourceTree = ""; }; C33FDB69255A580F00E217F9 /* FeatureFlags.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureFlags.swift; sourceTree = ""; }; C33FDB6B255A580F00E217F9 /* SNUserDefaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SNUserDefaults.swift; sourceTree = ""; }; @@ -1272,7 +1228,6 @@ C33FDBE1255A581A00E217F9 /* LKGroupUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LKGroupUtilities.m; sourceTree = ""; }; C33FDBF6255A581C00E217F9 /* NSURLSessionDataTask+StatusCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLSessionDataTask+StatusCode.h"; sourceTree = ""; }; C33FDBF9255A581C00E217F9 /* OWSError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSError.h; sourceTree = ""; }; - C33FDC02255A581D00E217F9 /* OWSPrimaryStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSPrimaryStorage.m; sourceTree = ""; }; C33FDC03255A581D00E217F9 /* ByteParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByteParser.h; sourceTree = ""; }; C33FDC0B255A581D00E217F9 /* OWSError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSError.m; sourceTree = ""; }; C33FDC12255A581E00E217F9 /* TSConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSConstants.h; sourceTree = ""; }; @@ -1426,7 +1381,6 @@ C3ADC66026426688005F1414 /* ShareVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareVC.swift; sourceTree = ""; }; C3AECBEA24EF5244005743DE /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = fa.lproj/Localizable.strings; sourceTree = ""; }; C3BBE0752554CDA60050F1E3 /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; - C3BBE07F2554CDD70050F1E3 /* Storage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Storage.swift; sourceTree = ""; }; C3BBE0C62554F1570050F1E3 /* FixedWidthInteger+BigEndian.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FixedWidthInteger+BigEndian.swift"; sourceTree = ""; }; C3C2A59F255385C100C340D1 /* SessionSnodeKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SessionSnodeKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C3C2A5A1255385C100C340D1 /* SessionSnodeKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SessionSnodeKit.h; sourceTree = ""; }; @@ -1472,7 +1426,6 @@ C3CA3ABD255CDB0D00F4C6D4 /* portuguese.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = portuguese.txt; sourceTree = ""; }; C3CA3AC7255CDB2900F4C6D4 /* spanish.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = spanish.txt; sourceTree = ""; }; C3D0972A2510499C00F6E3E4 /* BackgroundPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundPoller.swift; sourceTree = ""; }; - C3D9E41E25676C870040E4F3 /* OWSPrimaryStorageProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OWSPrimaryStorageProtocol.swift; sourceTree = ""; }; C3D9E43025676D3D0040E4F3 /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; C3DA9C0625AE7396008F7C7E /* ConfigurationMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationMessage.swift; sourceTree = ""; }; C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRCopyableLabel.swift; sourceTree = ""; }; @@ -1487,7 +1440,6 @@ C3F0A52F255C80BC007BE2A3 /* NoopNotificationsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoopNotificationsManager.swift; sourceTree = ""; }; C3F0A5B2255C915C007BE2A3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; C3F0A5EB255C970D007BE2A3 /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; - C3F0A5FD255C988A007BE2A3 /* Storage+Shared.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Storage+Shared.swift"; sourceTree = ""; }; C5060C3B36A848B71CCE4685 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionUtilitiesKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionUtilitiesKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C88965DE4F4EC4FC919BEC4E /* Pods-SessionUIKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SessionUIKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SessionUIKit/Pods-SessionUIKit.debug.xcconfig"; sourceTree = ""; }; C98441E849C3CA7FE8220D33 /* Pods-SessionNotificationServiceExtension.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SessionNotificationServiceExtension.app store release.xcconfig"; path = "Pods/Target Support Files/Pods-SessionNotificationServiceExtension/Pods-SessionNotificationServiceExtension.app store release.xcconfig"; sourceTree = ""; }; @@ -1852,7 +1804,6 @@ 4C090A1A210FD9C7001FD7F9 /* HapticFeedback.swift */, 34D5CCA71EAE3D30005515DB /* AvatarViewHelper.h */, 34D5CCA81EAE3D30005515DB /* AvatarViewHelper.m */, - 4CC1ECFA211A553000CC13BE /* AppUpdateNag.swift */, FD848B9728422F1A000E298B /* Date+Utilities.swift */, FDD2506D283711D600198BDA /* DifferenceKit+Utilities.swift */, 4C21D5D5223A9DC500EF8A77 /* UIAlerts+iOS9.m */, @@ -2081,11 +2032,7 @@ FD28A4F527EAD44C00FF65E7 /* GRDBStorage.swift */, C33FDBAB255A581500E217F9 /* OWSFileSystem.h */, C33FDA8E255A57FD00E217F9 /* OWSFileSystem.m */, - C3D9E41E25676C870040E4F3 /* OWSPrimaryStorageProtocol.swift */, C33FDBBC255A581600E217F9 /* SSKKeychainStorage.swift */, - C33FDB36255A580B00E217F9 /* Storage.swift */, - C33FDAA1255A57FF00E217F9 /* TSYapDatabaseObject.h */, - C33FDA90255A57FD00E217F9 /* TSYapDatabaseObject.m */, ); path = Database; sourceTree = ""; @@ -2385,19 +2332,6 @@ FD17D79427F3E03300122BE0 /* Migrations */, FD09796C27FA6C8B00936362 /* Models */, B8F5F56425EC8453003BF8D4 /* Notification+Contacts.swift */, - C33FDAEA255A580500E217F9 /* OWSBackupFragment.h */, - C33FDB07255A580700E217F9 /* OWSBackupFragment.m */, - C33FDA67255A57F900E217F9 /* OWSPrimaryStorage.h */, - C33FDC02255A581D00E217F9 /* OWSPrimaryStorage.m */, - C33FDAFE255A580600E217F9 /* OWSStorage.h */, - C33FDAB1255A580000E217F9 /* OWSStorage.m */, - C33FDAB9255A580100E217F9 /* OWSStorage+Subclass.h */, - B8D8F18825661BA50092EF10 /* Storage+OpenGroups.swift */, - C3F0A5FD255C988A007BE2A3 /* Storage+Shared.swift */, - C33FDB25255A580900E217F9 /* TSDatabaseSecondaryIndexes.h */, - C33FDB20255A580900E217F9 /* TSDatabaseSecondaryIndexes.m */, - C33FDB2C255A580A00E217F9 /* TSDatabaseView.h */, - C33FDB46255A580C00E217F9 /* TSDatabaseView.m */, ); path = Database; sourceTree = ""; @@ -2475,7 +2409,6 @@ children = ( C33FD9B7255A54A300E217F9 /* Meta */, C3F0A5EB255C970D007BE2A3 /* Configuration.swift */, - C38BBA0E255E32440041B9A3 /* Database */, C36096ED25AD20FD008B62B2 /* Media Viewing & Editing */, C38BBA0D255E321C0041B9A3 /* Messaging */, C36096EF25AD2268008B62B2 /* Profile Pictures */, @@ -2704,13 +2637,6 @@ path = Notifications; sourceTree = ""; }; - C379DCE82567330E0002D4EB /* Migrations */ = { - isa = PBXGroup; - children = ( - ); - path = Migrations; - sourceTree = ""; - }; C379DCE9256733390002D4EB /* Image Editing */ = { isa = PBXGroup; children = ( @@ -2777,15 +2703,6 @@ path = Messaging; sourceTree = ""; }; - C38BBA0E255E32440041B9A3 /* Database */ = { - isa = PBXGroup; - children = ( - C379DCE82567330E0002D4EB /* Migrations */, - C33FDA6D255A57FA00E217F9 /* YapDatabase+Promise.swift */, - ); - path = Database; - sourceTree = ""; - }; C3A721332558BDDF0043A11F /* Open Groups */ = { isa = PBXGroup; children = ( @@ -2836,10 +2753,6 @@ C38EEF09255B49A8007E1867 /* SNProtoEnvelope+Conversion.swift */, C3A3A170256E1D25004D228D /* SSKReachabilityManager.swift */, C3ECBF7A257056B700EA7FCE /* Threading.swift */, - C33FDB5F255A580E00E217F9 /* YapDatabaseConnection+OWS.h */, - C33FDB43255A580C00E217F9 /* YapDatabaseConnection+OWS.m */, - C33FDA88255A57FD00E217F9 /* YapDatabaseTransaction+OWS.h */, - C33FDB5B255A580E00E217F9 /* YapDatabaseTransaction+OWS.m */, ); path = Utilities; sourceTree = ""; @@ -2916,7 +2829,6 @@ children = ( C3C2A7802553AA6300C340D1 /* Protos */, C3C2A70A25539DF900C340D1 /* Meta */, - C3BBE07F2554CDD70050F1E3 /* Storage.swift */, C32C5BCB256DC818003C73A2 /* Database */, C300A5BB2554AFFB00555489 /* Messages */, C300A5F02554B08500555489 /* Sending & Receiving */, @@ -3497,7 +3409,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - C3D9E3FA25676BCE0040E4F3 /* TSYapDatabaseObject.h in Headers */, C3D9E3A4256763DE0040E4F3 /* AppContext.h in Headers */, C3D9E38A256760390040E4F3 /* OWSFileSystem.h in Headers */, C352A3B72557B6ED00338F3E /* TSRequest.h in Headers */, @@ -3520,21 +3431,13 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - C32C5EE5256DF506003C73A2 /* YapDatabaseConnection+OWS.h in Headers */, C3C2A6F425539DE700C340D1 /* SessionMessagingKit.h in Headers */, C32C5C46256DCBB2003C73A2 /* AppReadiness.h in Headers */, - B8856CB1256F0F47001CE70E /* OWSBackupFragment.h in Headers */, - C3A3A12B256E1AD5004D228D /* TSDatabaseSecondaryIndexes.h in Headers */, C32C5FC4256E0209003C73A2 /* OWSBackgroundTask.h in Headers */, - C32C5EF7256DF567003C73A2 /* TSDatabaseView.h in Headers */, B8856ED7256F1EB4001CE70E /* OWSPreferences.h in Headers */, C32A026C25A801AF000ED5D4 /* NSData+messagePadding.h in Headers */, B8856D72256F1421001CE70E /* OWSWindowManager.h in Headers */, B8856CF7256F105E001CE70E /* OWSAudioPlayer.h in Headers */, - C32C5E7E256DE023003C73A2 /* YapDatabaseTransaction+OWS.h in Headers */, - C32C5EA0256DE0D6003C73A2 /* OWSPrimaryStorage.h in Headers */, - B8856E33256F18D5001CE70E /* OWSStorage+Subclass.h in Headers */, - C32C5E64256DDFD6003C73A2 /* OWSStorage.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4295,7 +4198,6 @@ C33FDD03255A582000E217F9 /* WeakTimer.swift in Sources */, C38EF3B9255B6DE7007E1867 /* ImageEditorPinchGestureRecognizer.swift in Sources */, C33FDC98255A582000E217F9 /* SwiftSingletons.swift in Sources */, - C33FDC27255A581F00E217F9 /* YapDatabase+Promise.swift in Sources */, C38EF3B8255B6DE7007E1867 /* ImageEditorTextViewController.swift in Sources */, C38EF40B255B6DF7007E1867 /* TappableStackView.swift in Sources */, C38EF31D255B6DBF007E1867 /* UIImage+OWS.swift in Sources */, @@ -4354,7 +4256,6 @@ 7B1D74AC27BDE7510030B423 /* Promise+Timeout.swift in Sources */, C3AABDDF2553ECF00042FF4C /* Array+Utilities.swift in Sources */, C32C5A47256DB8F0003C73A2 /* ECKeyPair+Hexadecimal.swift in Sources */, - C3D9E41525676C320040E4F3 /* Storage.swift in Sources */, 7B1D74B027C365960030B423 /* Timer+MainThread.swift in Sources */, C32C5D83256DD5B6003C73A2 /* SSKKeychainStorage.swift in Sources */, C3D9E39B256763C20040E4F3 /* AppContext.m in Sources */, @@ -4393,7 +4294,6 @@ C3C2AC2E2553CBEB00C340D1 /* String+Trimming.swift in Sources */, C32C5B48256DC211003C73A2 /* NSNotificationCenter+OWS.m in Sources */, FD17D7C727F5207C00122BE0 /* DatabaseMigrator+Utilities.swift in Sources */, - C3D9E3C925676AF30040E4F3 /* TSYapDatabaseObject.m in Sources */, C352A3A62557B60D00338F3E /* TSRequest.m in Sources */, FD848B9328420164000E298B /* UnicodeScalar+Utilities.swift in Sources */, FD09796B27F6C67500936362 /* Failable.swift in Sources */, @@ -4415,7 +4315,6 @@ B8BC00C0257D90E30032E807 /* General.swift in Sources */, FD17D7A127F40D2500122BE0 /* GRDBStorage.swift in Sources */, C32C5A24256DB7DB003C73A2 /* SNUserDefaults.swift in Sources */, - C3D9E41F25676C870040E4F3 /* OWSPrimaryStorageProtocol.swift in Sources */, C3BBE0A72554D4DE0050F1E3 /* Promise+Retrying.swift in Sources */, B8856D7B256F14F4001CE70E /* UIView+OWS.m in Sources */, FD17D7B027F4225C00122BE0 /* Set+Utilities.swift in Sources */, @@ -4478,11 +4377,9 @@ FDF0B7472804F0CE004C14C5 /* DisappearingMessagesJob.swift in Sources */, B8856D1A256F114D001CE70E /* ProximityMonitoringManager.swift in Sources */, C3D9E52725677DF20040E4F3 /* ThumbnailService.swift in Sources */, - C32C5E75256DE020003C73A2 /* YapDatabaseTransaction+OWS.m in Sources */, FDF0B73C27FFD3D6004C14C5 /* LinkPreview.swift in Sources */, FD09797527FAB64300936362 /* ProfileManager.swift in Sources */, FDA8EAFE280E8B78002B68E5 /* FailedMessageSendsJob.swift in Sources */, - C3BBE0802554CDD70050F1E3 /* Storage.swift in Sources */, C3DB66AC260ACA42001EFC55 /* OpenGroupManagerV2.swift in Sources */, C379DCF4256735770002D4EB /* VisibleMessage+Attachment.swift in Sources */, FD09797F27FCFBFF00936362 /* OWSAES256Key+Utilities.swift in Sources */, @@ -4513,18 +4410,14 @@ C3C2A7712553A41E00C340D1 /* ControlMessage.swift in Sources */, C32C5D19256DD493003C73A2 /* LinkPreviewDraft.swift in Sources */, FD3C907527E83AC200CD579F /* OpenGroupServerIdLookup.swift in Sources */, - C32C5CF0256DD3E4003C73A2 /* Storage+Shared.swift in Sources */, C300A5BD2554B00D00555489 /* ReadReceipt.swift in Sources */, FDF0B7582807F368004C14C5 /* MessageReceiverError.swift in Sources */, - C32C5E5B256DDF45003C73A2 /* OWSStorage.m in Sources */, - C32C5C4F256DCC36003C73A2 /* Storage+OpenGroups.swift in Sources */, FD6A7A692818BE7300035AC1 /* RetrieveDefaultOpenGroupRoomsJob.swift in Sources */, C3DA9C0725AE7396008F7C7E /* ConfigurationMessage.swift in Sources */, B8856CEE256F1054001CE70E /* OWSAudioPlayer.m in Sources */, FD5D200F27AA2B6000FEA984 /* MessageRequestResponse.swift in Sources */, FD09798D27FD1D8900936362 /* DisappearingMessageConfiguration.swift in Sources */, FDF0B75A2807F3A3004C14C5 /* MessageSenderError.swift in Sources */, - C32C5EDC256DF501003C73A2 /* YapDatabaseConnection+OWS.m in Sources */, C3BBE0762554CDA60050F1E3 /* Configuration.swift in Sources */, B8856D69256F141F001CE70E /* OWSWindowManager.m in Sources */, C3ECBF7B257056B700EA7FCE /* Threading.swift in Sources */, @@ -4535,12 +4428,10 @@ C34A977425A3E34A00852C71 /* ClosedGroupControlMessage.swift in Sources */, FD09799527FE7B8E00936362 /* Interaction.swift in Sources */, B88FA7B826045D100049422F /* OpenGroupAPIV2.swift in Sources */, - C32C5E97256DE0CB003C73A2 /* OWSPrimaryStorage.m in Sources */, C3A71D1F25589AC30043A11F /* WebSocketResources.pb.swift in Sources */, FDF0B74B28061F7A004C14C5 /* InteractionAttachment.swift in Sources */, B8F5F56525EC8453003BF8D4 /* Notification+Contacts.swift in Sources */, FD09796E27FA6D0000936362 /* Contact.swift in Sources */, - C3A3A0FE256E1A3C004D228D /* TSDatabaseSecondaryIndexes.m in Sources */, C38D5E8D2575011E00B6A65C /* MessageSender+ClosedGroups.swift in Sources */, C3DB6695260AC923001EFC55 /* OpenGroupV2.swift in Sources */, C352A349255781F400338F3E /* AttachmentDownloadJob.swift in Sources */, @@ -4553,14 +4444,12 @@ C3C2A75F2553A3C500C340D1 /* VisibleMessage+LinkPreview.swift in Sources */, C32C5FBB256E0206003C73A2 /* OWSBackgroundTask.m in Sources */, FD848B8D283E0B26000E298B /* MessageInputTypes.swift in Sources */, - B8856CA8256F0F42001CE70E /* OWSBackupFragment.m in Sources */, C32C5C3D256DCBAF003C73A2 /* AppReadiness.m in Sources */, B87EF17126367CF800124B3C /* FileServerAPIV2.swift in Sources */, FD09799B27FFC82D00936362 /* Quote.swift in Sources */, C3C2A74425539EB700C340D1 /* Message.swift in Sources */, FD09798527FD1A6500936362 /* ClosedGroupKeyPair.swift in Sources */, C32C5DBF256DD743003C73A2 /* ClosedGroupPoller.swift in Sources */, - C32C5EEE256DF54E003C73A2 /* TSDatabaseView.m in Sources */, C352A35B2557824E00338F3E /* AttachmentUploadJob.swift in Sources */, FD09797027FA6FF300936362 /* Profile.swift in Sources */, FD09798B27FD1CFE00936362 /* Capability.swift in Sources */, @@ -4657,7 +4546,6 @@ B8F5F71A25F1B35C003BF8D4 /* MediaPlaceholderView.swift in Sources */, 4C21D5D8223AC60F00EF8A77 /* PhotoCapture.swift in Sources */, C331FFF32558FF0300070591 /* PathStatusView.swift in Sources */, - 4CC1ECFB211A553000CC13BE /* AppUpdateNag.swift in Sources */, B848A4C5269EAAA200617031 /* UserDetailsSheet.swift in Sources */, 34B6A903218B3F63007C4606 /* TypingIndicatorView.swift in Sources */, B886B4A72398B23E00211ABE /* QRCodeVC.swift in Sources */, diff --git a/Session/Conversations/Settings/OWSConversationSettingsViewController.m b/Session/Conversations/Settings/OWSConversationSettingsViewController.m index 8a0db3674..80f7c1dbb 100644 --- a/Session/Conversations/Settings/OWSConversationSettingsViewController.m +++ b/Session/Conversations/Settings/OWSConversationSettingsViewController.m @@ -11,7 +11,6 @@ #import #import #import -#import @import ContactsUI; @import PromiseKit; @@ -27,8 +26,6 @@ CGFloat kIconViewLength = 24; @property (nonatomic) BOOL isNoteToSelf; @property (nonatomic) BOOL isClosedGroup; @property (nonatomic) BOOL isOpenGroup; -@property (nonatomic) YapDatabaseConnection *uiDatabaseConnection; -@property (nonatomic, readonly) YapDatabaseConnection *editingDatabaseConnection; @property (nonatomic) NSArray *disappearingMessagesDurations; @property (nonatomic) BOOL originalIsDisappearingMessagesEnabled; @@ -106,11 +103,6 @@ CGFloat kIconViewLength = 24; object:nil]; } -- (YapDatabaseConnection *)editingDatabaseConnection -{ - return [OWSPrimaryStorage sharedManager].dbReadWriteConnection; -} - - (void)configureWithThreadId:(NSString *)threadId threadName:(nullable NSString *)threadName isClosedGroup:(BOOL)isClosedGroup isOpenGroup:(BOOL)isOpenGroup isNoteToSelf:(BOOL)isNoteToSelf { self.threadId = threadId; self.threadName = threadName; diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index 846daa04e..d12f8a3b1 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -236,14 +236,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD private func verifyDBKeysAvailableBeforeBackgroundLaunch() { guard UIApplication.shared.applicationState == .background else { return } - // Ensure both databases are accessible (as long as we are supporting the YDB migration - // we should keep this check) - let databasePasswordAccessible: Bool = ( - GRDBStorage.isDatabasePasswordAccessible && // GRDB password access - OWSStorage.isDatabasePasswordAccessible() // YapDatabase password access - ) - - guard !databasePasswordAccessible else { return } // All good + guard !GRDBStorage.isDatabasePasswordAccessible else { return } // All good Logger.info("Exiting because we are in the background and the database password is not accessible.") diff --git a/Session/Meta/SessionApp.swift b/Session/Meta/SessionApp.swift index c45aa7a45..dd00e2683 100644 --- a/Session/Meta/SessionApp.swift +++ b/Session/Meta/SessionApp.swift @@ -57,9 +57,8 @@ public struct SessionApp { Logger.error("") DDLog.flushLog() - OWSStorage.resetAllStorage() + GRDBStorage.resetAllStorage() ProfileManager.resetProfileStorage() - Environment.shared.preferences.clear() AppEnvironment.shared.notificationPresenter.clearAllNotifications() onReset?() diff --git a/Session/Notifications/AppNotifications.swift b/Session/Notifications/AppNotifications.swift index 0315b8eeb..48c792314 100644 --- a/Session/Notifications/AppNotifications.swift +++ b/Session/Notifications/AppNotifications.swift @@ -118,12 +118,6 @@ public class NotificationPresenter: NSObject, NotificationsProtocol { SwiftSingletons.register(self) } - // MARK: - Dependencies - - var preferences: OWSPreferences { - return Environment.shared.preferences - } - // MARK: - @objc @@ -380,10 +374,6 @@ class NotificationActionHandler { return AppEnvironment.shared.notificationPresenter } - var dbConnection: YapDatabaseConnection { - return OWSPrimaryStorage.shared().dbReadWriteConnection - } - // MARK: - func markAsRead(userInfo: [AnyHashable: Any]) throws -> Promise { diff --git a/Session/Utilities/AppUpdateNag.swift b/Session/Utilities/AppUpdateNag.swift deleted file mode 100644 index eee81cde8..000000000 --- a/Session/Utilities/AppUpdateNag.swift +++ /dev/null @@ -1,243 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -import Foundation -import PromiseKit - -@objc -class AppUpdateNag: NSObject { - - // MARK: Public - - @objc(sharedInstance) - public static let shared: AppUpdateNag = { - let versionService = AppStoreVersionService() - let nagManager = AppUpdateNag(versionService: versionService) - return nagManager - }() - - @objc - public func showAppUpgradeNagIfNecessary() { - return - - /* - guard let currentVersion = self.currentVersion else { - owsFailDebug("currentVersion was unexpectedly nil") - return - } - - guard let bundleIdentifier = self.bundleIdentifier else { - owsFailDebug("bundleIdentifier was unexpectedly nil") - return - } - - guard let lookupURL = lookupURL(bundleIdentifier: bundleIdentifier) else { - owsFailDebug("appStoreURL was unexpectedly nil") - return - } - - firstly { - self.versionService.fetchLatestVersion(lookupURL: lookupURL) - }.done { appStoreRecord in - guard appStoreRecord.version.compare(currentVersion, options: .numeric) == ComparisonResult.orderedDescending else { - Logger.debug("remote version: \(appStoreRecord) is not newer than currentVersion: \(currentVersion)") - return - } - - Logger.info("new version available: \(appStoreRecord)") - self.showUpdateNagIfEnoughTimeHasPassed(appStoreRecord: appStoreRecord) - }.catch { error in - Logger.error("failed with error: \(error)") - }.retainUntilComplete() - */ - } - - // MARK: - Internal - - let kUpgradeNagCollection = "TSStorageManagerAppUpgradeNagCollection" - let kLastNagDateKey = "TSStorageManagerAppUpgradeNagDate" - let kFirstHeardOfNewVersionDateKey = "TSStorageManagerAppUpgradeFirstHeardOfNewVersionDate" - - var dbConnection: YapDatabaseConnection { - return OWSPrimaryStorage.shared().dbReadWriteConnection - } - - // MARK: Bundle accessors - - var bundle: Bundle { - return Bundle.main - } - - var currentVersion: String? { - return bundle.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String - } - - var bundleIdentifier: String? { - return bundle.bundleIdentifier - } - - func lookupURL(bundleIdentifier: String) -> URL? { - return URL(string: "https://itunes.apple.com/lookup?bundleId=\(bundleIdentifier)") - } - - let versionService: AppStoreVersionService - - required init(versionService: AppStoreVersionService) { - self.versionService = versionService - super.init() - - SwiftSingletons.register(self) - } - - func showUpdateNagIfEnoughTimeHasPassed(appStoreRecord: AppStoreRecord) { - guard let firstHeardOfNewVersionDate = self.firstHeardOfNewVersionDate else { - self.setFirstHeardOfNewVersionDate(Date()) - return - } - - let intervalBeforeNag = 7 * kDayInterval - guard Date() > Date.init(timeInterval: intervalBeforeNag, since: firstHeardOfNewVersionDate) else { - Logger.info("firstHeardOfNewVersionDate: \(firstHeardOfNewVersionDate) not nagging for new release yet.") - return - } - - if let lastNagDate = self.lastNagDate { - let intervalBetweenNags = 14 * kDayInterval - guard Date() > Date.init(timeInterval: intervalBetweenNags, since: lastNagDate) else { - Logger.info("lastNagDate: \(lastNagDate) not nagging again so soon.") - return - } - } - - // Only show nag if we are "at rest" in the home view or registration view without any - // alerts or dialogs showing. - guard UIApplication.shared.frontmostViewController != nil else { - owsFailDebug("frontmostViewController was unexpectedly nil") - return - } - - /* - switch frontmostViewController { - case is OnboardingSplashViewController: - self.setLastNagDate(Date()) - self.clearFirstHeardOfNewVersionDate() - presentUpgradeNag(appStoreRecord: appStoreRecord) - default: - Logger.debug("not presenting alert due to frontmostViewController: \(frontmostViewController)") - break - } - */ - } - - func presentUpgradeNag(appStoreRecord: AppStoreRecord) { - let title = NSLocalizedString("APP_UPDATE_NAG_ALERT_TITLE", comment: "Title for the 'new app version available' alert.") - - let bodyFormat = NSLocalizedString("APP_UPDATE_NAG_ALERT_MESSAGE_FORMAT", comment: "Message format for the 'new app version available' alert. Embeds: {{The latest app version number}}") - let bodyText = String(format: bodyFormat, appStoreRecord.version) - let updateButtonText = NSLocalizedString("APP_UPDATE_NAG_ALERT_UPDATE_BUTTON", comment: "Label for the 'update' button in the 'new app version available' alert.") - let dismissButtonText = NSLocalizedString("APP_UPDATE_NAG_ALERT_DISMISS_BUTTON", comment: "Label for the 'dismiss' button in the 'new app version available' alert.") - - let alert = UIAlertController(title: title, message: bodyText, preferredStyle: .alert) - - let updateAction = UIAlertAction(title: updateButtonText, style: .default) { [weak self] _ in - guard let strongSelf = self else { - return - } - - strongSelf.showAppStore(appStoreURL: appStoreRecord.appStoreURL) - } - - alert.addAction(updateAction) - alert.addAction(UIAlertAction(title: dismissButtonText, style: .cancel, handler: nil)) - - OWSAlerts.showAlert(alert) - } - - func showAppStore(appStoreURL: URL) { - Logger.debug("") - UIApplication.shared.openURL(appStoreURL) - } - - // MARK: Storage - - var firstHeardOfNewVersionDate: Date? { - return self.dbConnection.date(forKey: kFirstHeardOfNewVersionDateKey, inCollection: kUpgradeNagCollection) - } - - func setFirstHeardOfNewVersionDate(_ date: Date) { - self.dbConnection.setDate(date, forKey: kFirstHeardOfNewVersionDateKey, inCollection: kUpgradeNagCollection) - } - - func clearFirstHeardOfNewVersionDate() { - self.dbConnection.removeObject(forKey: kFirstHeardOfNewVersionDateKey, inCollection: kUpgradeNagCollection) - } - - var lastNagDate: Date? { - return self.dbConnection.date(forKey: kLastNagDateKey, inCollection: kUpgradeNagCollection) - } - - func setLastNagDate(_ date: Date) { - self.dbConnection.setDate(date, forKey: kLastNagDateKey, inCollection: kUpgradeNagCollection) - } -} - -// MARK: Parsing Structs - -struct AppStoreLookupResultSet: Codable { - let resultCount: UInt - let results: [AppStoreRecord] -} - -struct AppStoreRecord: Codable { - let appStoreURL: URL - let version: String - - private enum CodingKeys: String, CodingKey { - case appStoreURL = "trackViewUrl" - case version - } -} - -class AppStoreVersionService: NSObject { - - // MARK: - - func fetchLatestVersion(lookupURL: URL) -> Promise { - Logger.debug("lookupURL:\(lookupURL)") - - let (promise, resolver) = Promise.pending() - - let task = URLSession.ephemeral.dataTask(with: lookupURL) { (data, _, error) in - guard let data = data else { - Logger.warn("data was unexpectedly nil") - resolver.reject(OWSErrorMakeUnableToProcessServerResponseError()) - return - } - - do { - let decoder = JSONDecoder() - let resultSet = try decoder.decode(AppStoreLookupResultSet.self, from: data) - guard let appStoreRecord = resultSet.results.first else { - Logger.warn("record was unexpectedly nil") - resolver.reject(OWSErrorMakeUnableToProcessServerResponseError()) - return - } - - resolver.fulfill(appStoreRecord) - } catch { - resolver.reject(error) - } - } - - task.resume() - - return promise - } -} - -extension URLSession { - static var ephemeral: URLSession { - return URLSession(configuration: .ephemeral) - } -} diff --git a/SessionMessagingKit/Database/Migrations/_003_YDBToGRDBMigration.swift b/SessionMessagingKit/Database/Migrations/_003_YDBToGRDBMigration.swift index 1d14576af..9497d4ce1 100644 --- a/SessionMessagingKit/Database/Migrations/_003_YDBToGRDBMigration.swift +++ b/SessionMessagingKit/Database/Migrations/_003_YDBToGRDBMigration.swift @@ -3,6 +3,7 @@ import Foundation import AVKit import GRDB +import YapDatabase import Curve25519Kit import SessionUtilitiesKit import SessionSnodeKit @@ -278,38 +279,49 @@ enum _003_YDBToGRDBMigration: Migration { // Note: The 'int(forKey:inCollection:)' defaults to `0` which is an incorrect value // for the notification sound so catch it and default - let globalNotificationSoundValue: Int32 = transaction.int( - forKey: SMKLegacy.soundsGlobalNotificationKey, - inCollection: SMKLegacy.soundsStorageNotificationCollection - ) - legacyPreferences[SMKLegacy.soundsGlobalNotificationKey] = (globalNotificationSoundValue > 0 ? - Int(globalNotificationSoundValue) : - Preferences.Sound.defaultNotificationSound.rawValue - ) + legacyPreferences[SMKLegacy.soundsGlobalNotificationKey] = (transaction + .object( + forKey: SMKLegacy.soundsGlobalNotificationKey, + inCollection: SMKLegacy.soundsStorageNotificationCollection + ) + .asType(NSNumber.self)? + .intValue) + .defaulting(to: Preferences.Sound.defaultNotificationSound.rawValue) - legacyPreferences[SMKLegacy.readReceiptManagerAreReadReceiptsEnabled] = transaction.bool( - forKey: SMKLegacy.readReceiptManagerAreReadReceiptsEnabled, - inCollection: SMKLegacy.readReceiptManagerCollection, - defaultValue: false - ) + legacyPreferences[SMKLegacy.readReceiptManagerAreReadReceiptsEnabled] = (transaction + .object( + forKey: SMKLegacy.readReceiptManagerAreReadReceiptsEnabled, + inCollection: SMKLegacy.readReceiptManagerCollection + ) + .asType(NSNumber.self)? + .boolValue) + .defaulting(to: false) - legacyPreferences[SMKLegacy.typingIndicatorsEnabledKey] = transaction.bool( - forKey: SMKLegacy.typingIndicatorsEnabledKey, - inCollection: SMKLegacy.typingIndicatorsCollection, - defaultValue: false - ) + legacyPreferences[SMKLegacy.typingIndicatorsEnabledKey] = (transaction + .object( + forKey: SMKLegacy.typingIndicatorsEnabledKey, + inCollection: SMKLegacy.typingIndicatorsCollection + ) + .asType(NSNumber.self)? + .boolValue) + .defaulting(to: false) - legacyPreferences[SMKLegacy.screenLockIsScreenLockEnabledKey] = transaction.bool( - forKey: SMKLegacy.screenLockIsScreenLockEnabledKey, - inCollection: SMKLegacy.screenLockCollection, - defaultValue: false - ) + legacyPreferences[SMKLegacy.screenLockIsScreenLockEnabledKey] = (transaction + .object( + forKey: SMKLegacy.screenLockIsScreenLockEnabledKey, + inCollection: SMKLegacy.screenLockCollection + ) + .asType(NSNumber.self)? + .boolValue) + .defaulting(to: false) - legacyPreferences[SMKLegacy.screenLockScreenLockTimeoutSecondsKey] = transaction.double( - forKey: SMKLegacy.screenLockScreenLockTimeoutSecondsKey, - inCollection: SMKLegacy.screenLockCollection, - defaultValue: (15 * 60) - ) + legacyPreferences[SMKLegacy.screenLockScreenLockTimeoutSecondsKey] = (transaction + .object( + forKey: SMKLegacy.screenLockScreenLockTimeoutSecondsKey, + inCollection: SMKLegacy.screenLockCollection) + .asType(NSNumber.self)? + .doubleValue) + .defaulting(to: (15 * 60)) GRDBStorage.shared.update(progress: 0.23, for: self, in: target) } diff --git a/SessionMessagingKit/Database/Notification+Contacts.swift b/SessionMessagingKit/Database/Notification+Contacts.swift index 6679490cf..a61ca1aa8 100644 --- a/SessionMessagingKit/Database/Notification+Contacts.swift +++ b/SessionMessagingKit/Database/Notification+Contacts.swift @@ -1,7 +1,7 @@ // Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. import SessionUtilitiesKit - +// FIXME: Remove these extensions once the OWSConversationSettingsViewModel is refactored to swift and uses proper database observation public extension Notification.Name { static let otherUsersProfileDidChange = Notification.Name("otherUsersProfileDidChange") diff --git a/SessionMessagingKit/Database/OWSBackupFragment.h b/SessionMessagingKit/Database/OWSBackupFragment.h deleted file mode 100644 index 392a7e73a..000000000 --- a/SessionMessagingKit/Database/OWSBackupFragment.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -// We store metadata for known backup fragments (i.e. CloudKit record) in -// the database. We might learn about them from: -// -// * Past backup exports. -// * An import downloading and parsing the manifest of the last complete backup. -// -// Storing this data in the database provides continuity. -// -// * Backup exports can reuse fragments from previous Backup exports even if they -// don't complete (i.e. backup export resume). -// * Backup exports can reuse fragments from the backup import, if any. -@interface OWSBackupFragment : TSYapDatabaseObject - -@property (nonatomic) NSString *recordName; - -@property (nonatomic) NSData *encryptionKey; - -// This property is only set for certain types of manifest item, -// namely attachments where we need to know where the attachment's -// file should reside relative to the attachments folder. -@property (nonatomic, nullable) NSString *relativeFilePath; - -// This property is only set for attachments. -@property (nonatomic, nullable) NSString *attachmentId; - -// This property is only set if the manifest item is downloaded. -@property (nonatomic, nullable) NSString *downloadFilePath; - -// This property is only set if the manifest item is compressed. -@property (nonatomic, nullable) NSNumber *uncompressedDataLength; - -- (instancetype)init NS_UNAVAILABLE; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/Database/OWSBackupFragment.m b/SessionMessagingKit/Database/OWSBackupFragment.m deleted file mode 100644 index 87627f26f..000000000 --- a/SessionMessagingKit/Database/OWSBackupFragment.m +++ /dev/null @@ -1,13 +0,0 @@ -// -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. -// - -#import "OWSBackupFragment.h" - -NS_ASSUME_NONNULL_BEGIN - -@implementation OWSBackupFragment - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/Database/OWSPrimaryStorage.h b/SessionMessagingKit/Database/OWSPrimaryStorage.h deleted file mode 100644 index 269ad1fc9..000000000 --- a/SessionMessagingKit/Database/OWSPrimaryStorage.h +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -extern NSString *const OWSUIDatabaseConnectionWillUpdateNotification; -extern NSString *const OWSUIDatabaseConnectionDidUpdateNotification; -extern NSString *const OWSUIDatabaseConnectionWillUpdateExternallyNotification; -extern NSString *const OWSUIDatabaseConnectionDidUpdateExternallyNotification; -extern NSString *const OWSUIDatabaseConnectionNotificationsKey; - -@interface OWSPrimaryStorage : OWSStorage - -- (instancetype)init NS_UNAVAILABLE; - -- (instancetype)initStorage; - -+ (instancetype)sharedManager NS_SWIFT_NAME(shared()); - -@property (nonatomic, readonly) YapDatabaseConnection *uiDatabaseConnection; -@property (nonatomic, readonly) YapDatabaseConnection *dbReadConnection; -@property (nonatomic, readonly) YapDatabaseConnection *dbReadWriteConnection; - -- (void)updateUIDatabaseConnectionToLatest; - -+ (YapDatabaseConnection *)dbReadConnection; -+ (YapDatabaseConnection *)dbReadWriteConnection; - -+ (nullable NSError *)migrateToSharedData; - -+ (NSString *)databaseFilePath; - -+ (NSString *)legacyDatabaseFilePath; -+ (NSString *)legacyDatabaseFilePath_SHM; -+ (NSString *)legacyDatabaseFilePath_WAL; -+ (NSString *)sharedDataDatabaseFilePath; -+ (NSString *)sharedDataDatabaseFilePath_SHM; -+ (NSString *)sharedDataDatabaseFilePath_WAL; - -+ (void)protectFiles; - -#pragma mark - Misc. - -- (void)touchDbAsync; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/Database/OWSPrimaryStorage.m b/SessionMessagingKit/Database/OWSPrimaryStorage.m deleted file mode 100644 index fd1cc007e..000000000 --- a/SessionMessagingKit/Database/OWSPrimaryStorage.m +++ /dev/null @@ -1,382 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import "OWSPrimaryStorage.h" -#import "AppContext.h" -#import "OWSFileSystem.h" -#import -#import "OWSStorage.h" -#import "OWSStorage+Subclass.h" -#import "TSDatabaseSecondaryIndexes.h" -#import "TSDatabaseView.h" -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -NSString *const OWSUIDatabaseConnectionWillUpdateNotification = @"OWSUIDatabaseConnectionWillUpdateNotification"; -NSString *const OWSUIDatabaseConnectionDidUpdateNotification = @"OWSUIDatabaseConnectionDidUpdateNotification"; -NSString *const OWSUIDatabaseConnectionWillUpdateExternallyNotification = @"OWSUIDatabaseConnectionWillUpdateExternallyNotification"; -NSString *const OWSUIDatabaseConnectionDidUpdateExternallyNotification = @"OWSUIDatabaseConnectionDidUpdateExternallyNotification"; - -NSString *const OWSUIDatabaseConnectionNotificationsKey = @"OWSUIDatabaseConnectionNotificationsKey"; - -void VerifyRegistrationsForPrimaryStorage(OWSStorage *storage) -{ - [[storage newDatabaseConnection] asyncReadWithBlock:^(YapDatabaseReadTransaction *transaction) { - for (NSString *extensionName in storage.registeredExtensionNames) { - YapDatabaseViewTransaction *_Nullable viewTransaction = [transaction ext:extensionName]; - if (!viewTransaction) { - [OWSStorage incrementVersionOfDatabaseExtension:extensionName]; - } - } - }]; -} - -#pragma mark - - -@interface OWSPrimaryStorage () - -@property (atomic) BOOL areAsyncRegistrationsComplete; -@property (atomic) BOOL areSyncRegistrationsComplete; -@property (nonatomic, readonly) YapDatabaseConnectionPool *dbReadPool; - -@end - -#pragma mark - - -@implementation OWSPrimaryStorage - -@synthesize uiDatabaseConnection = _uiDatabaseConnection; - -+ (instancetype)sharedManager -{ - return SSKEnvironment.shared.primaryStorage; -} - -- (instancetype)initStorage -{ - self = [super initStorage]; - - if (self) { - [self loadDatabase]; - - _dbReadPool = [[YapDatabaseConnectionPool alloc] initWithDatabase:self.database]; - _dbReadPool.connectionLimit = 10; // Increase max read connection limit. Default is 3. - _dbReadWriteConnection = [self newDatabaseConnection]; - _uiDatabaseConnection = [self newDatabaseConnection]; - - // Increase object cache limit. Default is 250. - _uiDatabaseConnection.objectCacheLimit = 500; - [_uiDatabaseConnection beginLongLivedReadTransaction]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(yapDatabaseModified:) - name:YapDatabaseModifiedNotification - object:self.dbNotificationObject]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(yapDatabaseModifiedExternally:) - name:YapDatabaseModifiedExternallyNotification - object:nil]; - } - - return self; -} - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (void)yapDatabaseModifiedExternally:(NSNotification *)notification -{ - // Notify observers we're about to update the database connection - [[NSNotificationCenter defaultCenter] postNotificationName:OWSUIDatabaseConnectionWillUpdateExternallyNotification object:self.dbNotificationObject]; - - // Move uiDatabaseConnection to the latest commit. - // Do so atomically, and fetch all the notifications for each commit we jump. - NSArray *notifications = [self.uiDatabaseConnection beginLongLivedReadTransaction]; - - // Notify observers that the uiDatabaseConnection was updated - NSDictionary *userInfo = @{ OWSUIDatabaseConnectionNotificationsKey: notifications }; - [[NSNotificationCenter defaultCenter] postNotificationName:OWSUIDatabaseConnectionDidUpdateExternallyNotification - object:self.dbNotificationObject - userInfo:userInfo]; -} - -- (void)yapDatabaseModified:(NSNotification *)notification -{ - [self updateUIDatabaseConnectionToLatest]; -} - -- (void)updateUIDatabaseConnectionToLatest -{ - // Notify observers we're about to update the database connection - [[NSNotificationCenter defaultCenter] postNotificationName:OWSUIDatabaseConnectionWillUpdateNotification object:self.dbNotificationObject]; - - // Move uiDatabaseConnection to the latest commit. - // Do so atomically, and fetch all the notifications for each commit we jump. - NSArray *notifications = [self.uiDatabaseConnection beginLongLivedReadTransaction]; - - // Notify observers that the uiDatabaseConnection was updated - NSDictionary *userInfo = @{ OWSUIDatabaseConnectionNotificationsKey: notifications }; - [[NSNotificationCenter defaultCenter] postNotificationName:OWSUIDatabaseConnectionDidUpdateNotification - object:self.dbNotificationObject - userInfo:userInfo]; -} - -- (YapDatabaseConnection *)uiDatabaseConnection -{ - return _uiDatabaseConnection; -} - -- (void)resetStorage -{ - _dbReadPool = nil; - _uiDatabaseConnection = nil; - _dbReadWriteConnection = nil; - - [super resetStorage]; -} - -- (void)runSyncRegistrations -{ - // Synchronously register extensions which are essential for views. - [TSDatabaseView registerCrossProcessNotifier:self]; - - // See comments on OWSDatabaseConnection. - // - // In the absence of finding documentation that can shed light on the issue we've been - // seeing, this issue only seems to affect sync and not async registrations. We've always - // been opening write transactions before the async registrations complete without negative - // consequences. - - self.areSyncRegistrationsComplete = YES; -} - -- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion -{ - // Asynchronously register other extensions. - // - // All sync registrations must be done before all async registrations, - // or the sync registrations will block on the async registrations. - [TSDatabaseView asyncRegisterLegacyThreadInteractionsDatabaseView:self]; - [TSDatabaseView asyncRegisterThreadInteractionsDatabaseView:self]; - [TSDatabaseView asyncRegisterThreadDatabaseView:self]; - [self asyncRegisterExtension:[TSDatabaseSecondaryIndexes registerTimeStampIndex] - withName:[TSDatabaseSecondaryIndexes registerTimeStampIndexExtensionName]]; - - [TSDatabaseView asyncRegisterUnreadMentionDatabaseView:self]; - [TSDatabaseView asyncRegisterThreadOutgoingMessagesDatabaseView:self]; - - [FullTextSearchFinder asyncRegisterDatabaseExtensionWithStorage:self]; - [TSDatabaseView asyncRegisterLazyRestoreAttachmentsDatabaseView:self]; - - [self.database - flushExtensionRequestsWithCompletionQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) - completionBlock:^{ - self.areAsyncRegistrationsComplete = YES; - - completion(); - - [self verifyDatabaseViews]; - }]; -} - -- (void)verifyDatabaseViews -{ - VerifyRegistrationsForPrimaryStorage(self); -} - -+ (void)protectFiles -{ - // Protect the entire new database directory. - [OWSFileSystem protectFileOrFolderAtPath:self.sharedDataDatabaseDirPath]; -} - -+ (NSString *)legacyDatabaseDirPath -{ - return [OWSFileSystem appDocumentDirectoryPath]; -} - -+ (NSString *)sharedDataDatabaseDirPath -{ - NSString *databaseDirPath = [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"database"]; - - [OWSFileSystem ensureDirectoryExists:databaseDirPath]; - return databaseDirPath; -} - -+ (NSString *)databaseFilename -{ - return @"Signal.sqlite"; -} - -+ (NSString *)databaseFilename_SHM -{ - return [self.databaseFilename stringByAppendingString:@"-shm"]; -} - -+ (NSString *)databaseFilename_WAL -{ - return [self.databaseFilename stringByAppendingString:@"-wal"]; -} - -+ (NSString *)legacyDatabaseFilePath -{ - return [self.legacyDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename]; -} - -+ (NSString *)legacyDatabaseFilePath_SHM -{ - return [self.legacyDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM]; -} - -+ (NSString *)legacyDatabaseFilePath_WAL -{ - return [self.legacyDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL]; -} - -+ (NSString *)sharedDataDatabaseFilePath -{ - return [self.sharedDataDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename]; -} - -+ (NSString *)sharedDataDatabaseFilePath_SHM -{ - return [self.sharedDataDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM]; -} - -+ (NSString *)sharedDataDatabaseFilePath_WAL -{ - return [self.sharedDataDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL]; -} - -+ (nullable NSError *)migrateToSharedData -{ - // Given how sensitive this migration is, we verbosely - // log the contents of all involved paths before and after. - NSFileManager *fileManager = [NSFileManager defaultManager]; - - // We protect the db files here, which is somewhat redundant with what will happen in - // `moveAppFilePath:` which also ensures file protection. - // However that method dispatches async, since it can take a while with large attachment directories. - // - // Since we only have three files here it'll be quick to do it sync, and we want to make - // sure it happens as part of the migration. - // - // FileProtection attributes move with the file, so we do it on the legacy files before moving - // them. - [OWSFileSystem protectFileOrFolderAtPath:self.legacyDatabaseFilePath]; - [OWSFileSystem protectFileOrFolderAtPath:self.legacyDatabaseFilePath_SHM]; - [OWSFileSystem protectFileOrFolderAtPath:self.legacyDatabaseFilePath_WAL]; - - NSError *_Nullable error = nil; - if ([fileManager fileExistsAtPath:self.legacyDatabaseFilePath] && - [fileManager fileExistsAtPath:self.sharedDataDatabaseFilePath]) { - // In the case that we have a "database conflict" (i.e. database files - // in the src and dst locations), ensure database integrity by renaming - // all of the dst database files. - for (NSString *filePath in @[ - self.sharedDataDatabaseFilePath, - self.sharedDataDatabaseFilePath_SHM, - self.sharedDataDatabaseFilePath_WAL, - ]) { - error = [OWSFileSystem renameFilePathUsingRandomExtension:filePath]; - if (error) { - return error; - } - } - } - - error = - [OWSFileSystem moveAppFilePath:self.legacyDatabaseFilePath sharedDataFilePath:self.sharedDataDatabaseFilePath]; - if (error) { - return error; - } - error = [OWSFileSystem moveAppFilePath:self.legacyDatabaseFilePath_SHM - sharedDataFilePath:self.sharedDataDatabaseFilePath_SHM]; - if (error) { - return error; - } - error = [OWSFileSystem moveAppFilePath:self.legacyDatabaseFilePath_WAL - sharedDataFilePath:self.sharedDataDatabaseFilePath_WAL]; - if (error) { - return error; - } - - return nil; -} - -+ (NSString *)databaseFilePath -{ - return self.sharedDataDatabaseFilePath; -} - -+ (NSString *)databaseFilePath_SHM -{ - return self.sharedDataDatabaseFilePath_SHM; -} - -+ (NSString *)databaseFilePath_WAL -{ - return self.sharedDataDatabaseFilePath_WAL; -} - -- (NSString *)databaseFilePath -{ - return OWSPrimaryStorage.databaseFilePath; -} - -- (NSString *)databaseFilePath_SHM -{ - return OWSPrimaryStorage.databaseFilePath_SHM; -} - -- (NSString *)databaseFilePath_WAL -{ - return OWSPrimaryStorage.databaseFilePath_WAL; -} - -- (NSString *)databaseFilename_SHM -{ - return OWSPrimaryStorage.databaseFilename_SHM; -} - -- (NSString *)databaseFilename_WAL -{ - return OWSPrimaryStorage.databaseFilename_WAL; -} - -+ (YapDatabaseConnection *)dbReadConnection -{ - return OWSPrimaryStorage.sharedManager.dbReadConnection; -} - -- (YapDatabaseConnection *)dbReadConnection -{ - return self.dbReadPool.connection; -} - -+ (YapDatabaseConnection *)dbReadWriteConnection -{ - return OWSPrimaryStorage.sharedManager.dbReadWriteConnection; -} - -#pragma mark - Misc. - -- (void)touchDbAsync -{ - // There appears to be a bug in YapDatabase that sometimes delays modifications - // made in another process (e.g. the SAE) from showing up in other processes. - // There's a simple workaround: a trivial write to the database flushes changes - // made from other processes. - [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [transaction setObject:[NSUUID UUID].UUIDString forKey:@"conversation_view_noop_mod" inCollection:@"temp"]; - }]; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/Database/OWSStorage+Subclass.h b/SessionMessagingKit/Database/OWSStorage+Subclass.h deleted file mode 100644 index 9f3fd0be1..000000000 --- a/SessionMessagingKit/Database/OWSStorage+Subclass.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@class YapDatabase; - -@interface OWSStorage (Subclass) - -@property (atomic, nullable, readonly) YapDatabase *database; - -- (void)loadDatabase; - -- (void)runSyncRegistrations; -// completion will be invoked _off_ the main thread. -- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion; - -- (BOOL)areAsyncRegistrationsComplete; -- (BOOL)areSyncRegistrationsComplete; - -- (NSString *)databaseFilePath; -- (NSString *)databaseFilePath_SHM; -- (NSString *)databaseFilePath_WAL; - -- (void)resetStorage; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/Database/OWSStorage.h b/SessionMessagingKit/Database/OWSStorage.h deleted file mode 100644 index 386794369..000000000 --- a/SessionMessagingKit/Database/OWSStorage.h +++ /dev/null @@ -1,116 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -extern NSString *const StorageIsReadyNotification; - -@class YapDatabaseExtension; - -@protocol OWSDatabaseConnectionDelegate - -- (BOOL)areAllRegistrationsComplete; - -@end - -#pragma mark - - -@interface OWSDatabaseConnection : YapDatabaseConnection - -@property (atomic, weak) id delegate; - -- (instancetype)init NS_UNAVAILABLE; -- (instancetype)initWithDatabase:(YapDatabase *)database - delegate:(id)delegate NS_DESIGNATED_INITIALIZER; - -@end - -#pragma mark - - -@interface OWSDatabase : YapDatabase - -- (instancetype)init NS_UNAVAILABLE; - -- (id)initWithPath:(NSString *)inPath - serializer:(nullable YapDatabaseSerializer)inSerializer - deserializer:(YapDatabaseDeserializer)inDeserializer - options:(YapDatabaseOptions *)inOptions - delegate:(id)delegate NS_DESIGNATED_INITIALIZER; - -@end - -#pragma mark - - -typedef void (^OWSStorageMigrationBlock)(void); - -@interface OWSStorage : NSObject - -- (instancetype)init NS_UNAVAILABLE; -- (instancetype)initStorage NS_DESIGNATED_INITIALIZER; - -// Returns YES if _ALL_ storage classes have completed both their -// sync _AND_ async view registrations. -+ (BOOL)isStorageReady; - -// This object can be used to filter database notifications. -@property (nonatomic, readonly, nullable) id dbNotificationObject; - -// migrationBlock will be invoked _off_ the main thread. -+ (void)registerExtensionsWithMigrationBlock:(OWSStorageMigrationBlock)migrationBlock; - -#ifdef DEBUG -- (void)closeStorageForTests; -#endif - -+ (void)resetAllStorage; - -- (YapDatabaseConnection *)newDatabaseConnection; - -+ (YapDatabaseOptions *)defaultDatabaseOptions; - -#pragma mark - Extension Registration - -+ (void)incrementVersionOfDatabaseExtension:(NSString *)extensionName; - -- (BOOL)registerExtension:(YapDatabaseExtension *)extension withName:(NSString *)extensionName; - -- (void)asyncRegisterExtension:(YapDatabaseExtension *)extension withName:(NSString *)extensionName; -- (void)asyncRegisterExtension:(YapDatabaseExtension *)extension - withName:(NSString *)extensionName - completion:(nullable dispatch_block_t)completion; - -- (nullable id)registeredExtension:(NSString *)extensionName; - -- (NSArray *)registeredExtensionNames; - -#pragma mark - - -- (unsigned long long)databaseFileSize; -- (unsigned long long)databaseWALFileSize; -- (unsigned long long)databaseSHMFileSize; - -- (YapDatabaseConnection *)registrationConnection; - -#pragma mark - Password - -/** - * Returns NO if: - * - * - Keychain is locked because device has just been restarted. - * - Password could not be retrieved because of a keychain error. - */ -+ (BOOL)isDatabasePasswordAccessible; - -+ (nullable NSData *)tryToLoadDatabaseLegacyPassphrase:(NSError **)errorHandle; -+ (void)removeLegacyPassphrase; - -+ (void)storeDatabaseCipherKeySpec:(NSData *)cipherKeySpecData; - -- (void)logFileSizes; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/Database/OWSStorage.m b/SessionMessagingKit/Database/OWSStorage.m deleted file mode 100644 index b3f07ce8e..000000000 --- a/SessionMessagingKit/Database/OWSStorage.m +++ /dev/null @@ -1,808 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import "OWSStorage.h" -#import "AppContext.h" -#import "OWSBackgroundTask.h" -#import "OWSFileSystem.h" -#import "OWSPrimaryStorage.h" -#import "TSYapDatabaseObject.h" -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -NSString *const StorageIsReadyNotification = @"StorageIsReadyNotification"; -NSString *const OWSResetStorageNotification = @"OWSResetStorageNotification"; - -static NSString *keychainService = @"TSKeyChainService"; -static NSString *keychainDBLegacyPassphrase = @"TSDatabasePass"; -static NSString *keychainDBCipherKeySpec = @"OWSDatabaseCipherKeySpec"; - -const NSUInteger kDatabasePasswordLength = 30; - -typedef NSData *_Nullable (^LoadDatabaseMetadataBlock)(NSError **_Nullable); -typedef NSData *_Nullable (^CreateDatabaseMetadataBlock)(void); - -NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_DatabaseExtensionVersionMap"; - -#pragma mark - - -@interface YapDatabaseConnection () - -- (id)initWithDatabase:(YapDatabase *)database; - -@end - -#pragma mark - - -@implementation OWSDatabaseConnection - -- (id)initWithDatabase:(YapDatabase *)database delegate:(id)delegate -{ - self = [super initWithDatabase:database]; - - if (!self) { - return self; - } - - self.delegate = delegate; - - return self; -} - -// Assert that the database is in a ready state (specifically that any sync database -// view registrations have completed and any async registrations have been started) -// before creating write transactions. -// -// Creating write transactions before the _sync_ database views are registered -// causes YapDatabase to rebuild all of our database views, which is catastrophic. -// Specifically, it causes YDB's "view version" checks to fail. -- (void)readWriteWithBlock:(void (^)(YapDatabaseReadWriteTransaction *transaction))block -{ - OWSBackgroundTask *_Nullable backgroundTask = nil; - if (CurrentAppContext().isMainApp && !CurrentAppContext().isRunningTests) { - backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; - } - [super readWriteWithBlock:block]; - backgroundTask = nil; -} - -- (void)asyncReadWriteWithBlock:(void (^)(YapDatabaseReadWriteTransaction *transaction))block -{ - [self asyncReadWriteWithBlock:block completionQueue:NULL completionBlock:NULL]; -} - -- (void)asyncReadWriteWithBlock:(void (^)(YapDatabaseReadWriteTransaction *transaction))block - completionBlock:(nullable dispatch_block_t)completionBlock -{ - [self asyncReadWriteWithBlock:block completionQueue:NULL completionBlock:completionBlock]; -} - -- (void)asyncReadWriteWithBlock:(void (^)(YapDatabaseReadWriteTransaction *transaction))block - completionQueue:(nullable dispatch_queue_t)completionQueue - completionBlock:(nullable dispatch_block_t)completionBlock -{ - __block OWSBackgroundTask *_Nullable backgroundTask = nil; - if (CurrentAppContext().isMainApp) { - backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; - } - [super asyncReadWriteWithBlock:block completionQueue:completionQueue completionBlock:^{ - if (completionBlock) { - completionBlock(); - } - backgroundTask = nil; - }]; -} - -@end - -#pragma mark - - -// This class is only used in DEBUG builds. -@interface YapDatabase () - -- (void)addConnection:(YapDatabaseConnection *)connection; - -- (YapDatabaseConnection *)registrationConnection; - -@end - -#pragma mark - - -@interface OWSDatabase () - -@property (atomic, weak) id delegate; - -@end - -#pragma mark - - -@implementation OWSDatabase - -- (id)initWithPath:(NSString *)inPath - serializer:(nullable YapDatabaseSerializer)inSerializer - deserializer:(YapDatabaseDeserializer)inDeserializer - options:(YapDatabaseOptions *)inOptions - delegate:(id)delegate -{ - self = [super initWithPath:inPath serializer:inSerializer deserializer:inDeserializer options:inOptions]; - - if (!self) { - return self; - } - - self.delegate = delegate; - - return self; -} - -// This clobbers the superclass implementation to include asserts which -// ensure that the database is in a ready state before creating write transactions. -// -// See comments in OWSDatabaseConnection. -- (YapDatabaseConnection *)newConnection -{ - id delegate = self.delegate; - - OWSDatabaseConnection *connection = [[OWSDatabaseConnection alloc] initWithDatabase:self delegate:delegate]; - [self addConnection:connection]; - return connection; -} - -- (YapDatabaseConnection *)registrationConnection -{ - YapDatabaseConnection *connection = [super registrationConnection]; - return connection; -} - -@end - -#pragma mark - - -@interface OWSUnknownDBObject : TSYapDatabaseObject - -@end - -#pragma mark - - -/** - * A default object to return when we can't deserialize an object from YapDB. This can prevent crashes when - * old objects linger after their definition file is removed. The danger is that, the objects can lay in wait - * until the next time a DB extension is added and we necessarily enumerate the entire DB. - */ -@implementation OWSUnknownDBObject - -- (void)encodeWithCoder:(NSCoder *)aCoder -{ - return [super encodeWithCoder:aCoder]; -} - -- (nullable instancetype)initWithCoder:(NSCoder *)coder -{ - self = [super initWithCoder:coder]; - if (!self) { - return self; - } - - return self; -} - -- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction -{ - // No-op. -} - -- (void)touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction -{ - // No-op. -} - -- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction -{ - // No-op. -} - -@end - -#pragma mark - - -@interface OWSUnarchiverDelegate : NSObject - -@end - -#pragma mark - - -@implementation OWSUnarchiverDelegate - -- (nullable Class)unarchiver:(NSKeyedUnarchiver *)unarchiver - cannotDecodeObjectOfClassName:(NSString *)name - originalClasses:(NSArray *)classNames -{ - return [OWSUnknownDBObject class]; -} - -@end - -#pragma mark - - -@interface OWSStorage () - -@property (atomic, nullable) YapDatabase *database; - -@property (nonatomic) NSMutableArray *extensionNames; - -@end - -#pragma mark - - -@implementation OWSStorage - -- (instancetype)initStorage -{ - self = [super init]; - - if (self) { - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(resetStorage) - name:OWSResetStorageNotification - object:nil]; - - self.extensionNames = [NSMutableArray new]; - } - - return self; -} - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (void)loadDatabase -{ - if (![self tryToLoadDatabase]) { - // Failing to load the database is catastrophic. - // - // The best we can try to do is to discard the current database - // and behave like a clean install. - - // Try to reset app by deleting all databases. - // - // TODO: Possibly clean up all app files. - // [OWSStorage deleteDatabaseFiles]; - - if (![self tryToLoadDatabase]) { - - // Sleep to give analytics events time to be delivered. - [NSThread sleepForTimeInterval:15.0f]; - - NSAssert(NO, @"Couldn't load database"); - } - } -} - -- (nullable id)dbNotificationObject -{ - return self.database; -} - -- (BOOL)areAsyncRegistrationsComplete -{ - return NO; -} - -- (BOOL)areSyncRegistrationsComplete -{ - return NO; -} - -- (BOOL)areAllRegistrationsComplete -{ - return self.areSyncRegistrationsComplete && self.areAsyncRegistrationsComplete; -} - -- (void)runSyncRegistrations -{ - -} - -- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion -{ - -} - -+ (void)registerExtensionsWithMigrationBlock:(OWSStorageMigrationBlock)migrationBlock -{ - __block OWSBackgroundTask *_Nullable backgroundTask = - [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; - - [OWSPrimaryStorage.sharedManager runSyncRegistrations]; - - [OWSPrimaryStorage.sharedManager runAsyncRegistrationsWithCompletion:^{ - [self postRegistrationCompleteNotification]; - - migrationBlock(); - - backgroundTask = nil; - }]; -} - -- (YapDatabaseConnection *)registrationConnection -{ - return self.database.registrationConnection; -} - -// Returns YES IFF all registrations are complete. -+ (void)postRegistrationCompleteNotification -{ - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - [[NSNotificationCenter defaultCenter] postNotificationNameAsync:StorageIsReadyNotification - object:nil - userInfo:nil]; - }); -} - -+ (BOOL)isStorageReady -{ - return OWSPrimaryStorage.sharedManager.areAllRegistrationsComplete; -} - -+ (YapDatabaseOptions *)defaultDatabaseOptions -{ - YapDatabaseOptions *options = [[YapDatabaseOptions alloc] init]; - options.corruptAction = YapDatabaseCorruptAction_Fail; - options.enableMultiProcessSupport = YES; - - // We leave a portion of the header decrypted so that iOS will recognize the file - // as a SQLite database. Otherwise, because the database lives in a shared data container, - // and our usage of sqlite's write-ahead logging retains a lock on the database, the OS - // would kill the app/share extension as soon as it is backgrounded. - options.cipherUnencryptedHeaderLength = kSqliteHeaderLength; - - // If we want to migrate to the new cipher defaults in SQLCipher4+ we'll need to do a one time - // migration. See the `PRAGMA cipher_migrate` documentation for details. - // https://www.zetetic.net/sqlcipher/sqlcipher-api/#cipher_migrate - options.legacyCipherCompatibilityVersion = 3; - - return options; -} - -- (BOOL)tryToLoadDatabase -{ - __weak OWSStorage *weakSelf = self; - YapDatabaseOptions *options = [self.class defaultDatabaseOptions]; - options.cipherKeySpecBlock = ^{ - // NOTE: It's critical that we don't capture a reference to self - // (e.g. by using OWSAssertDebug()) or this database will contain a - // circular reference and will leak. - OWSStorage *strongSelf = weakSelf; - - // Rather than compute this once and capture the value of the key - // in the closure, we prefer to fetch the key from the keychain multiple times - // in order to keep the key out of application memory. - NSData *databaseKeySpec = [strongSelf databaseKeySpec]; - return databaseKeySpec; - }; - - // Sanity checking elsewhere asserts we should only regenerate key specs when - // there is no existing database, so rather than lazily generate in the cipherKeySpecBlock - // we must ensure the keyspec exists before we create the database. - [self ensureDatabaseKeySpecExists]; - - OWSDatabase *database = [[OWSDatabase alloc] initWithPath:[self databaseFilePath] - serializer:nil - deserializer:[[self class] logOnFailureDeserializer] - options:options - delegate:self]; - - if (!database) { - return NO; - } - - _database = database; - - return YES; -} - -/** - * NSCoding sometimes throws exceptions killing our app. We want to log that exception. - **/ -+ (YapDatabaseDeserializer)logOnFailureDeserializer -{ - OWSUnarchiverDelegate *unarchiverDelegate = [OWSUnarchiverDelegate new]; - - return ^id(NSString __unused *collection, NSString __unused *key, NSData *data) { - if (!data || data.length <= 0) { - return [OWSUnknownDBObject new]; - } - - @try { - NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; - unarchiver.delegate = unarchiverDelegate; - return [unarchiver decodeObjectForKey:@"root"]; - } @catch (NSException *exception) { - // Sync log in case we bail - @throw exception; - } - }; -} - -- (YapDatabaseConnection *)newDatabaseConnection -{ - YapDatabaseConnection *dbConnection = self.database.newConnection; - return dbConnection; -} - -#pragma mark - Extension Registration - -+ (void)incrementVersionOfDatabaseExtension:(NSString *)extensionName -{ - // Don't increment version of a given extension more than once - // per launch. - static NSMutableSet *incrementedViewSet = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - incrementedViewSet = [NSMutableSet new]; - }); - @synchronized(incrementedViewSet) { - if ([incrementedViewSet containsObject:extensionName]) { - return; - } - [incrementedViewSet addObject:extensionName]; - } - - NSUserDefaults *appUserDefaults = [NSUserDefaults appUserDefaults]; - NSMutableDictionary *_Nullable versionMap = - [[appUserDefaults valueForKey:kNSUserDefaults_DatabaseExtensionVersionMap] mutableCopy]; - if (!versionMap) { - versionMap = [NSMutableDictionary new]; - } - NSNumber *_Nullable versionSuffix = versionMap[extensionName]; - versionMap[extensionName] = @(versionSuffix.intValue + 1); - [appUserDefaults setValue:versionMap forKey:kNSUserDefaults_DatabaseExtensionVersionMap]; - [appUserDefaults synchronize]; -} - -- (nullable NSString *)appendSuffixToDatabaseExtensionVersionIfNecessary:(nullable NSString *)versionTag - extensionName:(NSString *)extensionName -{ - NSUserDefaults *appUserDefaults = [NSUserDefaults appUserDefaults]; - NSDictionary *_Nullable versionMap = - [appUserDefaults valueForKey:kNSUserDefaults_DatabaseExtensionVersionMap]; - NSNumber *_Nullable versionSuffix = versionMap[extensionName]; - - if (versionSuffix) { - NSString *result = - [NSString stringWithFormat:@"%@.%@", (versionTag.length < 1 ? @"0" : versionTag), versionSuffix]; - return result; - } - return versionTag; -} - -- (YapDatabaseExtension *)updateExtensionVersion:(YapDatabaseExtension *)extension withName:(NSString *)extensionName -{ - if ([extension isKindOfClass:[YapDatabaseAutoView class]]) { - YapDatabaseAutoView *databaseView = (YapDatabaseAutoView *)extension; - YapDatabaseAutoView *databaseViewCopy = [[YapDatabaseAutoView alloc] - initWithGrouping:databaseView.grouping - sorting:databaseView.sorting - versionTag:[self appendSuffixToDatabaseExtensionVersionIfNecessary:databaseView.versionTag - extensionName:extensionName] - options:databaseView.options]; - return databaseViewCopy; - } else if ([extension isKindOfClass:[YapDatabaseSecondaryIndex class]]) { - YapDatabaseSecondaryIndex *secondaryIndex = (YapDatabaseSecondaryIndex *)extension; - YapDatabaseSecondaryIndex *secondaryIndexCopy = [[YapDatabaseSecondaryIndex alloc] - initWithSetup:secondaryIndex->setup - handler:secondaryIndex->handler - versionTag:[self appendSuffixToDatabaseExtensionVersionIfNecessary:secondaryIndex.versionTag - extensionName:extensionName] - options:secondaryIndex->options]; - return secondaryIndexCopy; - } else if ([extension isKindOfClass:[YapDatabaseFullTextSearch class]]) { - YapDatabaseFullTextSearch *fullTextSearch = (YapDatabaseFullTextSearch *)extension; - - NSString *versionTag = [self appendSuffixToDatabaseExtensionVersionIfNecessary:fullTextSearch.versionTag extensionName:extensionName]; - YapDatabaseFullTextSearch *fullTextSearchCopy = - [[YapDatabaseFullTextSearch alloc] initWithColumnNames:fullTextSearch->columnNames.array - options:fullTextSearch->options - handler:fullTextSearch->handler - ftsVersion:fullTextSearch->ftsVersion - versionTag:versionTag]; - - return fullTextSearchCopy; - } else if ([extension isKindOfClass:[YapDatabaseCrossProcessNotification class]]) { - // versionTag doesn't matter for YapDatabaseCrossProcessNotification. - return extension; - } else { - // This method needs to be able to update the versionTag of all extensions. - // If we start using other extension types, we need to modify this method to - // handle them as well. - - return extension; - } -} - -- (BOOL)registerExtension:(YapDatabaseExtension *)extension withName:(NSString *)extensionName -{ - extension = [self updateExtensionVersion:extension withName:extensionName]; - - [self.extensionNames addObject:extensionName]; - - return [self.database registerExtension:extension withName:extensionName]; -} - -- (void)asyncRegisterExtension:(YapDatabaseExtension *)extension - withName:(NSString *)extensionName -{ - [self asyncRegisterExtension:extension withName:extensionName completion:nil]; -} - -- (void)asyncRegisterExtension:(YapDatabaseExtension *)extension - withName:(NSString *)extensionName - completion:(nullable dispatch_block_t)completion -{ - extension = [self updateExtensionVersion:extension withName:extensionName]; - - [self.extensionNames addObject:extensionName]; - - [self.database asyncRegisterExtension:extension - withName:extensionName - completionBlock:^(BOOL ready) { - dispatch_async(dispatch_get_main_queue(), ^{ - if (completion) { - completion(); - } - }); - }]; -} - -- (nullable id)registeredExtension:(NSString *)extensionName -{ - return [self.database registeredExtension:extensionName]; -} - -- (NSArray *)registeredExtensionNames -{ - return [self.extensionNames copy]; -} - -#pragma mark - Password - -+ (void)deleteDatabaseFiles -{ - [OWSFileSystem deleteFile:[OWSPrimaryStorage legacyDatabaseFilePath]]; - [OWSFileSystem deleteFile:[OWSPrimaryStorage legacyDatabaseFilePath_SHM]]; - [OWSFileSystem deleteFile:[OWSPrimaryStorage legacyDatabaseFilePath_WAL]]; - [OWSFileSystem deleteFile:[OWSPrimaryStorage sharedDataDatabaseFilePath]]; - [OWSFileSystem deleteFile:[OWSPrimaryStorage sharedDataDatabaseFilePath_SHM]]; - [OWSFileSystem deleteFile:[OWSPrimaryStorage sharedDataDatabaseFilePath_WAL]]; -} - -- (void)closeStorageForTests -{ - [self resetStorage]; - - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (void)resetStorage -{ - self.database = nil; - - [OWSStorage deleteDatabaseFiles]; -} - -+ (void)resetAllStorage -{ - [[NSNotificationCenter defaultCenter] postNotificationName:OWSResetStorageNotification object:nil]; - - // This might be redundant but in the spirit of thoroughness... - [self deleteDatabaseFiles]; - - [self deleteDBKeys]; - - if (CurrentAppContext().isMainApp) { - [TSAttachmentStream deleteAttachments]; - } - - // TODO: Delete Profiles on Disk? -} - -#pragma mark - Password - -- (NSString *)databaseFilePath -{ - return @""; -} - -- (NSString *)databaseFilePath_SHM -{ - return @""; -} - -- (NSString *)databaseFilePath_WAL -{ - return @""; -} - -#pragma mark - Keychain - -+ (BOOL)isDatabasePasswordAccessible -{ - NSError *error; - NSData *cipherKeySpec = [self tryToLoadDatabaseCipherKeySpec:&error]; - - if (cipherKeySpec && !error) { - return YES; - } - - return NO; -} - -+ (nullable NSData *)tryToLoadDatabaseLegacyPassphrase:(NSError **)errorHandle -{ - return [self tryToLoadKeyChainValue:keychainDBLegacyPassphrase errorHandle:errorHandle]; -} - -+ (nullable NSData *)tryToLoadDatabaseCipherKeySpec:(NSError **)errorHandle -{ - NSData *_Nullable data = [self tryToLoadKeyChainValue:keychainDBCipherKeySpec errorHandle:errorHandle]; - - return data; -} - -+ (void)storeDatabaseCipherKeySpec:(NSData *)cipherKeySpecData -{ - [self storeKeyChainValue:cipherKeySpecData keychainKey:keychainDBCipherKeySpec]; -} - -+ (void)removeLegacyPassphrase -{ - NSError *_Nullable error; - BOOL result = [CurrentAppContext().keychainStorage removeWithService:keychainService - key:keychainDBLegacyPassphrase - error:&error]; -} - -- (void)ensureDatabaseKeySpecExists -{ - NSError *error; - NSData *_Nullable keySpec = [[self class] tryToLoadDatabaseCipherKeySpec:&error]; - - if (error || (keySpec.length != kSQLCipherKeySpecLength)) { - // Because we use kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, - // the keychain will be inaccessible after device restart until - // device is unlocked for the first time. If the app receives - // a push notification, we won't be able to access the keychain to - // process that notification, so we should just terminate by throwing - // an uncaught exception. - NSString *errorDescription = [NSString - stringWithFormat:@"CipherKeySpec inaccessible. New install or no unlock since device restart? Error: %@", - error]; - if (CurrentAppContext().isMainApp) { - UIApplicationState applicationState = CurrentAppContext().reportedApplicationState; - errorDescription = [errorDescription - stringByAppendingFormat:@", ApplicationState: %@", NSStringForUIApplicationState(applicationState)]; - } - - if (CurrentAppContext().isMainApp) { - if (CurrentAppContext().isInBackground) { - // Rather than crash here, we should have already detected the situation earlier - // and exited gracefully (in the app delegate) using isDatabasePasswordAccessible. - // This is a last ditch effort to avoid blowing away the user's database. - [self raiseKeySpecInaccessibleExceptionWithErrorDescription:errorDescription]; - } - } else { - [self raiseKeySpecInaccessibleExceptionWithErrorDescription:@"CipherKeySpec inaccessible; not main app."]; - } - - // At this point, either this is a new install so there's no existing password to retrieve - // or the keychain has become corrupt. Either way, we want to get back to a - // "known good state" and behave like a new install. - BOOL doesDBExist = [NSFileManager.defaultManager fileExistsAtPath:[self databaseFilePath]]; - - if (!CurrentAppContext().isRunningTests) { - // Try to reset app by deleting database. - [OWSStorage resetAllStorage]; - } - - keySpec = [Randomness generateRandomBytes:(int)kSQLCipherKeySpecLength]; - [[self class] storeDatabaseCipherKeySpec:keySpec]; - } -} - -- (NSData *)databaseKeySpec -{ - NSError *error; - NSData *_Nullable keySpec = [[self class] tryToLoadDatabaseCipherKeySpec:&error]; - - if (error) { - [self raiseKeySpecInaccessibleExceptionWithErrorDescription:@"CipherKeySpec inaccessible"]; - } - - if (keySpec.length != kSQLCipherKeySpecLength) { - [self raiseKeySpecInaccessibleExceptionWithErrorDescription:@"CipherKeySpec invalid"]; - } - - return keySpec; -} - -- (void)raiseKeySpecInaccessibleExceptionWithErrorDescription:(NSString *)errorDescription -{ - // Sleep to give analytics events time to be delivered. - [NSThread sleepForTimeInterval:5.0f]; - - // Presumably this happened in response to a push notification. It's possible that the keychain is corrupted - // but it could also just be that the user hasn't yet unlocked their device since our password is - // kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly -} - -+ (void)deleteDBKeys -{ - NSError *_Nullable error; - BOOL result = [CurrentAppContext().keychainStorage removeWithService:keychainService - key:keychainDBLegacyPassphrase - error:&error]; - result = [CurrentAppContext().keychainStorage removeWithService:keychainService - key:keychainDBCipherKeySpec - error:&error]; -} - -- (unsigned long long)databaseFileSize -{ - return [OWSFileSystem fileSizeOfPath:self.databaseFilePath].unsignedLongLongValue; -} - -- (unsigned long long)databaseWALFileSize -{ - return [OWSFileSystem fileSizeOfPath:self.databaseFilePath_WAL].unsignedLongLongValue; -} - -- (unsigned long long)databaseSHMFileSize -{ - return [OWSFileSystem fileSizeOfPath:self.databaseFilePath_SHM].unsignedLongLongValue; -} - -+ (nullable NSData *)tryToLoadKeyChainValue:(NSString *)keychainKey errorHandle:(NSError **)errorHandle -{ - NSData *_Nullable data = - [CurrentAppContext().keychainStorage dataForService:keychainService key:keychainKey error:errorHandle]; - return data; -} - -+ (void)storeKeyChainValue:(NSData *)data keychainKey:(NSString *)keychainKey -{ - NSError *error; - BOOL success = - [CurrentAppContext().keychainStorage setWithData:data service:keychainService key:keychainKey error:&error]; - if (!success || error) { - - // Sleep to give analytics events time to be delivered. - [NSThread sleepForTimeInterval:15.0f]; - - } -} - -- (void)logFileSizes -{ - -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/Database/Storage+OpenGroups.swift b/SessionMessagingKit/Database/Storage+OpenGroups.swift deleted file mode 100644 index ddcbc5268..000000000 --- a/SessionMessagingKit/Database/Storage+OpenGroups.swift +++ /dev/null @@ -1,209 +0,0 @@ - -extension Storage { - - // MARK: - Open Groups - - private static let openGroupCollection = "SNOpenGroupCollection" - - @objc public func getAllV2OpenGroups() -> [String:OpenGroupV2] { - var result = [String:OpenGroupV2]() - Storage.read { transaction in - transaction.enumerateKeysAndObjects(inCollection: Storage.openGroupCollection) { threadID, object, _ in - guard let openGroup = object as? OpenGroupV2 else { return } - result[threadID] = openGroup - } - } - return result - } - - @objc(getV2OpenGroupForThreadID:) - public func getV2OpenGroup(for threadID: String) -> OpenGroupV2? { - var result: OpenGroupV2? - Storage.read { transaction in - result = transaction.object(forKey: threadID, inCollection: Storage.openGroupCollection) as? OpenGroupV2 - } - return result - } - - public func v2GetThreadID(for v2OpenGroupID: String) -> String? { - var result: String? - Storage.read { transaction in - transaction.enumerateKeysAndObjects(inCollection: Storage.openGroupCollection, using: { threadID, object, stop in - guard let openGroup = object as? OpenGroupV2, openGroup.id == v2OpenGroupID else { return } - result = threadID - stop.pointee = true - }) - } - return result - } - - @objc(setV2OpenGroup:forThreadWithID:using:) - public func setV2OpenGroup(_ openGroup: OpenGroupV2, for threadID: String, using transaction: Any) { - (transaction as! YapDatabaseReadWriteTransaction).setObject(openGroup, forKey: threadID, inCollection: Storage.openGroupCollection) - } - - @objc(removeV2OpenGroupForThreadID:using:) - public func removeV2OpenGroup(for threadID: String, using transaction: Any) { - (transaction as! YapDatabaseReadWriteTransaction).removeObject(forKey: threadID, inCollection: Storage.openGroupCollection) - } - - - - // MARK: - Authorization - - private static let authTokenCollection = "SNAuthTokenCollection" - - public func getAuthToken(for room: String, on server: String) -> String? { - let collection = Storage.authTokenCollection - let key = "\(server).\(room)" - var result: String? = nil - Storage.read { transaction in - result = transaction.object(forKey: key, inCollection: collection) as? String - } - return result - } - - public func setAuthToken(for room: String, on server: String, to newValue: String, using transaction: Any) { - let collection = Storage.authTokenCollection - let key = "\(server).\(room)" - (transaction as! YapDatabaseReadWriteTransaction).setObject(newValue, forKey: key, inCollection: collection) - } - - public func removeAuthToken(for room: String, on server: String, using transaction: Any) { - let collection = Storage.authTokenCollection - let key = "\(server).\(room)" - (transaction as! YapDatabaseReadWriteTransaction).removeObject(forKey: key, inCollection: collection) - } - - - - // MARK: - Public Keys - - private static let openGroupPublicKeyCollection = "LokiOpenGroupPublicKeyCollection" - - public func getOpenGroupPublicKey(for server: String) -> String? { - var result: String? = nil - Storage.read { transaction in - result = transaction.object(forKey: server, inCollection: Storage.openGroupPublicKeyCollection) as? String - } - return result - } - - public func setOpenGroupPublicKey(for server: String, to newValue: String, using transaction: Any) { - (transaction as! YapDatabaseReadWriteTransaction).setObject(newValue, forKey: server, inCollection: Storage.openGroupPublicKeyCollection) - } - - public func removeOpenGroupPublicKey(for server: String, using transaction: Any) { - (transaction as! YapDatabaseReadWriteTransaction).removeObject(forKey: server, inCollection: Storage.openGroupPublicKeyCollection) - } - - - - // MARK: - Last Message Server ID - - public static let lastMessageServerIDCollection = "SNLastMessageServerIDCollection" - - public func getLastMessageServerID(for room: String, on server: String) -> Int64? { - let collection = Storage.lastMessageServerIDCollection - let key = "\(server).\(room)" - var result: Int64? = nil - Storage.read { transaction in - result = transaction.object(forKey: key, inCollection: collection) as? Int64 - } - return result - } - - public func setLastMessageServerID(for room: String, on server: String, to newValue: Int64, using transaction: Any) { - let collection = Storage.lastMessageServerIDCollection - let key = "\(server).\(room)" - (transaction as! YapDatabaseReadWriteTransaction).setObject(newValue, forKey: key, inCollection: collection) - } - - public func removeLastMessageServerID(for room: String, on server: String, using transaction: Any) { - let collection = Storage.lastMessageServerIDCollection - let key = "\(server).\(room)" - (transaction as! YapDatabaseReadWriteTransaction).removeObject(forKey: key, inCollection: collection) - } - - - - // MARK: - Last Deletion Server ID - - public static let lastDeletionServerIDCollection = "SNLastDeletionServerIDCollection" - - public func getLastDeletionServerID(for room: String, on server: String) -> Int64? { - let collection = Storage.lastDeletionServerIDCollection - let key = "\(server).\(room)" - var result: Int64? = nil - Storage.read { transaction in - result = transaction.object(forKey: key, inCollection: collection) as? Int64 - } - return result - } - - public func setLastDeletionServerID(for room: String, on server: String, to newValue: Int64, using transaction: Any) { - let collection = Storage.lastDeletionServerIDCollection - let key = "\(server).\(room)" - (transaction as! YapDatabaseReadWriteTransaction).setObject(newValue, forKey: key, inCollection: collection) - } - - public func removeLastDeletionServerID(for room: String, on server: String, using transaction: Any) { - let collection = Storage.lastDeletionServerIDCollection - let key = "\(server).\(room)" - (transaction as! YapDatabaseReadWriteTransaction).removeObject(forKey: key, inCollection: collection) - } - - // MARK: - OpenGroupServerIdToUniqueIdLookup - - public static let openGroupServerIdToUniqueIdLookupCollection = "SNOpenGroupServerIdToUniqueIdLookup" - - public func getOpenGroupServerIdLookup(_ serverId: UInt64, in room: String, on server: String, using transaction: YapDatabaseReadTransaction) -> OpenGroupServerIdLookup? { - let key: String = OpenGroupServerIdLookup.id(serverId: serverId, in: room, on: server) - return transaction.object(forKey: key, inCollection: Storage.openGroupServerIdToUniqueIdLookupCollection) as? OpenGroupServerIdLookup - } - - public func addOpenGroupServerIdLookup(_ serverId: UInt64?, tsMessageId: String?, in room: String, on server: String, using transaction: YapDatabaseReadWriteTransaction) { - guard let serverId: UInt64 = serverId, let tsMessageId: String = tsMessageId else { return } - - let lookup: OpenGroupServerIdLookup = OpenGroupServerIdLookup(server: server, room: room, serverId: serverId, tsMessageId: tsMessageId) - addOpenGroupServerIdLookup(lookup, using: transaction) - } - - public func addOpenGroupServerIdLookup(_ lookup: OpenGroupServerIdLookup, using transaction: YapDatabaseReadWriteTransaction) { - transaction.setObject(lookup, forKey: lookup.id, inCollection: Storage.openGroupServerIdToUniqueIdLookupCollection) - } - - public func removeOpenGroupServerIdLookup(_ serverId: UInt64, in room: String, on server: String, using transaction: YapDatabaseReadWriteTransaction) { - let key: String = OpenGroupServerIdLookup.id(serverId: serverId, in: room, on: server) - transaction.removeObject(forKey: key, inCollection: Storage.openGroupServerIdToUniqueIdLookupCollection) - } - - // MARK: - Metadata - - private static let openGroupUserCountCollection = "SNOpenGroupUserCountCollection" - private static let openGroupImageCollection = "SNOpenGroupImageCollection" - - public func getUserCount(forV2OpenGroupWithID openGroupID: String) -> UInt64? { - var result: UInt64? - Storage.read { transaction in - result = transaction.object(forKey: openGroupID, inCollection: Storage.openGroupUserCountCollection) as? UInt64 - } - return result - } - - public func setUserCount(to newValue: UInt64, forV2OpenGroupWithID openGroupID: String, using transaction: Any) { - (transaction as! YapDatabaseReadWriteTransaction).setObject(newValue, forKey: openGroupID, inCollection: Storage.openGroupUserCountCollection) - } - - public func getOpenGroupImage(for room: String, on server: String) -> Data? { - var result: Data? - Storage.read { transaction in - result = transaction.object(forKey: "\(server).\(room)", inCollection: Storage.openGroupImageCollection) as? Data - } - return result - } - - public func setOpenGroupImage(to data: Data, for room: String, on server: String, using transaction: Any) { - (transaction as! YapDatabaseReadWriteTransaction).setObject(data, forKey: "\(server).\(room)", inCollection: Storage.openGroupImageCollection) - } -} diff --git a/SessionMessagingKit/Database/Storage+Shared.swift b/SessionMessagingKit/Database/Storage+Shared.swift deleted file mode 100644 index 394f3b98c..000000000 --- a/SessionMessagingKit/Database/Storage+Shared.swift +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. - -import Foundation -import PromiseKit -import Sodium - -extension Storage { - - @discardableResult - public func write(with block: @escaping (Any) -> Void) -> Promise { - Storage.write(with: { block($0) }) - } - - @discardableResult - public func write(with block: @escaping (Any) -> Void, completion: @escaping () -> Void) -> Promise { - Storage.write(with: { block($0) }, completion: completion) - } - - public func writeSync(with block: @escaping (Any) -> Void) { - Storage.writeSync { block($0) } - } -// @objc public func getUser() -> Legacy.Contact? { -// return getUser(using: nil) -// } -// -// public func getUser(using transaction: YapDatabaseReadTransaction?) -> Legacy.Contact? { -// let userPublicKey = getUserHexEncodedPublicKey() -// var result: Legacy.Contact? -// -// if let transaction = transaction { -// result = Storage.shared.getContact(with: userPublicKey, using: transaction) -// } -// else { -// Storage.read { transaction in -// result = Storage.shared.getContact(with: userPublicKey, using: transaction) -// } -// } -// return result -// } -} diff --git a/SessionMessagingKit/Database/TSDatabaseSecondaryIndexes.h b/SessionMessagingKit/Database/TSDatabaseSecondaryIndexes.h deleted file mode 100644 index f2e377654..000000000 --- a/SessionMessagingKit/Database/TSDatabaseSecondaryIndexes.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface TSDatabaseSecondaryIndexes : NSObject - -+ (NSString *)registerTimeStampIndexExtensionName; - -+ (YapDatabaseSecondaryIndex *)registerTimeStampIndex; - -+ (void)enumerateMessagesWithTimestamp:(uint64_t)timestamp - withBlock:(void (^)(NSString *collection, NSString *key, BOOL *stop))block - usingTransaction:(YapDatabaseReadTransaction *)transaction; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/Database/TSDatabaseSecondaryIndexes.m b/SessionMessagingKit/Database/TSDatabaseSecondaryIndexes.m deleted file mode 100644 index 893a8e9ea..000000000 --- a/SessionMessagingKit/Database/TSDatabaseSecondaryIndexes.m +++ /dev/null @@ -1,53 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import "TSDatabaseSecondaryIndexes.h" -#import "OWSStorage.h" - -NS_ASSUME_NONNULL_BEGIN - -#define TSTimeStampSQLiteIndex @"messagesTimeStamp" - -@implementation TSDatabaseSecondaryIndexes - -+ (NSString *)registerTimeStampIndexExtensionName -{ - return @"idx"; -} - -+ (YapDatabaseSecondaryIndex *)registerTimeStampIndex { - YapDatabaseSecondaryIndexSetup *setup = [[YapDatabaseSecondaryIndexSetup alloc] init]; - [setup addColumn:TSTimeStampSQLiteIndex withType:YapDatabaseSecondaryIndexTypeReal]; - - YapDatabaseSecondaryIndexWithObjectBlock block = - ^(YapDatabaseReadTransaction *transaction, NSMutableDictionary *dict, NSString *collection, NSString *key, id object) { - - if ([object isKindOfClass:[TSInteraction class]]) { - TSInteraction *interaction = (TSInteraction *)object; - - [dict setObject:@(interaction.timestamp) forKey:TSTimeStampSQLiteIndex]; - } - }; - - YapDatabaseSecondaryIndexHandler *handler = [YapDatabaseSecondaryIndexHandler withObjectBlock:block]; - - YapDatabaseSecondaryIndex *secondaryIndex = - [[YapDatabaseSecondaryIndex alloc] initWithSetup:setup handler:handler versionTag:nil]; - - return secondaryIndex; -} - - -+ (void)enumerateMessagesWithTimestamp:(uint64_t)timestamp - withBlock:(void (^)(NSString *collection, NSString *key, BOOL *stop))block - usingTransaction:(YapDatabaseReadTransaction *)transaction -{ - NSString *formattedString = [NSString stringWithFormat:@"WHERE %@ = %lld", TSTimeStampSQLiteIndex, timestamp]; - YapDatabaseQuery *query = [YapDatabaseQuery queryWithFormat:formattedString]; - [[transaction ext:[self registerTimeStampIndexExtensionName]] enumerateKeysMatchingQuery:query usingBlock:block]; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/Database/TSDatabaseView.h b/SessionMessagingKit/Database/TSDatabaseView.h deleted file mode 100644 index f6244dba2..000000000 --- a/SessionMessagingKit/Database/TSDatabaseView.h +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -extern NSString *const TSInboxGroup; -extern NSString *const TSMessageRequestGroup; -extern NSString *const TSArchiveGroup; -extern NSString *const TSShareExtensionGroup; -extern NSString *const TSUnreadIncomingMessagesGroup; -extern NSString *const TSSecondaryDevicesGroup; - -extern NSString *const TSThreadDatabaseViewExtensionName; -extern NSString *const TSThreadShareExtensionDatabaseViewExtensionName; - -extern NSString *const TSMessageDatabaseViewExtensionName; -extern NSString *const TSMessageDatabaseViewExtensionName_Legacy; - -extern NSString *const TSUnreadDatabaseViewExtensionName; -extern NSString *const TSUnseenDatabaseViewExtensionName; -extern NSString *const TSUnreadMentionDatabaseViewExtensionName; -extern NSString *const TSThreadOutgoingMessageDatabaseViewExtensionName; -extern NSString *const TSThreadSpecialMessagesDatabaseViewExtensionName; - -extern NSString *const TSSecondaryDevicesDatabaseViewExtensionName; - -extern NSString *const TSLazyRestoreAttachmentsGroup; -extern NSString *const TSLazyRestoreAttachmentsDatabaseViewExtensionName; - -@interface TSDatabaseView : NSObject - -- (instancetype)init NS_UNAVAILABLE; - -#pragma mark - Views - -// Returns the "unseen" database view if it is ready; -// otherwise it returns the "unread" database view. -+ (id)unseenDatabaseViewExtension:(YapDatabaseReadTransaction *)transaction; - -+ (id)threadOutgoingMessageDatabaseView:(YapDatabaseReadTransaction *)transaction; - -+ (id)threadSpecialMessagesDatabaseView:(YapDatabaseReadTransaction *)transaction; - -#pragma mark - Registration - -+ (void)registerCrossProcessNotifier:(OWSStorage *)storage; - -// This method must be called _AFTER_ asyncRegisterThreadInteractionsDatabaseView. -+ (void)asyncRegisterThreadDatabaseView:(OWSStorage *)storage; - -+ (void)asyncRegisterThreadInteractionsDatabaseView:(OWSStorage *)storage; -+ (void)asyncRegisterLegacyThreadInteractionsDatabaseView:(OWSStorage *)storage; - -+ (void)asyncRegisterThreadOutgoingMessagesDatabaseView:(OWSStorage *)storage; - -// Should be used for "mention indicator". -// -// Instances of OWSReadTracking for wasRead is NO and isUserMentioned is YES. -+ (void)asyncRegisterUnreadMentionDatabaseView:(OWSStorage *)storage; - -+ (void)asyncRegisterLazyRestoreAttachmentsDatabaseView:(OWSStorage *)storage; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/Database/TSDatabaseView.m b/SessionMessagingKit/Database/TSDatabaseView.m deleted file mode 100644 index 9051d0a18..000000000 --- a/SessionMessagingKit/Database/TSDatabaseView.m +++ /dev/null @@ -1,441 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import "TSDatabaseView.h" -#import -#import -#import -#import -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -NSString *const TSInboxGroup = @"TSInboxGroup"; -NSString *const TSMessageRequestGroup = @"TSMessageRequestGroup"; -NSString *const TSArchiveGroup = @"TSArchiveGroup"; -NSString *const TSShareExtensionGroup = @"TSShareExtensionGroup"; - -NSString *const TSUnreadIncomingMessagesGroup = @"TSUnreadIncomingMessagesGroup"; -NSString *const TSSecondaryDevicesGroup = @"TSSecondaryDevicesGroup"; - -// YAPDB BUG: when changing from non-persistent to persistent view, we had to rename TSThreadDatabaseViewExtensionName -// -> TSThreadDatabaseViewExtensionName2 to work around https://github.com/yapstudios/YapDatabase/issues/324 -NSString *const TSThreadDatabaseViewExtensionName = @"TSThreadDatabaseViewExtensionName2"; - -NSString *const TSThreadShareExtensionDatabaseViewExtensionName = @"TSThreadShareExtensionDatabaseViewExtensionName"; - -// We sort interactions by a monotonically increasing counter. -// -// Previously we sorted the interactions database by local timestamp, which was problematic if the local clock changed. -// We need to maintain the legacy extension for purposes of migration. -// -// The "Legacy" sorting extension name constant has the same value as always, so that it won't need to be rebuilt, while -// the "Modern" sorting extension name constant has the same symbol name that we've always used for sorting -// interactions, so that the callsites won't need to change. -NSString *const TSMessageDatabaseViewExtensionName = @"TSMessageDatabaseViewExtensionName_Monotonic"; -NSString *const TSMessageDatabaseViewExtensionName_Legacy = @"TSMessageDatabaseViewExtensionName"; - -NSString *const TSThreadOutgoingMessageDatabaseViewExtensionName = @"TSThreadOutgoingMessageDatabaseViewExtensionName"; -NSString *const TSUnreadDatabaseViewExtensionName = @"TSUnreadDatabaseViewExtensionName"; -NSString *const TSUnseenDatabaseViewExtensionName = @"TSUnseenDatabaseViewExtensionName"; -NSString *const TSUnreadMentionDatabaseViewExtensionName = @"TSUnreadMentionDatabaseViewExtensionName"; -NSString *const TSThreadSpecialMessagesDatabaseViewExtensionName = @"TSThreadSpecialMessagesDatabaseViewExtensionName"; -NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevicesDatabaseViewExtensionName"; -NSString *const TSLazyRestoreAttachmentsDatabaseViewExtensionName - = @"TSLazyRestoreAttachmentsDatabaseViewExtensionName"; -NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"; - -@interface OWSStorage (TSDatabaseView) - -- (BOOL)registerExtension:(YapDatabaseExtension *)extension withName:(NSString *)extensionName; - -@end - -#pragma mark - - -@implementation TSDatabaseView - -+ (void)registerCrossProcessNotifier:(OWSStorage *)storage -{ - // I don't think the identifier and name of this extension matter for our purposes, - // so long as they don't conflict with any other extension names. - YapDatabaseExtension *extension = - [[YapDatabaseCrossProcessNotification alloc] initWithIdentifier:@"SignalCrossProcessNotifier"]; - [storage registerExtension:extension withName:@"SignalCrossProcessNotifier"]; -} - -+ (void)registerMessageDatabaseViewWithName:(NSString *)viewName - viewGrouping:(YapDatabaseViewGrouping *)viewGrouping - version:(NSString *)version - storage:(OWSStorage *)storage -{ - YapDatabaseView *existingView = [storage registeredExtension:viewName]; - if (existingView) { - return; - } - - YapDatabaseViewSorting *viewSorting = [self messagesSorting]; - - YapDatabaseViewOptions *options = [[YapDatabaseViewOptions alloc] init]; - options.isPersistent = YES; - options.allowedCollections = - [[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[TSInteraction collection]]]; - - YapDatabaseView *view = [[YapDatabaseAutoView alloc] initWithGrouping:viewGrouping - sorting:viewSorting - versionTag:version - options:options]; - [storage asyncRegisterExtension:view withName:viewName]; -} - -+ (void)asyncRegisterUnreadMentionDatabaseView:(OWSStorage *)storage -{ - YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( - YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { - if ([object isKindOfClass:[TSIncomingMessage class]]) { - TSIncomingMessage *message = (TSIncomingMessage *)object; - if (!message.wasRead && message.isUserMentioned) { - return message.uniqueThreadId; - } - } - return nil; - }]; - - [self registerMessageDatabaseViewWithName:TSUnreadMentionDatabaseViewExtensionName - viewGrouping:viewGrouping - version:@"2" - storage:storage]; -} - -+ (void)asyncRegisterLegacyThreadInteractionsDatabaseView:(OWSStorage *)storage -{ - YapDatabaseView *existingView = [storage registeredExtension:TSMessageDatabaseViewExtensionName_Legacy]; - if (existingView) { - return; - } - - YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( - YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { - if (![object isKindOfClass:[TSInteraction class]]) { - return nil; - } - TSInteraction *interaction = (TSInteraction *)object; - - return interaction.uniqueThreadId; - }]; - - YapDatabaseViewSorting *viewSorting = - [YapDatabaseViewSorting withObjectBlock:^NSComparisonResult(YapDatabaseReadTransaction *transaction, - NSString *group, - NSString *collection1, - NSString *key1, - id object1, - NSString *collection2, - NSString *key2, - id object2) { - if (![object1 isKindOfClass:[TSInteraction class]]) { - return NSOrderedSame; - } - if (![object2 isKindOfClass:[TSInteraction class]]) { - return NSOrderedSame; - } - TSInteraction *interaction1 = (TSInteraction *)object1; - TSInteraction *interaction2 = (TSInteraction *)object2; - - // Legit usage of timestampForLegacySorting since we're registering the - // legacy extension - uint64_t timestamp1 = interaction1.timestampForLegacySorting; - uint64_t timestamp2 = interaction2.timestampForLegacySorting; - - if (timestamp1 > timestamp2) { - return NSOrderedDescending; - } else if (timestamp1 < timestamp2) { - return NSOrderedAscending; - } else { - return NSOrderedSame; - } - }]; - - YapDatabaseViewOptions *options = [YapDatabaseViewOptions new]; - options.isPersistent = YES; - options.allowedCollections = - [[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[TSInteraction collection]]]; - - YapDatabaseView *view = - [[YapDatabaseAutoView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"1" options:options]; - - [storage asyncRegisterExtension:view withName:TSMessageDatabaseViewExtensionName_Legacy]; -} - -+ (void)asyncRegisterThreadInteractionsDatabaseView:(OWSStorage *)storage -{ - YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( - YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { - if (![object isKindOfClass:[TSInteraction class]]) { - return nil; - } - TSInteraction *interaction = (TSInteraction *)object; - - return interaction.uniqueThreadId; - }]; - - [self registerMessageDatabaseViewWithName:TSMessageDatabaseViewExtensionName - viewGrouping:viewGrouping - version:@"2" - storage:storage]; -} - -+ (void)asyncRegisterThreadOutgoingMessagesDatabaseView:(OWSStorage *)storage -{ - YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( - YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { - if ([object isKindOfClass:[TSOutgoingMessage class]]) { - return ((TSOutgoingMessage *)object).uniqueThreadId; - } - return nil; - }]; - - [self registerMessageDatabaseViewWithName:TSThreadOutgoingMessageDatabaseViewExtensionName - viewGrouping:viewGrouping - version:@"3" - storage:storage]; -} - -+ (void)asyncRegisterThreadDatabaseView:(OWSStorage *)storage -{ - YapDatabaseView *threadView = [storage registeredExtension:TSThreadDatabaseViewExtensionName]; - if (threadView) { - return; - } - - YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( - YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { - if (![object isKindOfClass:[TSThread class]]) { - return nil; - } - TSThread *thread = (TSThread *)object; - - if ([thread isMessageRequestUsingTransaction:transaction]) { - // Don't show blocked threads at all - if (thread.isBlocked) { - return nil; - } - - return TSMessageRequestGroup; - } - else if (thread.shouldBeVisible) { - // Do nothing; we never hide threads that have ever had a message. - } else { - YapDatabaseViewTransaction *viewTransaction = [transaction ext:TSMessageDatabaseViewExtensionName]; - NSUInteger threadMessageCount = [viewTransaction numberOfItemsInGroup:thread.uniqueId]; - if (threadMessageCount < 1) { - return nil; - } - } - - return TSInboxGroup; - }]; - - YapDatabaseViewSorting *viewSorting = [self threadSorting]; - - YapDatabaseViewOptions *options = [[YapDatabaseViewOptions alloc] init]; - options.isPersistent = YES; - options.allowedCollections = - [[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[TSThread collection]]]; - - YapDatabaseView *databaseView = - [[YapDatabaseAutoView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"4" options:options]; - - [storage asyncRegisterExtension:databaseView withName:TSThreadDatabaseViewExtensionName]; - - YapDatabaseView *shareExtensionThreadView = [storage registeredExtension:TSThreadShareExtensionDatabaseViewExtensionName]; - if (shareExtensionThreadView) { - return; - } - - YapDatabaseViewGrouping *shareExtensionViewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( - YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { - if (![object isKindOfClass:[TSThread class]]) { - return nil; - } - TSThread *thread = (TSThread *)object; - - if ([thread isMessageRequestUsingTransaction:transaction]) { - return nil; - } - else { - YapDatabaseViewTransaction *viewTransaction = [transaction ext:TSMessageDatabaseViewExtensionName]; - NSUInteger threadMessageCount = [viewTransaction numberOfItemsInGroup:thread.uniqueId]; - if (threadMessageCount < 1) { - return nil; - } - - if (!thread.isGroupThread) { - TSContactThread *contactThead = (TSContactThread *)thread; - SMKContact *contact = [SMKContact fetchOrCreateWithId:[contactThead contactSessionID]]; - - if (contact == nil || !contact.didApproveMe) { - return nil; - } - } - } - - return TSShareExtensionGroup; - }]; - - YapDatabaseViewSorting *shareExtensionViewSorting = [self threadSorting]; - - YapDatabaseViewOptions *shareExtensionOptions = [[YapDatabaseViewOptions alloc] init]; - shareExtensionOptions.isPersistent = YES; - shareExtensionOptions.allowedCollections = - [[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[TSThread collection]]]; - - YapDatabaseView *shareExtensionDatabaseView = - [[YapDatabaseAutoView alloc] initWithGrouping:shareExtensionViewGrouping sorting:shareExtensionViewSorting versionTag:@"1" options:shareExtensionOptions]; - - [storage asyncRegisterExtension:shareExtensionDatabaseView withName:TSThreadShareExtensionDatabaseViewExtensionName]; -} - -+ (YapDatabaseViewSorting *)threadSorting { - return [YapDatabaseViewSorting withObjectBlock:^NSComparisonResult(YapDatabaseReadTransaction *transaction, - NSString *group, - NSString *collection1, - NSString *key1, - id object1, - NSString *collection2, - NSString *key2, - id object2) { - if (![object1 isKindOfClass:[TSThread class]]) { - return NSOrderedSame; - } - if (![object2 isKindOfClass:[TSThread class]]) { - return NSOrderedSame; - } - TSThread *thread1 = (TSThread *)object1; - TSThread *thread2 = (TSThread *)object2; - if ([group isEqualToString:TSArchiveGroup] || [group isEqualToString:TSInboxGroup]) { - if (thread1.isPinned != thread2.isPinned) { - if (thread1.isPinned) { return NSOrderedDescending; } - if (thread2.isPinned) { return NSOrderedAscending; } - } - TSInteraction *_Nullable lastInteractionForInbox1 = - [thread1 lastInteractionForInboxWithTransaction:transaction]; - NSDate *lastInteractionForInboxDate1 = lastInteractionForInbox1 ? lastInteractionForInbox1.receivedAtDate : thread1.creationDate; - - TSInteraction *_Nullable lastInteractionForInbox2 = - [thread2 lastInteractionForInboxWithTransaction:transaction]; - NSDate *lastInteractionForInboxDate2 = lastInteractionForInbox2 ? lastInteractionForInbox2.receivedAtDate : thread2.creationDate; - - - NSDate *date1 = thread1.lastInteractionDate ?: lastInteractionForInboxDate1 ?: thread1.creationDate; - NSDate *date2 = thread2.lastInteractionDate ?: lastInteractionForInboxDate2 ?: thread2.creationDate; - return [date1 compare:date2]; - } - - return NSOrderedSame; - }]; -} - -+ (YapDatabaseViewSorting *)messagesSorting { - return [YapDatabaseViewSorting withObjectBlock:^NSComparisonResult(YapDatabaseReadTransaction *transaction, - NSString *group, - NSString *collection1, - NSString *key1, - id object1, - NSString *collection2, - NSString *key2, - id object2) { - if (![object1 isKindOfClass:[TSInteraction class]]) { - return NSOrderedSame; - } - if (![object2 isKindOfClass:[TSInteraction class]]) { - return NSOrderedSame; - } - TSInteraction *message1 = (TSInteraction *)object1; - TSInteraction *message2 = (TSInteraction *)object2; - - return [message1 compareForSorting:message2]; - }]; -} - -+ (void)asyncRegisterLazyRestoreAttachmentsDatabaseView:(OWSStorage *)storage -{ - YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *_Nullable( - YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { - if (![object isKindOfClass:[TSAttachment class]]) { - return nil; - } - if (![object isKindOfClass:[TSAttachmentPointer class]]) { - return nil; - } - TSAttachmentPointer *attachmentPointer = (TSAttachmentPointer *)object; - if (attachmentPointer.lazyRestoreFragment) { - return TSLazyRestoreAttachmentsGroup; - } else { - return nil; - } - }]; - - YapDatabaseViewSorting *viewSorting = - [YapDatabaseViewSorting withObjectBlock:^NSComparisonResult(YapDatabaseReadTransaction *transaction, - NSString *group, - NSString *collection1, - NSString *key1, - id object1, - NSString *collection2, - NSString *key2, - id object2) { - if (![object1 isKindOfClass:[TSAttachmentPointer class]]) { - return NSOrderedSame; - } - if (![object2 isKindOfClass:[TSAttachmentPointer class]]) { - return NSOrderedSame; - } - - // Specific ordering doesn't matter; we just need a stable ordering. - TSAttachmentPointer *attachmentPointer1 = (TSAttachmentPointer *)object1; - TSAttachmentPointer *attachmentPointer2 = (TSAttachmentPointer *)object2; - return [attachmentPointer1.uniqueId compare:attachmentPointer2.uniqueId]; - }]; - - YapDatabaseViewOptions *options = [YapDatabaseViewOptions new]; - options.isPersistent = YES; - options.allowedCollections = - [[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[TSAttachment collection]]]; - YapDatabaseView *view = - [[YapDatabaseAutoView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"4" options:options]; - [storage asyncRegisterExtension:view withName:TSLazyRestoreAttachmentsDatabaseViewExtensionName]; -} - -+ (id)unseenDatabaseViewExtension:(YapDatabaseReadTransaction *)transaction -{ - id _Nullable result = [transaction ext:TSUnseenDatabaseViewExtensionName]; - - // TODO: I believe we can now safely remove this? - if (!result) { - result = [transaction ext:TSUnreadDatabaseViewExtensionName]; - } - - return result; -} - -// MJK TODO - dynamic interactions -+ (id)threadOutgoingMessageDatabaseView:(YapDatabaseReadTransaction *)transaction -{ - id result = [transaction ext:TSThreadOutgoingMessageDatabaseViewExtensionName]; - - return result; -} - -+ (id)threadSpecialMessagesDatabaseView:(YapDatabaseReadTransaction *)transaction -{ - id result = [transaction ext:TSThreadSpecialMessagesDatabaseViewExtensionName]; - - return result; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/File Server/FileServerAPIV2.swift b/SessionMessagingKit/File Server/FileServerAPIV2.swift index a5b880b36..553005494 100644 --- a/SessionMessagingKit/File Server/FileServerAPIV2.swift +++ b/SessionMessagingKit/File Server/FileServerAPIV2.swift @@ -1,5 +1,9 @@ +// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. + +import Foundation import PromiseKit import SessionSnodeKit +import SessionUtilitiesKit @objc(SNFileServerAPIV2) public final class FileServerAPIV2 : NSObject { diff --git a/SessionMessagingKit/Meta/SessionMessagingKit.h b/SessionMessagingKit/Meta/SessionMessagingKit.h index 6006d21c1..c7ef2d60a 100644 --- a/SessionMessagingKit/Meta/SessionMessagingKit.h +++ b/SessionMessagingKit/Meta/SessionMessagingKit.h @@ -7,13 +7,5 @@ FOUNDATION_EXPORT const unsigned char SessionMessagingKitVersionString[]; #import #import #import -#import #import -#import -#import -#import #import -#import -#import -#import -#import diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift index eeebdeeba..2a091b7a9 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift @@ -6,6 +6,7 @@ import Sodium import Curve25519Kit import SignalCoreKit import SessionSnodeKit +import SessionUtilitiesKit extension MessageReceiver { diff --git a/SessionMessagingKit/Sending & Receiving/Notifications/PushNotificationAPI.swift b/SessionMessagingKit/Sending & Receiving/Notifications/PushNotificationAPI.swift index 9e07f583c..0702cae33 100644 --- a/SessionMessagingKit/Sending & Receiving/Notifications/PushNotificationAPI.swift +++ b/SessionMessagingKit/Sending & Receiving/Notifications/PushNotificationAPI.swift @@ -3,6 +3,7 @@ import GRDB import PromiseKit import SessionSnodeKit +import SessionUtilitiesKit @objc(LKPushNotificationAPI) public final class PushNotificationAPI : NSObject { diff --git a/SessionMessagingKit/Sending & Receiving/Pollers/ClosedGroupPoller.swift b/SessionMessagingKit/Sending & Receiving/Pollers/ClosedGroupPoller.swift index 56ba23f92..9eadf1d85 100644 --- a/SessionMessagingKit/Sending & Receiving/Pollers/ClosedGroupPoller.swift +++ b/SessionMessagingKit/Sending & Receiving/Pollers/ClosedGroupPoller.swift @@ -4,6 +4,7 @@ import Foundation import GRDB import PromiseKit import SessionSnodeKit +import SessionUtilitiesKit @objc(LKClosedGroupPoller) public final class ClosedGroupPoller: NSObject { diff --git a/SessionMessagingKit/Sending & Receiving/Pollers/Poller.swift b/SessionMessagingKit/Sending & Receiving/Pollers/Poller.swift index e94e8d9ab..4aac480a2 100644 --- a/SessionMessagingKit/Sending & Receiving/Pollers/Poller.swift +++ b/SessionMessagingKit/Sending & Receiving/Pollers/Poller.swift @@ -5,6 +5,7 @@ import GRDB import PromiseKit import Sodium import SessionSnodeKit +import SessionUtilitiesKit public final class Poller { private var isPolling: Atomic = Atomic(false) diff --git a/SessionMessagingKit/Shared Models/SessionThreadViewModel.swift b/SessionMessagingKit/Shared Models/SessionThreadViewModel.swift index 8da43ce45..51c288269 100644 --- a/SessionMessagingKit/Shared Models/SessionThreadViewModel.swift +++ b/SessionMessagingKit/Shared Models/SessionThreadViewModel.swift @@ -3,6 +3,7 @@ import Foundation import GRDB import DifferenceKit +import SessionUtilitiesKit fileprivate typealias ViewModel = SessionThreadViewModel diff --git a/SessionMessagingKit/Storage.swift b/SessionMessagingKit/Storage.swift deleted file mode 100644 index b543b8552..000000000 --- a/SessionMessagingKit/Storage.swift +++ /dev/null @@ -1,56 +0,0 @@ -import PromiseKit -import Sodium -import SessionSnodeKit - -public protocol SessionMessagingKitStorageProtocol { - - // MARK: - Shared - - @discardableResult - func write(with block: @escaping (Any) -> Void) -> Promise - @discardableResult - func write(with block: @escaping (Any) -> Void, completion: @escaping () -> Void) -> Promise - func writeSync(with block: @escaping (Any) -> Void) - - // MARK: - Authorization - - func getAuthToken(for room: String, on server: String) -> String? - func setAuthToken(for room: String, on server: String, to newValue: String, using transaction: Any) - func removeAuthToken(for room: String, on server: String, using transaction: Any) - - // MARK: - Open Groups - - func getAllV2OpenGroups() -> [String:OpenGroupV2] - func getV2OpenGroup(for threadID: String) -> OpenGroupV2? - func v2GetThreadID(for v2OpenGroupID: String) -> String? - - // MARK: - Open Group Public Keys - - func getOpenGroupPublicKey(for server: String) -> String? - func setOpenGroupPublicKey(for server: String, to newValue: String, using transaction: Any) - - // MARK: - Last Message Server ID - - func getLastMessageServerID(for room: String, on server: String) -> Int64? - func setLastMessageServerID(for room: String, on server: String, to newValue: Int64, using transaction: Any) - func removeLastMessageServerID(for room: String, on server: String, using transaction: Any) - - // MARK: - Last Deletion Server ID - - func getLastDeletionServerID(for room: String, on server: String) -> Int64? - func setLastDeletionServerID(for room: String, on server: String, to newValue: Int64, using transaction: Any) - func removeLastDeletionServerID(for room: String, on server: String, using transaction: Any) - - // MARK: - OpenGroupServerIdToUniqueIdLookup - - func getOpenGroupServerIdLookup(_ serverId: UInt64, in room: String, on server: String, using transaction: YapDatabaseReadTransaction) -> OpenGroupServerIdLookup? - func addOpenGroupServerIdLookup(_ serverId: UInt64?, tsMessageId: String?, in room: String, on server: String, using transaction: YapDatabaseReadWriteTransaction) - func addOpenGroupServerIdLookup(_ lookup: OpenGroupServerIdLookup, using transaction: YapDatabaseReadWriteTransaction) - func removeOpenGroupServerIdLookup(_ serverId: UInt64, in room: String, on server: String, using transaction: YapDatabaseReadWriteTransaction) - - // MARK: - Open Group Metadata - - func setUserCount(to newValue: UInt64, forV2OpenGroupWithID openGroupID: String, using transaction: Any) -} - -extension Storage: SessionMessagingKitStorageProtocol {} diff --git a/SessionMessagingKit/Utilities/Environment.swift b/SessionMessagingKit/Utilities/Environment.swift index 6d616b06a..1630ed8f7 100644 --- a/SessionMessagingKit/Utilities/Environment.swift +++ b/SessionMessagingKit/Utilities/Environment.swift @@ -6,11 +6,9 @@ import SessionUtilitiesKit public class Environment { public static var shared: Environment! - public let primaryStorage: OWSPrimaryStorage public let reachabilityManager: SSKReachabilityManager public let audioSession: OWSAudioSession - public let preferences: OWSPreferences public let proximityMonitoringManager: OWSProximityMonitoringManager public let windowManager: OWSWindowManager public var isRequestingPermission: Bool @@ -22,34 +20,20 @@ public class Environment { (notificationsManager.wrappedValue != nil) } - public var objectReadWriteConnection: YapDatabaseConnection - public var sessionStoreDBConnection: YapDatabaseConnection - public var migrationDBConnection: YapDatabaseConnection - public var analyticsDBConnection: YapDatabaseConnection - // MARK: - Initialization public init( - primaryStorage: OWSPrimaryStorage, reachabilityManager: SSKReachabilityManager, audioSession: OWSAudioSession, - preferences: OWSPreferences, proximityMonitoringManager: OWSProximityMonitoringManager, windowManager: OWSWindowManager ) { - self.primaryStorage = primaryStorage self.reachabilityManager = reachabilityManager self.audioSession = audioSession - self.preferences = preferences self.proximityMonitoringManager = proximityMonitoringManager self.windowManager = windowManager self.isRequestingPermission = false - self.objectReadWriteConnection = primaryStorage.newDatabaseConnection() - self.sessionStoreDBConnection = primaryStorage.newDatabaseConnection() - self.migrationDBConnection = primaryStorage.newDatabaseConnection() - self.analyticsDBConnection = primaryStorage.newDatabaseConnection() - if Environment.shared == nil { Environment.shared = self } @@ -68,7 +52,6 @@ public class Environment { class SMKEnvironment: NSObject { @objc public static let shared: SMKEnvironment = SMKEnvironment() - @objc public var primaryStorage: OWSPrimaryStorage { Environment.shared.primaryStorage } @objc public var audioSession: OWSAudioSession { Environment.shared.audioSession } @objc public var windowManager: OWSWindowManager { Environment.shared.windowManager } diff --git a/SessionMessagingKit/Utilities/OWSAudioSession.swift b/SessionMessagingKit/Utilities/OWSAudioSession.swift index 890c25055..65adae8e5 100644 --- a/SessionMessagingKit/Utilities/OWSAudioSession.swift +++ b/SessionMessagingKit/Utilities/OWSAudioSession.swift @@ -3,6 +3,7 @@ import Foundation import AVFoundation import SignalCoreKit +import SessionUtilitiesKit @objc(OWSAudioActivity) public class AudioActivity: NSObject { diff --git a/SessionMessagingKit/Utilities/ProximityMonitoringManager.swift b/SessionMessagingKit/Utilities/ProximityMonitoringManager.swift index 5a870cdd0..2739f356a 100644 --- a/SessionMessagingKit/Utilities/ProximityMonitoringManager.swift +++ b/SessionMessagingKit/Utilities/ProximityMonitoringManager.swift @@ -2,6 +2,7 @@ import Foundation import SignalCoreKit +import SessionUtilitiesKit @objc public protocol OWSProximityMonitoringManager: AnyObject { diff --git a/SessionMessagingKit/Utilities/SNProtoEnvelope+Conversion.swift b/SessionMessagingKit/Utilities/SNProtoEnvelope+Conversion.swift index d17f65563..5cb291067 100644 --- a/SessionMessagingKit/Utilities/SNProtoEnvelope+Conversion.swift +++ b/SessionMessagingKit/Utilities/SNProtoEnvelope+Conversion.swift @@ -2,6 +2,7 @@ import Foundation import SessionSnodeKit +import SessionUtilitiesKit public extension SNProtoEnvelope { static func from(_ message: SnodeReceivedMessage) -> SNProtoEnvelope? { diff --git a/SessionMessagingKit/Utilities/YapDatabaseConnection+OWS.h b/SessionMessagingKit/Utilities/YapDatabaseConnection+OWS.h deleted file mode 100644 index 2c7e6cc77..000000000 --- a/SessionMessagingKit/Utilities/YapDatabaseConnection+OWS.h +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import - -@class ECKeyPair; -@class PreKeyRecord; -@class SignedPreKeyRecord; -@class PreKeyBundle; - -NS_ASSUME_NONNULL_BEGIN - -@interface YapDatabaseConnection (OWS) - -- (BOOL)hasObjectForKey:(NSString *)key inCollection:(NSString *)collection; -- (BOOL)boolForKey:(NSString *)key inCollection:(NSString *)collection defaultValue:(BOOL)defaultValue; -- (double)doubleForKey:(NSString *)key inCollection:(NSString *)collection defaultValue:(double)defaultValue; -- (int)intForKey:(NSString *)key inCollection:(NSString *)collection; -- (nullable id)objectForKey:(NSString *)key inCollection:(NSString *)collection; -- (nullable NSDate *)dateForKey:(NSString *)key inCollection:(NSString *)collection; -- (nullable NSDictionary *)dictionaryForKey:(NSString *)key inCollection:(NSString *)collection; -- (nullable NSString *)stringForKey:(NSString *)key inCollection:(NSString *)collection; -- (nullable NSData *)dataForKey:(NSString *)key inCollection:(NSString *)collection; -- (nullable ECKeyPair *)keyPairForKey:(NSString *)key inCollection:(NSString *)collection; - -- (NSUInteger)numberOfKeysInCollection:(NSString *)collection; - -#pragma mark - - -- (void)setObject:(id)object forKey:(NSString *)key inCollection:(NSString *)collection; -- (void)setBool:(BOOL)value forKey:(NSString *)key inCollection:(NSString *)collection; -- (void)setDouble:(double)value forKey:(NSString *)key inCollection:(NSString *)collection; -- (void)removeObjectForKey:(NSString *)string inCollection:(NSString *)collection; -- (void)setInt:(int)integer forKey:(NSString *)key inCollection:(NSString *)collection; -- (void)setDate:(NSDate *)value forKey:(NSString *)key inCollection:(NSString *)collection; -- (int)incrementIntForKey:(NSString *)key inCollection:(NSString *)collection; - -- (void)purgeCollection:(NSString *)collection; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/Utilities/YapDatabaseConnection+OWS.m b/SessionMessagingKit/Utilities/YapDatabaseConnection+OWS.m deleted file mode 100644 index 3f30cf2a4..000000000 --- a/SessionMessagingKit/Utilities/YapDatabaseConnection+OWS.m +++ /dev/null @@ -1,154 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import "YapDatabaseConnection+OWS.h" -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -@implementation YapDatabaseConnection (OWS) - -- (BOOL)hasObjectForKey:(NSString *)key inCollection:(NSString *)collection -{ - return nil != [self objectForKey:key inCollection:collection]; -} - -- (nullable id)objectForKey:(NSString *)key inCollection:(NSString *)collection -{ - __block NSString *_Nullable object; - - [self readWithBlock:^(YapDatabaseReadTransaction *transaction) { - object = [transaction objectForKey:key inCollection:collection]; - }]; - - return object; -} - -- (nullable id)objectForKey:(NSString *)key inCollection:(NSString *)collection ofExpectedType:(Class)class -{ - id _Nullable value = [self objectForKey:key inCollection:collection]; - return value; -} - -- (nullable NSDictionary *)dictionaryForKey:(NSString *)key inCollection:(NSString *)collection -{ - return [self objectForKey:key inCollection:collection ofExpectedType:[NSDictionary class]]; -} - -- (nullable NSString *)stringForKey:(NSString *)key inCollection:(NSString *)collection -{ - return [self objectForKey:key inCollection:collection ofExpectedType:[NSString class]]; -} - -- (BOOL)boolForKey:(NSString *)key inCollection:(NSString *)collection defaultValue:(BOOL)defaultValue -{ - NSNumber *_Nullable value = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]]; - return value ? [value boolValue] : defaultValue; -} - -- (double)doubleForKey:(NSString *)key inCollection:(NSString *)collection defaultValue:(double)defaultValue -{ - NSNumber *_Nullable value = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]]; - return value ? [value doubleValue] : defaultValue; -} - -- (nullable NSData *)dataForKey:(NSString *)key inCollection:(NSString *)collection -{ - return [self objectForKey:key inCollection:collection ofExpectedType:[NSData class]]; -} - -- (nullable ECKeyPair *)keyPairForKey:(NSString *)key inCollection:(NSString *)collection -{ - return [self objectForKey:key inCollection:collection ofExpectedType:[ECKeyPair class]]; -} - -- (int)intForKey:(NSString *)key inCollection:(NSString *)collection -{ - NSNumber *_Nullable number = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]]; - return [number intValue]; -} - -- (nullable NSDate *)dateForKey:(NSString *)key inCollection:(NSString *)collection -{ - NSNumber *_Nullable value = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]]; - if (value) { - return [NSDate dateWithTimeIntervalSince1970:value.doubleValue]; - } else { - return nil; - } -} - -#pragma mark - - -- (NSUInteger)numberOfKeysInCollection:(NSString *)collection -{ - __block NSUInteger result; - [self readWithBlock:^(YapDatabaseReadTransaction *transaction) { - result = [transaction numberOfKeysInCollection:collection]; - }]; - return result; -} - -- (void)purgeCollection:(NSString *)collection -{ - [self readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [transaction removeAllObjectsInCollection:collection]; - }]; -} - -- (void)setObject:(id)object forKey:(NSString *)key inCollection:(NSString *)collection -{ - [self readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [transaction setObject:object forKey:key inCollection:collection]; - }]; -} - -- (void)setBool:(BOOL)value forKey:(NSString *)key inCollection:(NSString *)collection -{ - NSNumber *_Nullable oldValue = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]]; - if (oldValue && [@(value) isEqual:oldValue]) { - // Skip redundant writes. - return; - } - - [self setObject:@(value) forKey:key inCollection:collection]; -} - -- (void)setDouble:(double)value forKey:(NSString *)key inCollection:(NSString *)collection -{ - [self setObject:@(value) forKey:key inCollection:collection]; -} - -- (void)removeObjectForKey:(NSString *)key inCollection:(NSString *)collection -{ - [self readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [transaction removeObjectForKey:key inCollection:collection]; - }]; -} - -- (void)setInt:(int)value forKey:(NSString *)key inCollection:(NSString *)collection -{ - [self setObject:@(value) forKey:key inCollection:collection]; -} - -- (int)incrementIntForKey:(NSString *)key inCollection:(NSString *)collection -{ - __block int value = 0; - [self readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - value = [[transaction objectForKey:key inCollection:collection] intValue]; - value++; - [transaction setObject:@(value) forKey:key inCollection:collection]; - }]; - return value; -} - -- (void)setDate:(NSDate *)value forKey:(NSString *)key inCollection:(NSString *)collection -{ - [self setObject:@(value.timeIntervalSince1970) forKey:key inCollection:collection]; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/Utilities/YapDatabaseTransaction+OWS.h b/SessionMessagingKit/Utilities/YapDatabaseTransaction+OWS.h deleted file mode 100644 index 056a20aa5..000000000 --- a/SessionMessagingKit/Utilities/YapDatabaseTransaction+OWS.h +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import - -@class ECKeyPair; -@class PreKeyRecord; -@class PreKeyBundle; -@class SignedPreKeyRecord; - -NS_ASSUME_NONNULL_BEGIN - -@interface YapDatabaseReadTransaction (OWS) - -- (BOOL)boolForKey:(NSString *)key inCollection:(NSString *)collection defaultValue:(BOOL)defaultValue; -- (double)doubleForKey:(NSString *)key inCollection:(NSString *)collection defaultValue:(double)defaultValue; -- (int)intForKey:(NSString *)key inCollection:(NSString *)collection; -- (nullable NSDate *)dateForKey:(NSString *)key inCollection:(NSString *)collection; -- (nullable NSDictionary *)dictionaryForKey:(NSString *)key inCollection:(NSString *)collection; -- (nullable NSString *)stringForKey:(NSString *)key inCollection:(NSString *)collection; -- (nullable NSData *)dataForKey:(NSString *)key inCollection:(NSString *)collection; -- (nullable ECKeyPair *)keyPairForKey:(NSString *)key inCollection:(NSString *)collection; - -@end - -#pragma mark - - -@interface YapDatabaseReadWriteTransaction (OWS) - -#pragma mark - Debug - -#if DEBUG -- (void)snapshotCollection:(NSString *)collection snapshotFilePath:(NSString *)snapshotFilePath; -- (void)restoreSnapshotOfCollection:(NSString *)collection snapshotFilePath:(NSString *)snapshotFilePath; -#endif - -- (void)setBool:(BOOL)value forKey:(NSString *)key inCollection:(NSString *)collection; -- (void)setDate:(NSDate *)value forKey:(NSString *)key inCollection:(NSString *)collection; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/Utilities/YapDatabaseTransaction+OWS.m b/SessionMessagingKit/Utilities/YapDatabaseTransaction+OWS.m deleted file mode 100644 index c102ee6e3..000000000 --- a/SessionMessagingKit/Utilities/YapDatabaseTransaction+OWS.m +++ /dev/null @@ -1,116 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import "YapDatabaseTransaction+OWS.h" -#import - -NS_ASSUME_NONNULL_BEGIN - -@implementation YapDatabaseReadTransaction (OWS) - -- (nullable id)objectForKey:(NSString *)key inCollection:(NSString *)collection ofExpectedType:(Class) class { - id _Nullable value = [self objectForKey:key inCollection:collection]; - return value; -} - -- (nullable NSDictionary *)dictionaryForKey : (NSString *)key inCollection : (NSString *)collection -{ - return [self objectForKey:key inCollection:collection ofExpectedType:[NSDictionary class]]; -} - -- (nullable NSString *)stringForKey:(NSString *)key inCollection:(NSString *)collection -{ - return [self objectForKey:key inCollection:collection ofExpectedType:[NSString class]]; -} - -- (BOOL)boolForKey:(NSString *)key inCollection:(NSString *)collection defaultValue:(BOOL)defaultValue -{ - NSNumber *_Nullable value = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]]; - return value ? [value boolValue] : defaultValue; -} - -- (double)doubleForKey:(NSString *)key inCollection:(NSString *)collection defaultValue:(double)defaultValue -{ - NSNumber *_Nullable value = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]]; - return value ? [value doubleValue] : defaultValue; -} - -- (nullable NSData *)dataForKey:(NSString *)key inCollection:(NSString *)collection -{ - return [self objectForKey:key inCollection:collection ofExpectedType:[NSData class]]; -} - -- (nullable ECKeyPair *)keyPairForKey:(NSString *)key inCollection:(NSString *)collection -{ - return [self objectForKey:key inCollection:collection ofExpectedType:[ECKeyPair class]]; -} - -- (int)intForKey:(NSString *)key inCollection:(NSString *)collection -{ - NSNumber *_Nullable number = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]]; - return [number intValue]; -} - -- (nullable NSDate *)dateForKey:(NSString *)key inCollection:(NSString *)collection -{ - NSNumber *_Nullable value = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]]; - if (value) { - return [NSDate dateWithTimeIntervalSince1970:value.doubleValue]; - } else { - return nil; - } -} - -@end - -#pragma mark - - -@implementation YapDatabaseReadWriteTransaction (OWS) - -#pragma mark - Debug - -#if DEBUG -- (void)snapshotCollection:(NSString *)collection snapshotFilePath:(NSString *)snapshotFilePath -{ - NSMutableDictionary *snapshot = [NSMutableDictionary new]; - [self enumerateKeysAndObjectsInCollection:collection - usingBlock:^(NSString *_Nonnull key, id _Nonnull value, BOOL *_Nonnull stop) { - snapshot[key] = value; - }]; - NSData *_Nullable data = [NSKeyedArchiver archivedDataWithRootObject:snapshot]; - BOOL success = [data writeToFile:snapshotFilePath atomically:YES]; -} - -- (void)restoreSnapshotOfCollection:(NSString *)collection snapshotFilePath:(NSString *)snapshotFilePath -{ - - NSData *_Nullable data = [NSData dataWithContentsOfFile:snapshotFilePath]; - NSMutableDictionary *_Nullable snapshot = [NSKeyedUnarchiver unarchiveObjectWithData:data]; - - [self removeAllObjectsInCollection:collection]; - [snapshot enumerateKeysAndObjectsUsingBlock:^(NSString *_Nonnull key, id _Nonnull value, BOOL *_Nonnull stop) { - [self setObject:value forKey:key inCollection:collection]; - }]; -} -#endif - -- (void)setBool:(BOOL)value forKey:(NSString *)key inCollection:(NSString *)collection -{ - NSNumber *_Nullable oldValue = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]]; - if (oldValue && [@(value) isEqual:oldValue]) { - // Skip redundant writes. - return; - } - - [self setObject:@(value) forKey:key inCollection:collection]; -} - -- (void)setDate:(NSDate *)value forKey:(NSString *)key inCollection:(NSString *)collection -{ - [self setObject:@(value.timeIntervalSince1970) forKey:key inCollection:collection]; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionNotificationServiceExtension/NotificationServiceExtension.swift b/SessionNotificationServiceExtension/NotificationServiceExtension.swift index c0df8e76d..77055d422 100644 --- a/SessionNotificationServiceExtension/NotificationServiceExtension.swift +++ b/SessionNotificationServiceExtension/NotificationServiceExtension.swift @@ -125,8 +125,6 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension completion() } ) - - NotificationCenter.default.addObserver(self, selector: #selector(storageIsReady), name: .StorageIsReady, object: nil) } @objc @@ -145,13 +143,6 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension checkIsAppReady() } - @objc - private func storageIsReady() { - AssertIsOnMainThread() - - checkIsAppReady() - } - @objc private func checkIsAppReady() { AssertIsOnMainThread() @@ -160,7 +151,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension guard !AppReadiness.isAppReady() else { return } // App isn't ready until storage is ready AND all version migrations are complete. - guard OWSStorage.isStorageReady() && areVersionMigrationsComplete else { return } + guard GRDBStorage.shared.isValid && areVersionMigrationsComplete else { return } SignalUtilitiesKit.Configuration.performMainSetup() diff --git a/SessionShareExtension/ShareVC.swift b/SessionShareExtension/ShareVC.swift index a300e2bbe..0f168e201 100644 --- a/SessionShareExtension/ShareVC.swift +++ b/SessionShareExtension/ShareVC.swift @@ -56,13 +56,6 @@ final class ShareVC : UINavigationController, ShareViewDelegate, AppModeManagerD ) // We don't need to use "screen protection" in the SAE. - - NotificationCenter.default.addObserver( - self, - selector: #selector(storageIsReady), - name: .StorageIsReady, - object: nil - ) NotificationCenter.default.addObserver( self, selector: #selector(applicationDidEnterBackground), @@ -89,22 +82,13 @@ final class ShareVC : UINavigationController, ShareViewDelegate, AppModeManagerD checkIsAppReady() } - @objc - func storageIsReady() { - AssertIsOnMainThread() - - Logger.debug("") - - checkIsAppReady() - } - @objc func checkIsAppReady() { AssertIsOnMainThread() // App isn't ready until storage is ready AND all version migrations are complete. guard areVersionMigrationsComplete else { return } - guard OWSStorage.isStorageReady() else { return } + guard GRDBStorage.shared.isValid else { return } guard !AppReadiness.isAppReady() else { // Only mark the app as ready once. return diff --git a/SessionSnodeKit/Configuration.swift b/SessionSnodeKit/Configuration.swift index 24df07e8e..11a6c6944 100644 --- a/SessionSnodeKit/Configuration.swift +++ b/SessionSnodeKit/Configuration.swift @@ -3,10 +3,6 @@ import Foundation import SessionUtilitiesKit -public struct SNSnodeKitConfiguration { - internal static var shared: SNSnodeKitConfiguration! -} - public enum SNSnodeKit { // Just to make the external API nice public static func migrations() -> TargetMigrations { return TargetMigrations( diff --git a/SessionSnodeKit/Database/Migrations/_003_YDBToGRDBMigration.swift b/SessionSnodeKit/Database/Migrations/_003_YDBToGRDBMigration.swift index 65f982d4d..2919396f3 100644 --- a/SessionSnodeKit/Database/Migrations/_003_YDBToGRDBMigration.swift +++ b/SessionSnodeKit/Database/Migrations/_003_YDBToGRDBMigration.swift @@ -2,6 +2,7 @@ import Foundation import GRDB +import YapDatabase import SessionUtilitiesKit enum _003_YDBToGRDBMigration: Migration { diff --git a/SessionUtilitiesKit/Configuration.swift b/SessionUtilitiesKit/Configuration.swift index c102292d2..b0f728ee0 100644 --- a/SessionUtilitiesKit/Configuration.swift +++ b/SessionUtilitiesKit/Configuration.swift @@ -1,13 +1,14 @@ +// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. + +import Foundation @objc public final class SNUtilitiesKitConfiguration : NSObject { - @objc public let owsPrimaryStorage: OWSPrimaryStorageProtocol public let maxFileSize: UInt @objc public static var shared: SNUtilitiesKitConfiguration! - fileprivate init(owsPrimaryStorage: OWSPrimaryStorageProtocol, maxFileSize: UInt) { - self.owsPrimaryStorage = owsPrimaryStorage + fileprivate init(maxFileSize: UInt) { self.maxFileSize = maxFileSize } } @@ -29,7 +30,7 @@ public enum SNUtilitiesKit { // Just to make the external API nice ) } - public static func configure(owsPrimaryStorage: OWSPrimaryStorageProtocol, maxFileSize: UInt) { - SNUtilitiesKitConfiguration.shared = SNUtilitiesKitConfiguration(owsPrimaryStorage: owsPrimaryStorage, maxFileSize: maxFileSize) + public static func configure(maxFileSize: UInt) { + SNUtilitiesKitConfiguration.shared = SNUtilitiesKitConfiguration(maxFileSize: maxFileSize) } } diff --git a/SessionUtilitiesKit/Database/GRDBStorage.swift b/SessionUtilitiesKit/Database/GRDBStorage.swift index 4009d7b3c..ff3326221 100644 --- a/SessionUtilitiesKit/Database/GRDBStorage.swift +++ b/SessionUtilitiesKit/Database/GRDBStorage.swift @@ -257,7 +257,7 @@ public final class GRDBStorage { // MARK: - File Management - private static func resetAllStorage() { + public static func resetAllStorage() { NotificationCenter.default.post(name: .resetStorage, object: nil) // This might be redundant but in the spirit of thoroughness... diff --git a/SessionUtilitiesKit/Database/Migrations/_003_YDBToGRDBMigration.swift b/SessionUtilitiesKit/Database/Migrations/_003_YDBToGRDBMigration.swift index fc87b4c85..df806b93c 100644 --- a/SessionUtilitiesKit/Database/Migrations/_003_YDBToGRDBMigration.swift +++ b/SessionUtilitiesKit/Database/Migrations/_003_YDBToGRDBMigration.swift @@ -2,6 +2,7 @@ import Foundation import GRDB +import YapDatabase enum _003_YDBToGRDBMigration: Migration { static let target: TargetMigrations.Identifier = .utilitiesKit diff --git a/SessionUtilitiesKit/Database/OWSPrimaryStorageProtocol.swift b/SessionUtilitiesKit/Database/OWSPrimaryStorageProtocol.swift deleted file mode 100644 index 49f6b327c..000000000 --- a/SessionUtilitiesKit/Database/OWSPrimaryStorageProtocol.swift +++ /dev/null @@ -1,7 +0,0 @@ -import YapDatabase - -@objc public protocol OWSPrimaryStorageProtocol { - - var dbReadConnection: YapDatabaseConnection { get } - var dbReadWriteConnection: YapDatabaseConnection { get } -} diff --git a/SessionUtilitiesKit/Database/Storage.swift b/SessionUtilitiesKit/Database/Storage.swift deleted file mode 100644 index a2e2dcbc5..000000000 --- a/SessionUtilitiesKit/Database/Storage.swift +++ /dev/null @@ -1,71 +0,0 @@ -import PromiseKit -import YapDatabase - -// Some important notes about YapDatabase: -// -// • Connections are thread-safe. -// • Executing a write transaction from within a write transaction is NOT allowed. - -@objc(LKStorage) -public final class Storage : NSObject { - public static let serialQueue = DispatchQueue(label: "Storage.serialQueue", qos: .userInitiated) - - private static var owsStorage: OWSPrimaryStorageProtocol { SNUtilitiesKitConfiguration.shared.owsPrimaryStorage } - - @objc public static let shared = Storage() - - // MARK: Reading - - // Some important points regarding reading from the database: - // - // • Background threads should use `OWSPrimaryStorage`'s `dbReadConnection`, whereas the main thread should use `OWSPrimaryStorage`'s `uiDatabaseConnection` (see the `YapDatabaseConnectionPool` documentation for more information). - // • Multiple read transactions can safely be executed at the same time. - - @objc(readWithBlock:) - public static func read(with block: @escaping (YapDatabaseReadTransaction) -> Void) { - owsStorage.dbReadConnection.read(block) - } - - // MARK: Writing - - // Some important points regarding writing to the database: - // - // • There can only be a single write transaction per database at any one time, so all write transactions must use `OWSPrimaryStorage`'s `dbReadWriteConnection`. - // • Executing a write transaction from within a write transaction causes a deadlock and must be avoided. - - @discardableResult - @objc(writeWithBlock:) - public static func objc_write(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) -> AnyPromise { - return AnyPromise.from(write(with: block) { }) - } - - @discardableResult - public static func write(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) -> Promise { - return write(with: block) { } - } - - @discardableResult - @objc(writeWithBlock:completion:) - public static func objc_write(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void, completion: @escaping () -> Void) -> AnyPromise { - return AnyPromise.from(write(with: block, completion: completion)) - } - - @discardableResult - public static func write(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void, completion: @escaping () -> Void) -> Promise { - let (promise, seal) = Promise.pending() - serialQueue.async { - owsStorage.dbReadWriteConnection.readWrite { transaction in - transaction.addCompletionQueue(DispatchQueue.main, completionBlock: completion) - block(transaction) - } - seal.fulfill(()) - } - return promise - } - - /// Blocks the calling thread until the write has finished. - @objc(writeSyncWithBlock:) - public static func writeSync(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) { - try! write(with: block, completion: { }).wait() // The promise returned by write(with:completion:) never rejects - } -} diff --git a/SessionUtilitiesKit/Database/TSYapDatabaseObject.h b/SessionUtilitiesKit/Database/TSYapDatabaseObject.h deleted file mode 100644 index 4ddcdcedd..000000000 --- a/SessionUtilitiesKit/Database/TSYapDatabaseObject.h +++ /dev/null @@ -1,165 +0,0 @@ -// -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. -// - -#import -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -@class OWSPrimaryStorage; -@class YapDatabaseConnection; -@class YapDatabaseReadTransaction; -@class YapDatabaseReadWriteTransaction; - -@interface TSYapDatabaseObject : MTLModel - -- (instancetype)init NS_DESIGNATED_INITIALIZER; - -/** - * Initializes a new database object with a unique identifier - * - * @param uniqueId Key used for the key-value store - * - * @return Initialized object - */ -- (instancetype)initWithUniqueId:(NSString *_Nullable)uniqueId NS_DESIGNATED_INITIALIZER; - -- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - -/** - * Returns the collection to which the object belongs. - * - * @return Key (string) identifying the collection - */ -+ (NSString *)collection; - -/** - * Get the number of keys in the models collection. Be aware that if there - * are multiple object types in this collection that the count will include - * the count of other objects in the same collection. - * - * @return The number of keys in the classes collection. - */ -+ (NSUInteger)numberOfKeysInCollection; -+ (NSUInteger)numberOfKeysInCollectionWithTransaction:(YapDatabaseReadTransaction *)transaction; - -/** - * Removes all objects in the classes collection. - */ -+ (void)removeAllObjectsInCollection; - -/** - * A memory intesive method to get all objects in the collection. You should prefer using enumeration over this method - * whenever feasible. See `enumerateObjectsInCollectionUsingBlock` - * - * @return All objects in the classes collection. - */ -+ (NSArray *)allObjectsInCollection; - -/** - * Enumerates all objects in collection. - */ -+ (void)enumerateCollectionObjectsUsingBlock:(void (^)(id obj, BOOL *stop))block; -+ (void)enumerateCollectionObjectsWithTransaction:(YapDatabaseReadTransaction *)transaction - usingBlock:(void (^)(id object, BOOL *stop))block; - -/** - * @return Shared database connections for reading and writing. - */ -- (YapDatabaseConnection *)dbReadConnection; -+ (YapDatabaseConnection *)dbReadConnection; -- (YapDatabaseConnection *)dbReadWriteConnection; -+ (YapDatabaseConnection *)dbReadWriteConnection; - -/** - * Fetches the object with the provided identifier - * - * @param uniqueID Unique identifier of the entry in a collection - * @param transaction Transaction used for fetching the object - * - * @return Instance of the object or nil if non-existent - */ -+ (nullable instancetype)fetchObjectWithUniqueID:(NSString *)uniqueID - transaction:(YapDatabaseReadTransaction *)transaction - NS_SWIFT_NAME(fetch(uniqueId:transaction:)); -+ (nullable instancetype)fetchObjectWithUniqueID:(NSString *)uniqueID NS_SWIFT_NAME(fetch(uniqueId:)); - -/** - * Saves the object with the shared readWrite connection. - * - * This method will block if another readWrite transaction is open. - */ -- (void)save; - -/** - * Assign the latest persisted values from the database. - */ -- (void)reload; -- (void)reloadWithTransaction:(YapDatabaseReadTransaction *)transaction; -- (void)reloadWithTransaction:(YapDatabaseReadTransaction *)transaction ignoreMissing:(BOOL)ignoreMissing; - -/** - * Saves the object with the shared readWrite connection - does not block. - * - * Be mindful that this method may clobber other changes persisted - * while waiting to open the readWrite transaction. - * - * @param completionBlock is called on the main thread - */ -- (void)saveAsyncWithCompletionBlock:(void (^_Nullable)(void))completionBlock; - -/** - * Saves the object with the provided transaction - * - * @param transaction Database transaction - */ -- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction; - -/** - * `touch` is a cheap way to fire a YapDatabaseModified notification to redraw anythign depending on the model. - */ -- (void)touch; -- (void)touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction; - -/** - * The unique identifier of the stored object - */ -@property (nonatomic, nullable) NSString *uniqueId; - -- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction; -- (void)remove; - -#pragma mark - Update With... - -// This method is used by "updateWith..." methods. -// -// This model may be updated from many threads. We don't want to save -// our local copy (this instance) since it may be out of date. We also -// want to avoid re-saving a model that has been deleted. Therefore, we -// use "updateWith..." methods to: -// -// a) Update a property of this instance. -// b) If a copy of this model exists in the database, load an up-to-date copy, -// and update and save that copy. -// b) If a copy of this model _DOES NOT_ exist in the database, do _NOT_ save -// this local instance. -// -// After "updateWith...": -// -// a) Any copy of this model in the database will have been updated. -// b) The local property on this instance will always have been updated. -// c) Other properties on this instance may be out of date. -// -// All mutable properties of this class have been made read-only to -// prevent accidentally modifying them directly. -// -// This isn't a perfect arrangement, but in practice this will prevent -// data loss and will resolve all known issues. -- (void)applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction - changeBlock:(void (^)(id))changeBlock; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionUtilitiesKit/Database/TSYapDatabaseObject.m b/SessionUtilitiesKit/Database/TSYapDatabaseObject.m deleted file mode 100644 index 1c3c84b0a..000000000 --- a/SessionUtilitiesKit/Database/TSYapDatabaseObject.m +++ /dev/null @@ -1,229 +0,0 @@ -// -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. -// - -#import "TSYapDatabaseObject.h" -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -@implementation TSYapDatabaseObject - -- (instancetype)init -{ - return [self initWithUniqueId:[[NSUUID UUID] UUIDString]]; -} - -- (instancetype)initWithUniqueId:(NSString *_Nullable)aUniqueId -{ - self = [super init]; - if (!self) { - return self; - } - - _uniqueId = aUniqueId; - - return self; -} - -- (nullable instancetype)initWithCoder:(NSCoder *)coder -{ - self = [super initWithCoder:coder]; - if (!self) { - return self; - } - - return self; -} - -- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction -{ - [transaction setObject:self forKey:self.uniqueId inCollection:[[self class] collection]]; -} - -- (void)save -{ - [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [self saveWithTransaction:transaction]; - }]; -} - -- (void)saveAsyncWithCompletionBlock:(void (^_Nullable)(void))completionBlock -{ - [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [self saveWithTransaction:transaction]; - } completion:completionBlock]; -} - -- (void)touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction -{ - [transaction touchObjectForKey:self.uniqueId inCollection:[self.class collection]]; -} - -- (void)touch -{ - [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [self touchWithTransaction:transaction]; - }]; -} - -- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction -{ - [transaction removeObjectForKey:self.uniqueId inCollection:[[self class] collection]]; -} - -- (void)remove -{ - [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [self removeWithTransaction:transaction]; - }]; -} - -- (YapDatabaseConnection *)dbReadConnection -{ - return [[self class] dbReadConnection]; -} - -- (YapDatabaseConnection *)dbReadWriteConnection -{ - return [[self class] dbReadWriteConnection]; -} - -#pragma mark Class Methods - -+ (MTLPropertyStorage)storageBehaviorForPropertyWithKey:(NSString *)propertyKey -{ - if ([propertyKey isEqualToString:@"TAG"]) { - return MTLPropertyStorageNone; - } else { - return [super storageBehaviorForPropertyWithKey:propertyKey]; - } -} - -+ (YapDatabaseConnection *)dbReadConnection -{ - // We use TSYapDatabaseObject's dbReadWriteConnection (not OWSPrimaryStorage's - // dbReadConnection) for consistency, since we tend to [TSYapDatabaseObject - // save] and want to write to the same connection we read from. To get true - // consistency, we'd want to update entities by reading & writing from within - // the same transaction, but that'll be a big refactor. - return self.dbReadWriteConnection; -} - -+ (YapDatabaseConnection *)dbReadWriteConnection -{ - return SNUtilitiesKitConfiguration.shared.owsPrimaryStorage.dbReadWriteConnection; -} - -+ (NSString *)collection -{ - return NSStringFromClass([self class]); -} - -+ (NSUInteger)numberOfKeysInCollection -{ - __block NSUInteger count; - [[self dbReadConnection] readWithBlock:^(YapDatabaseReadTransaction *transaction) { - count = [self numberOfKeysInCollectionWithTransaction:transaction]; - }]; - return count; -} - -+ (NSUInteger)numberOfKeysInCollectionWithTransaction:(YapDatabaseReadTransaction *)transaction -{ - return [transaction numberOfKeysInCollection:[self collection]]; -} - -+ (NSArray *)allObjectsInCollection -{ - __block NSMutableArray *all = [[NSMutableArray alloc] initWithCapacity:[self numberOfKeysInCollection]]; - [self enumerateCollectionObjectsUsingBlock:^(id object, BOOL *stop) { - [all addObject:object]; - }]; - return [all copy]; -} - -+ (void)enumerateCollectionObjectsUsingBlock:(void (^)(id object, BOOL *stop))block -{ - [[self dbReadConnection] readWithBlock:^(YapDatabaseReadTransaction *transaction) { - [self enumerateCollectionObjectsWithTransaction:transaction usingBlock:block]; - }]; -} - -+ (void)enumerateCollectionObjectsWithTransaction:(YapDatabaseReadTransaction *)transaction - usingBlock:(void (^)(id object, BOOL *stop))block -{ - // Ignoring most of the YapDB parameters, and just passing through the ones we usually use. - void (^yapBlock)(NSString *key, id object, id metadata, BOOL *stop) - = ^void(NSString *key, id object, id metadata, BOOL *stop) { - block(object, stop); - }; - - [transaction enumerateRowsInCollection:[self collection] usingBlock:yapBlock]; -} - -+ (void)removeAllObjectsInCollection -{ - [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [transaction removeAllObjectsInCollection:[self collection]]; - }]; -} - -+ (nullable instancetype)fetchObjectWithUniqueID:(NSString *)uniqueID - transaction:(YapDatabaseReadTransaction *)transaction -{ - return [transaction objectForKey:uniqueID inCollection:[self collection]]; -} - -+ (nullable instancetype)fetchObjectWithUniqueID:(NSString *)uniqueID -{ - __block id _Nullable object = nil; - [[self dbReadConnection] readWithBlock:^(YapDatabaseReadTransaction *transaction) { - object = [transaction objectForKey:uniqueID inCollection:[self collection]]; - }]; - return object; -} - -#pragma mark - Update With... - -- (void)applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction - changeBlock:(void (^)(id))changeBlock -{ - changeBlock(self); - - NSString *collection = [[self class] collection]; - id latestInstance = [transaction objectForKey:self.uniqueId inCollection:collection]; - if (latestInstance) { - changeBlock(latestInstance); - [latestInstance saveWithTransaction:transaction]; - } -} - -#pragma mark Reload - -- (void)reload -{ - [self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { - [self reloadWithTransaction:transaction]; - }]; -} - -- (void)reloadWithTransaction:(YapDatabaseReadTransaction *)transaction -{ - [self reloadWithTransaction:transaction ignoreMissing:NO]; -} - -- (void)reloadWithTransaction:(YapDatabaseReadTransaction *)transaction ignoreMissing:(BOOL)ignoreMissing -{ - TSYapDatabaseObject *latest = [[self class] fetchObjectWithUniqueID:self.uniqueId transaction:transaction]; - if (!latest) { - return; - } - - [self setValuesForKeysWithDictionary:latest.dictionaryValue]; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/SessionUtilitiesKit/Meta/SessionUtilitiesKit.h b/SessionUtilitiesKit/Meta/SessionUtilitiesKit.h index fc889a5b2..4e92094f7 100644 --- a/SessionUtilitiesKit/Meta/SessionUtilitiesKit.h +++ b/SessionUtilitiesKit/Meta/SessionUtilitiesKit.h @@ -15,7 +15,6 @@ FOUNDATION_EXPORT const unsigned char SessionUtilitiesKitVersionString[]; #import #import #import -#import #import #import diff --git a/SignalUtilitiesKit/Configuration.swift b/SignalUtilitiesKit/Configuration.swift index 000a6ef43..a89b6e5d9 100644 --- a/SignalUtilitiesKit/Configuration.swift +++ b/SignalUtilitiesKit/Configuration.swift @@ -1,20 +1,14 @@ import SessionMessagingKit import SessionSnodeKit -extension OWSPrimaryStorage : OWSPrimaryStorageProtocol { } - -@objc(SNConfiguration) -public final class Configuration : NSObject { - - - @objc public static func performMainSetup() { +public enum Configuration { + public static func performMainSetup() { // Need to do this first to ensure the legacy database exists SNUtilitiesKit.configure( - owsPrimaryStorage: OWSPrimaryStorage.shared(), maxFileSize: UInt(Double(FileServerAPIV2.maxFileSize) / FileServerAPIV2.fileSizeORMultiplier) ) - SNMessagingKit.configure(storage: Storage.shared) + SNMessagingKit.configure() SNSnodeKit.configure() } } diff --git a/SignalUtilitiesKit/Database/YapDatabase+Promise.swift b/SignalUtilitiesKit/Database/YapDatabase+Promise.swift deleted file mode 100644 index 49ad9fcc0..000000000 --- a/SignalUtilitiesKit/Database/YapDatabase+Promise.swift +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -import Foundation -import PromiseKit - -public extension YapDatabaseConnection { - - @objc - func readWritePromise(_ block: @escaping (YapDatabaseReadWriteTransaction) -> Void) -> AnyPromise { - return AnyPromise(readWritePromise(block) as Promise) - } - - func readWritePromise(_ block: @escaping (YapDatabaseReadWriteTransaction) -> Void) -> Promise { - return Promise { resolver in - self.asyncReadWrite(block, completionBlock: { resolver.fulfill(()) }) - } - } - - func read(_ block: @escaping (YapDatabaseReadTransaction) throws -> Void) throws { - var errorToRaise: Error? - - read { transaction in - do { - try block(transaction) - } catch { - errorToRaise = error - } - } - - if let errorToRaise = errorToRaise { - throw errorToRaise - } - } - - func readWrite(_ block: @escaping (YapDatabaseReadWriteTransaction) throws -> Void) throws { - var errorToRaise: Error? - - readWrite { transaction in - do { - try block(transaction) - } catch { - errorToRaise = error - } - } - - if let errorToRaise = errorToRaise { - throw errorToRaise - } - } -} diff --git a/SignalUtilitiesKit/Utilities/AppSetup.swift b/SignalUtilitiesKit/Utilities/AppSetup.swift index 021f2a3c6..61a0fc0b3 100644 --- a/SignalUtilitiesKit/Utilities/AppSetup.swift +++ b/SignalUtilitiesKit/Utilities/AppSetup.swift @@ -25,13 +25,10 @@ public enum AppSetup { // All of these "singletons" should have any dependencies used in their // initializers injected. OWSBackgroundTaskManager.shared().observeNotifications() - - let primaryStorage: OWSPrimaryStorage = OWSPrimaryStorage(storage: ()) - OWSPrimaryStorage.protectFiles() - + // AFNetworking (via CFNetworking) spools it's attachments to NSTemporaryDirectory(). - // If you receive a media message while the device is locked, the download will fail if the temporary directory - // is NSFileProtectionComplete + // If you receive a media message while the device is locked, the download will fail if + // the temporary directory is NSFileProtectionComplete let success: Bool = OWSFileSystem.protectFileOrFolder( atPath: NSTemporaryDirectory(), fileProtectionType: .completeUntilFirstUserAuthentication @@ -39,10 +36,8 @@ public enum AppSetup { assert(success) Environment.shared = Environment( - primaryStorage: primaryStorage, reachabilityManager: SSKReachabilityManagerImpl(), audioSession: OWSAudioSession(), - preferences: OWSPreferences(), proximityMonitoringManager: OWSProximityMonitoringManagerImpl(), windowManager: OWSWindowManager(default: ()) ) diff --git a/SignalUtilitiesKit/Utilities/OWSAlerts.swift b/SignalUtilitiesKit/Utilities/OWSAlerts.swift index 5db9ecf7d..caa9d7e6d 100644 --- a/SignalUtilitiesKit/Utilities/OWSAlerts.swift +++ b/SignalUtilitiesKit/Utilities/OWSAlerts.swift @@ -3,6 +3,7 @@ // import Foundation +import SessionUtilitiesKit @objc public class OWSAlerts: NSObject { @@ -93,32 +94,4 @@ import Foundation action.accessibilityIdentifier = "OWSAlerts.\("cancel")" return action } - - @objc - public class func showIOSUpgradeNagIfNecessary() { - // Our min SDK is iOS9, so this will only show for iOS9 users - if #available(iOS 10.0, *) { - return - } - - // Don't show the nag to users who have just launched - // the app for the first time. - guard AppVersion.sharedInstance().lastAppVersion != nil else { - return - } - - if let iOSUpgradeNagDate = Environment.shared.preferences.iOSUpgradeNagDate() { - let kNagFrequencySeconds = 14 * kDayInterval - guard fabs(iOSUpgradeNagDate.timeIntervalSinceNow) > kNagFrequencySeconds else { - return - } - } - - Environment.shared.preferences.setIOSUpgradeNagDate(Date()) - - OWSAlerts.showAlert(title: NSLocalizedString("UPGRADE_IOS_ALERT_TITLE", - comment: "Title for the alert indicating that user should upgrade iOS."), - message: NSLocalizedString("UPGRADE_IOS_ALERT_MESSAGE", - comment: "Message for the alert indicating that user should upgrade iOS.")) - } }