Fixed a few more PN logic issues

Sorted out some more threading issues
Removed a redundant SyncPushTokensJob run
Fixed an issue where the NotificationServiceExtension could incorrectly setup the database before setting up it's context
Fixed a few warnings
Removed a bunch of legacy code
Refactored the MainAppContext from Objective C into Swift
This commit is contained in:
Morgan Pretty 2023-08-10 14:43:40 +10:00
parent 49f2d3bfe2
commit 5285d81177
97 changed files with 498 additions and 2254 deletions

View File

@ -19,7 +19,6 @@
3496956021A2FC8100DCFE74 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3496955F21A2FC8100DCFE74 /* CloudKit.framework */; };
34A6C28021E503E700B5B12E /* OWSImagePickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A6C27F21E503E600B5B12E /* OWSImagePickerController.swift */; };
34A8B3512190A40E00218A25 /* MediaAlbumView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A8B3502190A40E00218A25 /* MediaAlbumView.swift */; };
34B0796D1FCF46B100E248C2 /* MainAppContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B0796B1FCF46B000E248C2 /* MainAppContext.m */; };
34B6A903218B3F63007C4606 /* TypingIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B6A902218B3F62007C4606 /* TypingIndicatorView.swift */; };
34BECE2E1F7ABCE000D7438D /* GifPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34BECE2D1F7ABCE000D7438D /* GifPickerViewController.swift */; };
34BECE301F7ABCF800D7438D /* GifPickerLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34BECE2F1F7ABCF800D7438D /* GifPickerLayout.swift */; };
@ -314,27 +313,13 @@
C33FDC29255A581F00E217F9 /* ReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA6F255A57FA00E217F9 /* ReachabilityManager.swift */; };
C33FDC45255A581F00E217F9 /* AppVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA8B255A57FD00E217F9 /* AppVersion.m */; };
C33FDC58255A582000E217F9 /* ReverseDispatchQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA9E255A57FF00E217F9 /* ReverseDispatchQueue.swift */; };
C33FDC78255A582000E217F9 /* TSConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDABE255A580100E217F9 /* TSConstants.m */; };
C33FDC98255A582000E217F9 /* SwiftSingletons.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDADE255A580400E217F9 /* SwiftSingletons.swift */; };
C33FDC9A255A582000E217F9 /* ByteParser.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAE0255A580400E217F9 /* ByteParser.m */; };
C33FDCD1255A582000E217F9 /* FunctionalUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB17255A580800E217F9 /* FunctionalUtil.m */; };
C33FDCFA255A582000E217F9 /* SignalIOSProto.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB40255A580C00E217F9 /* SignalIOSProto.swift */; };
C33FDD03255A582000E217F9 /* WeakTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB49255A580C00E217F9 /* WeakTimer.swift */; };
C33FDD06255A582000E217F9 /* AppVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB4C255A580D00E217F9 /* AppVersion.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDD23255A582000E217F9 /* FeatureFlags.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB69255A580F00E217F9 /* FeatureFlags.swift */; };
C33FDD32255A582000E217F9 /* OWSOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB78255A581000E217F9 /* OWSOperation.m */; };
C33FDD3A255A582000E217F9 /* Notification+Loki.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB80255A581100E217F9 /* Notification+Loki.swift */; };
C33FDD49255A582000E217F9 /* ParamParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB8F255A581200E217F9 /* ParamParser.swift */; };
C33FDD5B255A582000E217F9 /* OWSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDBA1255A581400E217F9 /* OWSOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDD6E255A582000E217F9 /* NSURLSessionDataTask+StatusCode.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBB4255A581600E217F9 /* NSURLSessionDataTask+StatusCode.m */; };
C33FDD8D255A582000E217F9 /* OWSSignalAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBD3255A581800E217F9 /* OWSSignalAddress.swift */; };
C33FDD92255A582000E217F9 /* SignalIOS.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBD8255A581900E217F9 /* SignalIOS.pb.swift */; };
C33FDDB0255A582000E217F9 /* NSURLSessionDataTask+StatusCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDBF6255A581C00E217F9 /* NSURLSessionDataTask+StatusCode.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDDB3255A582000E217F9 /* OWSError.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDBF9255A581C00E217F9 /* OWSError.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDDBD255A582000E217F9 /* ByteParser.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDC03255A581D00E217F9 /* ByteParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDDC5255A582000E217F9 /* OWSError.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDC0B255A581D00E217F9 /* OWSError.m */; };
C33FDDCC255A582000E217F9 /* TSConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDC12255A581E00E217F9 /* TSConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDDD0255A582000E217F9 /* FunctionalUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDC16255A581E00E217F9 /* FunctionalUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
C3402FE52559036600EA6424 /* SessionUIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C331FF1B2558F9D300070591 /* SessionUIKit.framework */; };
C3471ECB2555356A00297E91 /* MessageSender+Encryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471ECA2555356A00297E91 /* MessageSender+Encryption.swift */; };
C3471F4C25553AB000297E91 /* MessageReceiver+Decryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471F4B25553AB000297E91 /* MessageReceiver+Decryption.swift */; };
@ -837,6 +822,7 @@
FDDCBDAD29E776BF00303C38 /* seed3-2023-2y.der in Resources */ = {isa = PBXBuildFile; fileRef = FDDCBDA729E776BF00303C38 /* seed3-2023-2y.der */; };
FDDF074429C3E3D000E5E8B5 /* FetchRequest+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDDF074329C3E3D000E5E8B5 /* FetchRequest+Utilities.swift */; };
FDDF074A29DAB36900E5E8B5 /* JobRunnerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDDF074929DAB36900E5E8B5 /* JobRunnerSpec.swift */; };
FDE125232A837E4E002DA685 /* MainAppContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDE125222A837E4E002DA685 /* MainAppContext.swift */; };
FDE658A129418C7900A33BC1 /* CryptoKit+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDE658A029418C7900A33BC1 /* CryptoKit+Utilities.swift */; };
FDE658A329418E2F00A33BC1 /* KeyPair.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDE658A229418E2F00A33BC1 /* KeyPair.swift */; };
FDE6E99829F8E63A00F93C5D /* Accessibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDE6E99729F8E63A00F93C5D /* Accessibility.swift */; };
@ -1129,8 +1115,6 @@
3496955F21A2FC8100DCFE74 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; };
34A6C27F21E503E600B5B12E /* OWSImagePickerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSImagePickerController.swift; sourceTree = "<group>"; };
34A8B3502190A40E00218A25 /* MediaAlbumView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaAlbumView.swift; sourceTree = "<group>"; };
34B0796B1FCF46B000E248C2 /* MainAppContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainAppContext.m; sourceTree = "<group>"; };
34B0796C1FCF46B000E248C2 /* MainAppContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainAppContext.h; sourceTree = "<group>"; };
34B0796E1FD07B1E00E248C2 /* SignalShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SignalShareExtension.entitlements; sourceTree = "<group>"; };
34B6A902218B3F62007C4606 /* TypingIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypingIndicatorView.swift; sourceTree = "<group>"; };
34BECE2D1F7ABCE000D7438D /* GifPickerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GifPickerViewController.swift; sourceTree = "<group>"; };
@ -1433,9 +1417,7 @@
C33FDA8E255A57FD00E217F9 /* OWSFileSystem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSFileSystem.m; sourceTree = "<group>"; };
C33FDA9E255A57FF00E217F9 /* ReverseDispatchQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReverseDispatchQueue.swift; sourceTree = "<group>"; };
C33FDAA8255A57FF00E217F9 /* BuildConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BuildConfiguration.swift; sourceTree = "<group>"; };
C33FDABE255A580100E217F9 /* TSConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSConstants.m; sourceTree = "<group>"; };
C33FDADE255A580400E217F9 /* SwiftSingletons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftSingletons.swift; sourceTree = "<group>"; };
C33FDAE0255A580400E217F9 /* ByteParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ByteParser.m; sourceTree = "<group>"; };
C33FDAEF255A580500E217F9 /* NSData+Image.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Image.m"; sourceTree = "<group>"; };
C33FDAF1255A580500E217F9 /* ThumbnailService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThumbnailService.swift; sourceTree = "<group>"; };
C33FDAF2255A580500E217F9 /* ProxiedContentDownloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProxiedContentDownloader.swift; sourceTree = "<group>"; };
@ -1443,7 +1425,6 @@
C33FDAFD255A580600E217F9 /* LRUCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LRUCache.swift; sourceTree = "<group>"; };
C33FDB01255A580700E217F9 /* AppReadiness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppReadiness.h; sourceTree = "<group>"; };
C33FDB14255A580800E217F9 /* OWSMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMath.h; sourceTree = "<group>"; };
C33FDB17255A580800E217F9 /* FunctionalUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FunctionalUtil.m; sourceTree = "<group>"; };
C33FDB1C255A580900E217F9 /* UIImage+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+OWS.h"; sourceTree = "<group>"; };
C33FDB22255A580900E217F9 /* OWSMediaUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSMediaUtils.swift; sourceTree = "<group>"; };
C33FDB29255A580A00E217F9 /* NSData+Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Image.h"; sourceTree = "<group>"; };
@ -1451,7 +1432,6 @@
C33FDB38255A580B00E217F9 /* OWSBackgroundTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackgroundTask.h; sourceTree = "<group>"; };
C33FDB3A255A580B00E217F9 /* Poller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Poller.swift; sourceTree = "<group>"; };
C33FDB3F255A580C00E217F9 /* String+SSK.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+SSK.swift"; sourceTree = "<group>"; };
C33FDB40255A580C00E217F9 /* SignalIOSProto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalIOSProto.swift; sourceTree = "<group>"; };
C33FDB41255A580C00E217F9 /* MIMETypeUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MIMETypeUtil.m; sourceTree = "<group>"; };
C33FDB49255A580C00E217F9 /* WeakTimer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeakTimer.swift; sourceTree = "<group>"; };
C33FDB4C255A580D00E217F9 /* AppVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppVersion.h; sourceTree = "<group>"; };
@ -1462,27 +1442,17 @@
C33FDB6B255A580F00E217F9 /* SNUserDefaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SNUserDefaults.swift; sourceTree = "<group>"; };
C33FDB75255A581000E217F9 /* AppReadiness.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppReadiness.m; sourceTree = "<group>"; };
C33FDB77255A581000E217F9 /* NSUserDefaults+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSUserDefaults+OWS.m"; sourceTree = "<group>"; };
C33FDB78255A581000E217F9 /* OWSOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSOperation.m; sourceTree = "<group>"; };
C33FDB80255A581100E217F9 /* Notification+Loki.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Notification+Loki.swift"; sourceTree = "<group>"; };
C33FDB81255A581100E217F9 /* UIImage+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+OWS.m"; sourceTree = "<group>"; };
C33FDB85255A581100E217F9 /* AppContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppContext.m; sourceTree = "<group>"; };
C33FDB8A255A581200E217F9 /* AppContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppContext.h; sourceTree = "<group>"; };
C33FDB8F255A581200E217F9 /* ParamParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParamParser.swift; sourceTree = "<group>"; };
C33FDBA1255A581400E217F9 /* OWSOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSOperation.h; sourceTree = "<group>"; };
C33FDBA8255A581500E217F9 /* LinkPreviewDraft.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LinkPreviewDraft.swift; sourceTree = "<group>"; };
C33FDBAB255A581500E217F9 /* OWSFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSFileSystem.h; sourceTree = "<group>"; };
C33FDBB4255A581600E217F9 /* NSURLSessionDataTask+StatusCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLSessionDataTask+StatusCode.m"; sourceTree = "<group>"; };
C33FDBB6255A581600E217F9 /* DataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataSource.m; sourceTree = "<group>"; };
C33FDBBC255A581600E217F9 /* SSKKeychainStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SSKKeychainStorage.swift; sourceTree = "<group>"; };
C33FDBD3255A581800E217F9 /* OWSSignalAddress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSSignalAddress.swift; sourceTree = "<group>"; };
C33FDBD8255A581900E217F9 /* SignalIOS.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalIOS.pb.swift; sourceTree = "<group>"; };
C33FDBDE255A581900E217F9 /* PushNotificationAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PushNotificationAPI.swift; sourceTree = "<group>"; };
C33FDBF6255A581C00E217F9 /* NSURLSessionDataTask+StatusCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLSessionDataTask+StatusCode.h"; sourceTree = "<group>"; };
C33FDBF9255A581C00E217F9 /* OWSError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSError.h; sourceTree = "<group>"; };
C33FDC03255A581D00E217F9 /* ByteParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByteParser.h; sourceTree = "<group>"; };
C33FDC0B255A581D00E217F9 /* OWSError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSError.m; sourceTree = "<group>"; };
C33FDC12255A581E00E217F9 /* TSConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSConstants.h; sourceTree = "<group>"; };
C33FDC16255A581E00E217F9 /* FunctionalUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionalUtil.h; sourceTree = "<group>"; };
C33FDC1B255A581F00E217F9 /* OWSBackgroundTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackgroundTask.m; sourceTree = "<group>"; };
C3471ECA2555356A00297E91 /* MessageSender+Encryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageSender+Encryption.swift"; sourceTree = "<group>"; };
C3471F4B25553AB000297E91 /* MessageReceiver+Decryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageReceiver+Decryption.swift"; sourceTree = "<group>"; };
@ -1962,6 +1932,7 @@
FDDCBDA729E776BF00303C38 /* seed3-2023-2y.der */ = {isa = PBXFileReference; lastKnownFileType = file; path = "seed3-2023-2y.der"; sourceTree = "<group>"; };
FDDF074329C3E3D000E5E8B5 /* FetchRequest+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FetchRequest+Utilities.swift"; sourceTree = "<group>"; };
FDDF074929DAB36900E5E8B5 /* JobRunnerSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JobRunnerSpec.swift; sourceTree = "<group>"; };
FDE125222A837E4E002DA685 /* MainAppContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainAppContext.swift; sourceTree = "<group>"; };
FDE658A029418C7900A33BC1 /* CryptoKit+Utilities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CryptoKit+Utilities.swift"; sourceTree = "<group>"; };
FDE658A229418E2F00A33BC1 /* KeyPair.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyPair.swift; sourceTree = "<group>"; };
FDE6E99729F8E63A00F93C5D /* Accessibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Accessibility.swift; sourceTree = "<group>"; };
@ -2052,7 +2023,6 @@
FDFBB74A2A1EFF4900CA7350 /* Bencode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bencode.swift; sourceTree = "<group>"; };
FDFBB74C2A1F3C4E00CA7350 /* NotificationMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationMetadata.swift; sourceTree = "<group>"; };
FDFBB7532A2023EB00CA7350 /* BencodeSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BencodeSpec.swift; sourceTree = "<group>"; };
FDFC4E1829F1F9A600992FB6 /* libsession-util.xcframework */ = {isa = PBXFileReference; explicitFileType = wrapper.xcframework; includeInIndex = 0; path = "libsession-util.xcframework"; sourceTree = BUILD_DIR; };
FDFD645A27F26D4600808CA1 /* Data+Utilities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Data+Utilities.swift"; sourceTree = "<group>"; };
FDFD645C27F273F300808CA1 /* MockGeneralCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockGeneralCache.swift; sourceTree = "<group>"; };
FDFDE123282D04F20098B17F /* MediaDismissAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaDismissAnimationController.swift; sourceTree = "<group>"; };
@ -3400,34 +3370,20 @@
FD71161D28D9772700B47552 /* UIViewController+OWS.swift */,
C38EF2B1255B6D9C007E1867 /* UIViewController+Utilities.swift */,
C38EF307255B6DBE007E1867 /* UIGestureRecognizer+OWS.swift */,
C33FDBF9255A581C00E217F9 /* OWSError.h */,
C33FDC0B255A581D00E217F9 /* OWSError.m */,
C33FDBA1255A581400E217F9 /* OWSOperation.h */,
C33FDB78255A581000E217F9 /* OWSOperation.m */,
C33FDBD3255A581800E217F9 /* OWSSignalAddress.swift */,
C33FDA6F255A57FA00E217F9 /* ReachabilityManager.swift */,
C33FDBD8255A581900E217F9 /* SignalIOS.pb.swift */,
C33FDB40255A580C00E217F9 /* SignalIOSProto.swift */,
C33FDC12255A581E00E217F9 /* TSConstants.h */,
C33FDABE255A580100E217F9 /* TSConstants.m */,
C33FDB4C255A580D00E217F9 /* AppVersion.h */,
C33FDA8B255A57FD00E217F9 /* AppVersion.m */,
C38EF3E4255B6DF4007E1867 /* CommonStrings.swift */,
C38EF304255B6DBE007E1867 /* ImageCache.swift */,
C38EF2F2255B6DBC007E1867 /* Searcher.swift */,
C3F0A52F255C80BC007BE2A3 /* NoopNotificationsManager.swift */,
C33FDA8B255A57FD00E217F9 /* AppVersion.m */,
C33FDB69255A580F00E217F9 /* FeatureFlags.swift */,
C33FDB80255A581100E217F9 /* Notification+Loki.swift */,
C33FDC16255A581E00E217F9 /* FunctionalUtil.h */,
C33FDB17255A580800E217F9 /* FunctionalUtil.m */,
C33FDB8F255A581200E217F9 /* ParamParser.swift */,
C33FDADE255A580400E217F9 /* SwiftSingletons.swift */,
C33FDB49255A580C00E217F9 /* WeakTimer.swift */,
C33FDA9E255A57FF00E217F9 /* ReverseDispatchQueue.swift */,
C33FDBF6255A581C00E217F9 /* NSURLSessionDataTask+StatusCode.h */,
C33FDBB4255A581600E217F9 /* NSURLSessionDataTask+StatusCode.m */,
C33FDC03255A581D00E217F9 /* ByteParser.h */,
C33FDAE0255A580400E217F9 /* ByteParser.m */,
C38EF3DD255B6DF1007E1867 /* UIAlertController+OWS.swift */,
C38EF241255B6D67007E1867 /* Collection+OWS.swift */,
C38EF3AE255B6DE5007E1867 /* OrderedDictionary.swift */,
@ -3457,8 +3413,7 @@
34330A581E7875FB00DF2FB9 /* Fonts */,
B66DBF4919D5BBC8006EA940 /* Images.xcassets */,
45CB2FA71CB7146C00E1B343 /* Launch Screen.storyboard */,
34B0796C1FCF46B000E248C2 /* MainAppContext.h */,
34B0796B1FCF46B000E248C2 /* MainAppContext.m */,
FDE125222A837E4E002DA685 /* MainAppContext.swift */,
C3CA3AA0255CDA7000F4C6D4 /* Mnemonic */,
B67EBF5C19194AC60084CCFD /* Settings.bundle */,
B657DDC91911A40500F45B0C /* Signal.entitlements */,
@ -4495,12 +4450,6 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
C33FDDB0255A582000E217F9 /* NSURLSessionDataTask+StatusCode.h in Headers */,
C33FDDD0255A582000E217F9 /* FunctionalUtil.h in Headers */,
C33FDD5B255A582000E217F9 /* OWSOperation.h in Headers */,
C33FDDCC255A582000E217F9 /* TSConstants.h in Headers */,
C33FDDBD255A582000E217F9 /* ByteParser.h in Headers */,
C33FDDB3255A582000E217F9 /* OWSError.h in Headers */,
C38EF35E255B6DCC007E1867 /* OWSViewController.h in Headers */,
C33FD9AF255A548A00E217F9 /* SignalUtilitiesKit.h in Headers */,
C33FDD06255A582000E217F9 /* AppVersion.h in Headers */,
@ -4801,6 +4750,7 @@
D221A080169C9E5E00537ABF /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
DefaultBuildSystemTypeForWorkspace = Original;
LastSwiftUpdateCheck = 1430;
LastTestingUpgradeCheck = 0600;
@ -5562,10 +5512,8 @@
C38EF30C255B6DBF007E1867 /* ScreenLock.swift in Sources */,
C38EF363255B6DCC007E1867 /* ModalActivityIndicatorViewController.swift in Sources */,
C38EF38A255B6DD2007E1867 /* AttachmentCaptionToolbar.swift in Sources */,
C33FDCD1255A582000E217F9 /* FunctionalUtil.m in Sources */,
C38EF402255B6DF7007E1867 /* CommonStrings.swift in Sources */,
C38EF3C1255B6DE7007E1867 /* ImageEditorBrushViewController.swift in Sources */,
C33FDD32255A582000E217F9 /* OWSOperation.m in Sources */,
C3F0A530255C80BC007BE2A3 /* NoopNotificationsManager.swift in Sources */,
C33FDD8D255A582000E217F9 /* OWSSignalAddress.swift in Sources */,
C38EF388255B6DD2007E1867 /* AttachmentApprovalViewController.swift in Sources */,
@ -5573,7 +5521,6 @@
C33FDC29255A581F00E217F9 /* ReachabilityManager.swift in Sources */,
C38EF407255B6DF7007E1867 /* Toast.swift in Sources */,
C38EF38C255B6DD2007E1867 /* ApprovalRailCellView.swift in Sources */,
C33FDD92255A582000E217F9 /* SignalIOS.pb.swift in Sources */,
C33FDC45255A581F00E217F9 /* AppVersion.m in Sources */,
C38EF3C7255B6DE7007E1867 /* ImageEditorCanvasView.swift in Sources */,
C38EF400255B6DF7007E1867 /* GalleryRailView.swift in Sources */,
@ -5582,7 +5529,6 @@
C38EF3BA255B6DE7007E1867 /* ImageEditorItem.swift in Sources */,
C33FDD3A255A582000E217F9 /* Notification+Loki.swift in Sources */,
C38EF24E255B6D67007E1867 /* Collection+OWS.swift in Sources */,
C33FDCFA255A582000E217F9 /* SignalIOSProto.swift in Sources */,
C38EF24D255B6D67007E1867 /* UIView+OWS.swift in Sources */,
C38EF38B255B6DD2007E1867 /* AttachmentPrepViewController.swift in Sources */,
C38EF405255B6DF7007E1867 /* OWSButton.swift in Sources */,
@ -5598,9 +5544,7 @@
FD52090B28B59BB4006098F6 /* ScreenLockViewController.swift in Sources */,
C38EF401255B6DF7007E1867 /* VideoPlayerView.swift in Sources */,
C38EF3BD255B6DE7007E1867 /* ImageEditorTransform.swift in Sources */,
C33FDC9A255A582000E217F9 /* ByteParser.m in Sources */,
C33FDC58255A582000E217F9 /* ReverseDispatchQueue.swift in Sources */,
C33FDC78255A582000E217F9 /* TSConstants.m in Sources */,
C38EF324255B6DBF007E1867 /* Bench.swift in Sources */,
FDCDB8DE2810F73B00352A0C /* Differentiable+Utilities.swift in Sources */,
C38EF3F9255B6DF7007E1867 /* OWSLayerView.swift in Sources */,
@ -5612,12 +5556,10 @@
C38EF386255B6DD2007E1867 /* AttachmentApprovalInputAccessoryView.swift in Sources */,
B8C2B2C82563685C00551B4D /* CircleView.swift in Sources */,
C38EF331255B6DBF007E1867 /* UIGestureRecognizer+OWS.swift in Sources */,
C33FDDC5255A582000E217F9 /* OWSError.m in Sources */,
FD848B9C284435D7000E298B /* AppSetup.swift in Sources */,
C38EF31C255B6DBF007E1867 /* Searcher.swift in Sources */,
C38EF2B3255B6D9C007E1867 /* UIViewController+Utilities.swift in Sources */,
C38EF3BE255B6DE7007E1867 /* OrderedDictionary.swift in Sources */,
C33FDD6E255A582000E217F9 /* NSURLSessionDataTask+StatusCode.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -6059,10 +6001,10 @@
B83F2B88240CB75A000A54AB /* UIImage+Scaling.swift in Sources */,
3430FE181F7751D4000EC51B /* GiphyAPI.swift in Sources */,
4C090A1B210FD9C7001FD7F9 /* HapticFeedback.swift in Sources */,
FDE125232A837E4E002DA685 /* MainAppContext.swift in Sources */,
7B9F71D12852EEE2006DFE7B /* EmojiWithSkinTones+String.swift in Sources */,
34F308A21ECB469700BB7697 /* OWSBezierPathView.m in Sources */,
B886B4A92398BA1500211ABE /* QRCode.swift in Sources */,
34B0796D1FCF46B100E248C2 /* MainAppContext.m in Sources */,
34A8B3512190A40E00218A25 /* MediaAlbumView.swift in Sources */,
FD09C5E828264937000CE219 /* MediaDetailViewController.swift in Sources */,
3496955E219B605E00DCFE74 /* PhotoLibrary.swift in Sources */,
@ -6491,7 +6433,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 421;
CURRENT_PROJECT_VERSION = 422;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
@ -6515,7 +6457,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.3.2;
MARKETING_VERSION = 2.4.0;
MTL_ENABLE_DEBUG_INFO = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -6563,7 +6505,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 421;
CURRENT_PROJECT_VERSION = 422;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = SUQ8J2PCT7;
ENABLE_NS_ASSERTIONS = NO;
@ -6592,7 +6534,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.3.2;
MARKETING_VERSION = 2.4.0;
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -6628,7 +6570,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 421;
CURRENT_PROJECT_VERSION = 422;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
@ -6651,7 +6593,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.3.2;
MARKETING_VERSION = 2.4.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension";
@ -6702,7 +6644,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 421;
CURRENT_PROJECT_VERSION = 422;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = SUQ8J2PCT7;
ENABLE_NS_ASSERTIONS = NO;
@ -6730,7 +6672,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.3.2;
MARKETING_VERSION = 2.4.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension";
@ -7662,7 +7604,7 @@
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 421;
CURRENT_PROJECT_VERSION = 422;
DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@ -7700,7 +7642,7 @@
"$(SRCROOT)",
);
LLVM_LTO = NO;
MARKETING_VERSION = 2.3.2;
MARKETING_VERSION = 2.4.0;
OTHER_LDFLAGS = "$(inherited)";
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger";
@ -7733,7 +7675,7 @@
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 421;
CURRENT_PROJECT_VERSION = 422;
DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@ -7771,7 +7713,7 @@
"$(SRCROOT)",
);
LLVM_LTO = NO;
MARKETING_VERSION = 2.3.2;
MARKETING_VERSION = 2.4.0;
OTHER_LDFLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger";
PRODUCT_NAME = Session;

View File

@ -9,6 +9,8 @@ import WebRTC
import SessionUIKit
import SignalUtilitiesKit
import SessionMessagingKit
import SessionUtilitiesKit
import SessionSnodeKit
public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
@objc static let isEnabled = true

View File

@ -2,6 +2,7 @@
import UIKit
import GRDB
import SessionUtilitiesKit
extension SessionCallManager {
@discardableResult

View File

@ -6,6 +6,7 @@ import GRDB
import SessionMessagingKit
import SignalCoreKit
import SignalUtilitiesKit
import SessionUtilitiesKit
public final class SessionCallManager: NSObject, CallManagerProtocol {
let provider: CXProvider?

View File

@ -4,6 +4,7 @@ import UIKit
import SessionUIKit
import SessionMessagingKit
import SignalUtilitiesKit
import SessionUtilitiesKit
final class IncomingCallBanner: UIView, UIGestureRecognizerDelegate {
private static let swipeToOperateThreshold: CGFloat = 60

View File

@ -3,6 +3,7 @@
import UIKit
import WebRTC
import SessionUIKit
import SessionUtilitiesKit
final class MiniCallView: UIView, RTCVideoViewDelegate {
var callVC: CallVC

View File

@ -7,6 +7,7 @@ import DifferenceKit
import SessionUIKit
import SessionMessagingKit
import SignalUtilitiesKit
import SessionUtilitiesKit
final class EditClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegate {
private struct GroupMemberDisplayInfo: FetchableRecord, Equatable, Hashable, Decodable, Differentiable {

View File

@ -2,6 +2,7 @@
import UIKit
import SessionMessagingKit
import SessionUtilitiesKit
extension ContextMenuVC {
struct Action {

View File

@ -5,6 +5,7 @@ import GRDB
import SignalUtilitiesKit
import SignalCoreKit
import SessionUIKit
import SessionUtilitiesKit
public class StyledSearchController: UISearchController {
public override var preferredStatusBarStyle: UIStatusBarStyle {

View File

@ -11,6 +11,7 @@ import SessionUIKit
import SessionMessagingKit
import SessionUtilitiesKit
import SignalUtilitiesKit
import SessionSnodeKit
extension ConversationVC:
InputViewDelegate,

View File

@ -2,6 +2,7 @@
import UIKit
import SessionUIKit
import SessionUtilitiesKit
final class InputViewButton: UIView {
private let icon: UIImage?

View File

@ -3,6 +3,7 @@
import UIKit
import SessionUIKit
import SessionMessagingKit
import SessionUtilitiesKit
final class CallMessageCell: MessageCell {
private static let iconSize: CGFloat = 16

View File

@ -3,6 +3,7 @@
import UIKit
import SessionMessagingKit
import SignalCoreKit
import SessionUtilitiesKit
public class MediaAlbumView: UIStackView {
private let items: [Attachment]

View File

@ -6,6 +6,7 @@ import SessionUIKit
import SessionMessagingKit
import SignalCoreKit
import SignalUtilitiesKit
import SessionUtilitiesKit
public class MediaView: UIView {
static let contentMode: UIView.ContentMode = .scaleAspectFill

View File

@ -3,6 +3,7 @@
import UIKit
import SessionUIKit
import SignalCoreKit
import SessionUtilitiesKit
@objc class TypingIndicatorView: UIStackView {
// This represents the spacing between the dots

View File

@ -2,6 +2,7 @@
import UIKit
import SessionMessagingKit
import SessionUtilitiesKit
public enum SwipeState {
case began

View File

@ -9,6 +9,7 @@ import SessionUIKit
import SessionMessagingKit
import SignalUtilitiesKit
import SessionUtilitiesKit
import SessionSnodeKit
class ThreadSettingsViewModel: SessionTableViewModel<ThreadSettingsViewModel.NavButton, ThreadSettingsViewModel.Section, ThreadSettingsViewModel.Setting> {
// MARK: - Config

View File

@ -5,6 +5,7 @@ import DifferenceKit
import SessionUIKit
import SessionMessagingKit
import SignalUtilitiesKit
import SessionUtilitiesKit
final class ReactionListSheet: BaseVC {
public struct ReactionSummary: Hashable, Differentiable {

View File

@ -1,5 +1,6 @@
import Foundation
import SignalCoreKit
import SessionUtilitiesKit
extension Emoji {
private static let availableCache: Atomic<[Emoji:Bool]> = Atomic([:])

View File

@ -6,6 +6,7 @@ import DifferenceKit
import SessionUIKit
import SessionMessagingKit
import SignalUtilitiesKit
import SessionUtilitiesKit
class MessageRequestsViewController: BaseVC, SessionUtilRespondingViewController, UITableViewDelegate, UITableViewDataSource {
private static let loadingHeaderHeight: CGFloat = 40

View File

@ -4,6 +4,7 @@ import Foundation
import GRDB
import DifferenceKit
import SignalUtilitiesKit
import SessionUtilitiesKit
public class MessageRequestsViewModel {
public typealias SectionModel = ArraySection<Section, SessionThreadViewModel>

View File

@ -7,6 +7,7 @@ import SessionUIKit
import SessionMessagingKit
import SessionUtilitiesKit
import SignalUtilitiesKit
import SessionSnodeKit
final class NewDMVC: BaseVC, UIPageViewControllerDataSource, UIPageViewControllerDelegate, QRScannerDelegate {
private var shouldShowBackButton: Bool = true

View File

@ -5,6 +5,7 @@ import MediaPlayer
import SessionUIKit
import SignalUtilitiesKit
import SignalCoreKit
import SessionUtilitiesKit
// This kind of view is tricky. I've tried to organize things in the
// simplest possible way.
@ -359,54 +360,54 @@ import SignalCoreKit
@objc func handlePinch(sender: UIPinchGestureRecognizer) {
switch sender.state {
case .possible:
break
case .began:
srcTranslationAtPinchStart = srcTranslation
imageScaleAtPinchStart = imageScale
case .possible: break
case .began:
srcTranslationAtPinchStart = srcTranslation
imageScaleAtPinchStart = imageScale
lastPinchLocation =
sender.location(in: sender.view)
lastPinchScale = sender.scale
break
case .changed, .ended:
if sender.numberOfTouches > 1 {
let location =
lastPinchLocation =
sender.location(in: sender.view)
let scaleDiff = sender.scale / lastPinchScale
// Update scaling.
let srcCropSizeBeforeScalePoints = CGSize(width: srcDefaultCropSizePoints.width / imageScale,
height: srcDefaultCropSizePoints.height / imageScale)
imageScale = max(kMinImageScale, min(kMaxImageScale, imageScale * scaleDiff))
let srcCropSizeAfterScalePoints = CGSize(width: srcDefaultCropSizePoints.width / imageScale,
height: srcDefaultCropSizePoints.height / imageScale)
// Since the translation state reflects the "upper left" corner of the crop region, we need to
// adjust the translation when scaling to preserve the "center" of the crop region.
srcTranslation.x += (srcCropSizeBeforeScalePoints.width - srcCropSizeAfterScalePoints.width) * 0.5
srcTranslation.y += (srcCropSizeBeforeScalePoints.height - srcCropSizeAfterScalePoints.height) * 0.5
// Update translation.
let viewSizePoints = imageView.frame.size
let srcCropSizePoints = CGSize(width: srcDefaultCropSizePoints.width / imageScale,
height: srcDefaultCropSizePoints.height / imageScale)
let viewToSrcRatio = srcCropSizePoints.width / viewSizePoints.width
let gestureTranslation = CGPoint(x: location.x - lastPinchLocation.x,
y: location.y - lastPinchLocation.y)
srcTranslation = CGPoint(x: srcTranslation.x + gestureTranslation.x * -viewToSrcRatio,
y: srcTranslation.y + gestureTranslation.y * -viewToSrcRatio)
lastPinchLocation = location
lastPinchScale = sender.scale
}
break
case .cancelled, .failed:
srcTranslation = srcTranslationAtPinchStart
imageScale = imageScaleAtPinchStart
break
case .changed, .ended:
if sender.numberOfTouches > 1 {
let location =
sender.location(in: sender.view)
let scaleDiff = sender.scale / lastPinchScale
// Update scaling.
let srcCropSizeBeforeScalePoints = CGSize(width: srcDefaultCropSizePoints.width / imageScale,
height: srcDefaultCropSizePoints.height / imageScale)
imageScale = max(kMinImageScale, min(kMaxImageScale, imageScale * scaleDiff))
let srcCropSizeAfterScalePoints = CGSize(width: srcDefaultCropSizePoints.width / imageScale,
height: srcDefaultCropSizePoints.height / imageScale)
// Since the translation state reflects the "upper left" corner of the crop region, we need to
// adjust the translation when scaling to preserve the "center" of the crop region.
srcTranslation.x += (srcCropSizeBeforeScalePoints.width - srcCropSizeAfterScalePoints.width) * 0.5
srcTranslation.y += (srcCropSizeBeforeScalePoints.height - srcCropSizeAfterScalePoints.height) * 0.5
// Update translation.
let viewSizePoints = imageView.frame.size
let srcCropSizePoints = CGSize(width: srcDefaultCropSizePoints.width / imageScale,
height: srcDefaultCropSizePoints.height / imageScale)
let viewToSrcRatio = srcCropSizePoints.width / viewSizePoints.width
let gestureTranslation = CGPoint(x: location.x - lastPinchLocation.x,
y: location.y - lastPinchLocation.y)
srcTranslation = CGPoint(x: srcTranslation.x + gestureTranslation.x * -viewToSrcRatio,
y: srcTranslation.y + gestureTranslation.y * -viewToSrcRatio)
lastPinchLocation = location
lastPinchScale = sender.scale
}
case .cancelled, .failed:
srcTranslation = srcTranslationAtPinchStart
imageScale = imageScaleAtPinchStart
@unknown default: break
}
updateImageLayout()
@ -416,29 +417,28 @@ import SignalCoreKit
@objc func handlePan(sender: UIPanGestureRecognizer) {
switch sender.state {
case .possible:
break
case .began:
srcTranslationAtPanStart = srcTranslation
break
case .changed, .ended:
let viewSizePoints = imageView.frame.size
let srcCropSizePoints = CGSize(width: srcDefaultCropSizePoints.width / imageScale,
height: srcDefaultCropSizePoints.height / imageScale)
case .possible: break
case .began:
srcTranslationAtPanStart = srcTranslation
case .changed, .ended:
let viewSizePoints = imageView.frame.size
let srcCropSizePoints = CGSize(width: srcDefaultCropSizePoints.width / imageScale,
height: srcDefaultCropSizePoints.height / imageScale)
let viewToSrcRatio = srcCropSizePoints.width / viewSizePoints.width
let viewToSrcRatio = srcCropSizePoints.width / viewSizePoints.width
let gestureTranslation =
sender.translation(in: sender.view)
let gestureTranslation =
sender.translation(in: sender.view)
// Update translation.
srcTranslation = CGPoint(x: srcTranslationAtPanStart.x + gestureTranslation.x * -viewToSrcRatio,
y: srcTranslationAtPanStart.y + gestureTranslation.y * -viewToSrcRatio)
break
case .cancelled, .failed:
srcTranslation
= srcTranslationAtPanStart
break
// Update translation.
srcTranslation = CGPoint(x: srcTranslationAtPanStart.x + gestureTranslation.x * -viewToSrcRatio,
y: srcTranslationAtPanStart.y + gestureTranslation.y * -viewToSrcRatio)
case .cancelled, .failed:
srcTranslation = srcTranslationAtPanStart
@unknown default: break
}
updateImageLayout()

View File

@ -7,6 +7,7 @@ import DifferenceKit
import SessionUIKit
import SignalUtilitiesKit
import SignalCoreKit
import SessionUtilitiesKit
public class DocumentTileViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

View File

@ -5,6 +5,7 @@ import Combine
import YYImage
import SignalUtilitiesKit
import SignalCoreKit
import SessionUtilitiesKit
class GifPickerCell: UICollectionViewCell {

View File

@ -6,6 +6,7 @@ import Reachability
import SignalUtilitiesKit
import SessionUIKit
import SignalCoreKit
import SessionUtilitiesKit
class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollectionViewDataSource, UICollectionViewDelegate, GifPickerLayoutDelegate {

View File

@ -2,6 +2,7 @@
import Foundation
import SignalUtilitiesKit
import SessionUtilitiesKit
public class GiphyDownloader: ProxiedContentDownloader {

View File

@ -6,6 +6,7 @@ import Photos
import SessionUIKit
import SignalUtilitiesKit
import SignalCoreKit
import SessionUtilitiesKit
protocol ImagePickerGridControllerDelegate: AnyObject {
func imagePickerDidCompleteSelection(_ imagePicker: ImagePickerGridController)
@ -155,6 +156,8 @@ class ImagePickerGridController: UICollectionViewController, PhotoLibraryDelegat
case .cancelled, .ended, .failed:
collectionView.isUserInteractionEnabled = true
collectionView.isScrollEnabled = true
@unknown default: break
}
}

View File

@ -6,6 +6,7 @@ import SessionUIKit
import SignalUtilitiesKit
import SessionMessagingKit
import SignalCoreKit
import SessionUtilitiesKit
public enum MediaGalleryOption {
case sliderEnabled

View File

@ -6,6 +6,8 @@ import SessionUIKit
import SessionMessagingKit
import SignalUtilitiesKit
import SignalCoreKit
import SessionUtilitiesKit
import SessionSnodeKit
class MediaPageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate, MediaDetailViewControllerDelegate, InteractivelyDismissableViewController {
class DynamicallySizedView: UIView {

View File

@ -7,6 +7,7 @@ import DifferenceKit
import SessionUIKit
import SignalUtilitiesKit
import SignalCoreKit
import SessionUtilitiesKit
public class MediaTileViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

View File

@ -6,6 +6,7 @@ import AVFoundation
import SessionUIKit
import SignalUtilitiesKit
import SignalCoreKit
import SessionUtilitiesKit
protocol PhotoCaptureViewControllerDelegate: AnyObject {
func photoCaptureViewController(_ photoCaptureViewController: PhotoCaptureViewController, didFinishProcessingAttachment attachment: SignalAttachment)

View File

@ -6,6 +6,7 @@ import Photos
import CoreServices
import SignalUtilitiesKit
import SignalCoreKit
import SessionUtilitiesKit
protocol PhotoLibraryDelegate: AnyObject {
func photoLibraryDidChange(_ photoLibrary: PhotoLibrary)

View File

@ -6,6 +6,7 @@ import Photos
import SignalUtilitiesKit
import SignalCoreKit
import SessionUIKit
import SessionUtilitiesKit
class SendMediaNavigationController: UINavigationController {
public override var preferredStatusBarStyle: UIStatusBarStyle {
@ -539,8 +540,8 @@ private struct MediaLibrarySelection: Hashable, Equatable {
let asset: PHAsset
let signalAttachmentPublisher: AnyPublisher<SignalAttachment, Error>
var hashValue: Int {
return asset.hashValue
func hash(into hasher: inout Hasher) {
asset.hash(into: &hasher)
}
var publisher: AnyPublisher<MediaLibraryAttachment, Error> {
@ -559,8 +560,8 @@ private struct MediaLibraryAttachment: Hashable, Equatable {
let asset: PHAsset
let signalAttachment: SignalAttachment
public var hashValue: Int {
return asset.hashValue
func hash(into hasher: inout Hasher) {
asset.hash(into: &hasher)
}
public static func == (lhs: MediaLibraryAttachment, rhs: MediaLibraryAttachment) -> Bool {

View File

@ -9,6 +9,7 @@ import SessionMessagingKit
import SessionUtilitiesKit
import SignalUtilitiesKit
import SignalCoreKit
import SessionSnodeKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

View File

@ -4,6 +4,7 @@ import Foundation
import SessionUtilitiesKit
import SignalUtilitiesKit
import SignalCoreKit
import SessionMessagingKit
public class AppEnvironment {

View File

@ -1,17 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import <SessionUtilitiesKit/AppContext.h>
NS_ASSUME_NONNULL_BEGIN
extern NSString *const ReportedApplicationStateDidChangeNotification;
@interface MainAppContext : NSObject <AppContext>
- (instancetype)init;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,314 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import "MainAppContext.h"
#import "Session-Swift.h"
#import <SignalCoreKit/OWSAsserts.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN
NSString *const ReportedApplicationStateDidChangeNotification = @"ReportedApplicationStateDidChangeNotification";
@interface MainAppContext ()
@property (atomic) UIApplicationState reportedApplicationState;
@property (nonatomic, nullable) NSMutableArray<AppActiveBlock> *appActiveBlocks;
@end
#pragma mark -
@implementation MainAppContext
@synthesize mainWindow = _mainWindow;
@synthesize appLaunchTime = _appLaunchTime;
@synthesize wasWokenUpByPushNotification = _wasWokenUpByPushNotification;
- (instancetype)init
{
self = [super init];
if (!self) {
return self;
}
self.reportedApplicationState = UIApplicationStateInactive;
_appLaunchTime = [NSDate new];
_wasWokenUpByPushNotification = false;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillEnterForeground:)
name:UIApplicationWillEnterForegroundNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillResignActive:)
name:UIApplicationWillResignActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidBecomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillTerminate:)
name:UIApplicationWillTerminateNotification
object:nil];
self.appActiveBlocks = [NSMutableArray new];
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark - Notifications
- (void)setReportedApplicationState:(UIApplicationState)reportedApplicationState
{
OWSAssertIsOnMainThread();
if (_reportedApplicationState == reportedApplicationState) {
return;
}
_reportedApplicationState = reportedApplicationState;
[[NSNotificationCenter defaultCenter] postNotificationName:ReportedApplicationStateDidChangeNotification
object:nil
userInfo:nil];
}
- (void)applicationWillEnterForeground:(NSNotification *)notification
{
OWSAssertIsOnMainThread();
self.reportedApplicationState = UIApplicationStateInactive;
OWSLogInfo(@"");
[NSNotificationCenter.defaultCenter postNotificationName:OWSApplicationWillEnterForegroundNotification object:nil];
}
- (void)applicationDidEnterBackground:(NSNotification *)notification
{
OWSAssertIsOnMainThread();
self.reportedApplicationState = UIApplicationStateBackground;
OWSLogInfo(@"");
[DDLog flushLog];
[NSNotificationCenter.defaultCenter postNotificationName:OWSApplicationDidEnterBackgroundNotification object:nil];
}
- (void)applicationWillResignActive:(NSNotification *)notification
{
OWSAssertIsOnMainThread();
self.reportedApplicationState = UIApplicationStateInactive;
OWSLogInfo(@"");
[DDLog flushLog];
[NSNotificationCenter.defaultCenter postNotificationName:OWSApplicationWillResignActiveNotification object:nil];
}
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
OWSAssertIsOnMainThread();
self.reportedApplicationState = UIApplicationStateActive;
OWSLogInfo(@"");
[NSNotificationCenter.defaultCenter postNotificationName:OWSApplicationDidBecomeActiveNotification object:nil];
[self runAppActiveBlocks];
}
- (void)applicationWillTerminate:(NSNotification *)notification
{
OWSAssertIsOnMainThread();
OWSLogInfo(@"");
[DDLog flushLog];
}
#pragma mark -
- (BOOL)isMainApp
{
return YES;
}
- (BOOL)isMainAppAndActive
{
return [UIApplication sharedApplication].applicationState == UIApplicationStateActive;
}
- (BOOL)isShareExtension {
return NO;
}
- (BOOL)isRTL
{
// FIXME: We should try to remove this as we've had to add a hack to ensure the first call to this runs on the main thread
static BOOL isRTL = NO;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
isRTL = [[UIApplication sharedApplication] userInterfaceLayoutDirection]
== UIUserInterfaceLayoutDirectionRightToLeft;
});
return isRTL;
}
- (void)setStatusBarHidden:(BOOL)isHidden animated:(BOOL)isAnimated
{
[[UIApplication sharedApplication] setStatusBarHidden:isHidden animated:isAnimated];
}
- (CGFloat)statusBarHeight
{
return [UIApplication sharedApplication].statusBarFrame.size.height;
}
- (BOOL)isInBackground
{
return self.reportedApplicationState == UIApplicationStateBackground;
}
- (BOOL)isAppForegroundAndActive
{
return self.reportedApplicationState == UIApplicationStateActive;
}
- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:
(BackgroundTaskExpirationHandler)expirationHandler
{
return [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:expirationHandler];
}
- (void)endBackgroundTask:(UIBackgroundTaskIdentifier)backgroundTaskIdentifier
{
[UIApplication.sharedApplication endBackgroundTask:backgroundTaskIdentifier];
}
- (void)ensureSleepBlocking:(BOOL)shouldBeBlocking blockingObjects:(NSArray<id> *)blockingObjects
{
if (UIApplication.sharedApplication.isIdleTimerDisabled != shouldBeBlocking) {
if (shouldBeBlocking) {
NSMutableString *logString =
[NSMutableString stringWithFormat:@"Blocking sleep because of: %@", blockingObjects.firstObject];
if (blockingObjects.count > 1) {
[logString appendString:[NSString stringWithFormat:@"(and %lu others)", blockingObjects.count - 1]];
}
OWSLogInfo(@"%@", logString);
} else {
OWSLogInfo(@"Unblocking Sleep.");
}
}
UIApplication.sharedApplication.idleTimerDisabled = shouldBeBlocking;
}
- (void)setMainAppBadgeNumber:(NSInteger)value
{
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:value];
[[NSUserDefaults sharedLokiProject] setInteger:value forKey:@"currentBadgeNumber"];
[[NSUserDefaults sharedLokiProject] synchronize];
}
- (nullable UIViewController *)frontmostViewController
{
return UIApplication.sharedApplication.frontmostViewControllerIgnoringAlerts;
}
- (nullable UIAlertAction *)openSystemSettingsAction
{
return [UIAlertAction actionWithTitle:CommonStrings.openSettingsButton
accessibilityIdentifier:[NSString stringWithFormat:@"%@.%@", self.class, @"system_settings"]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
[UIApplication.sharedApplication openSystemSettings];
}];
}
- (void)setNetworkActivityIndicatorVisible:(BOOL)value
{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:value];
}
#pragma mark -
- (void)runNowOrWhenMainAppIsActive:(AppActiveBlock)block
{
OWSAssertDebug(block);
[Threading dispatchMainThreadSafe:^{
if (self.isMainAppAndActive) {
// App active blocks typically will be used to safely access the
// shared data container, so use a background task to protect this
// work.
OWSBackgroundTask *_Nullable backgroundTask =
[OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__];
block();
OWSAssertDebug(backgroundTask);
backgroundTask = nil;
return;
}
[self.appActiveBlocks addObject:block];
}];
}
- (void)runAppActiveBlocks
{
OWSAssertIsOnMainThread();
OWSAssertDebug(self.isMainAppAndActive);
// App active blocks typically will be used to safely access the
// shared data container, so use a background task to protect this
// work.
OWSBackgroundTask *_Nullable backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__];
NSArray<AppActiveBlock> *appActiveBlocks = [self.appActiveBlocks copy];
[self.appActiveBlocks removeAllObjects];
for (AppActiveBlock block in appActiveBlocks) {
block();
}
OWSAssertDebug(backgroundTask);
backgroundTask = nil;
}
- (NSString *)appDocumentDirectoryPath
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *documentDirectoryURL =
[[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
return [documentDirectoryURL path];
}
- (NSString *)appSharedDataDirectoryPath
{
NSURL *groupContainerDirectoryURL =
[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:SignalApplicationGroup];
return [groupContainerDirectoryURL path];
}
- (NSUserDefaults *)appUserDefaults
{
return [[NSUserDefaults alloc] initWithSuiteName:SignalApplicationGroup];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,253 @@
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
import UIKit
import SignalCoreKit
import SessionUtilitiesKit
final class MainAppContext: NSObject, AppContext {
var reportedApplicationState: UIApplication.State
let appLaunchTime = Date()
let isMainApp: Bool = true
var isMainAppAndActive: Bool { UIApplication.shared.applicationState == .active }
var isShareExtension: Bool = false
var appActiveBlocks: [AppActiveBlock] = []
var mainWindow: UIWindow?
var wasWokenUpByPushNotification: Bool = false
private static var _isRTL: Bool = {
return (UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft)
}()
var isRTL: Bool { return MainAppContext._isRTL }
var statusBarHeight: CGFloat { UIApplication.shared.statusBarFrame.size.height }
var openSystemSettingsAction: UIAlertAction? {
let result = UIAlertAction(
title: "OPEN_SETTINGS_BUTTON".localized(),
style: .default
) { _ in UIApplication.shared.openSystemSettings() }
result.accessibilityIdentifier = "\(type(of: self)).system_settings"
return result
}
// MARK: - Initialization
override init() {
self.reportedApplicationState = .inactive
super.init()
NotificationCenter.default.addObserver(
self,
selector: #selector(applicationWillEnterForeground(notification:)),
name: UIApplication.willEnterForegroundNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(applicationDidEnterBackground(notification:)),
name: UIApplication.didEnterBackgroundNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(applicationWillResignActive(notification:)),
name: UIApplication.willResignActiveNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(applicationDidBecomeActive(notification:)),
name: UIApplication.didBecomeActiveNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(applicationWillTerminate(notification:)),
name: UIApplication.willTerminateNotification,
object: nil
)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
// MARK: - Notifications
@objc private func applicationWillEnterForeground(notification: NSNotification) {
AssertIsOnMainThread()
self.reportedApplicationState = .inactive
OWSLogger.info("")
NotificationCenter.default.post(
name: .OWSApplicationWillEnterForeground,
object: nil
)
}
@objc private func applicationDidEnterBackground(notification: NSNotification) {
AssertIsOnMainThread()
self.reportedApplicationState = .background
OWSLogger.info("")
DDLog.flushLog()
NotificationCenter.default.post(
name: .OWSApplicationDidEnterBackground,
object: nil
)
}
@objc private func applicationWillResignActive(notification: NSNotification) {
AssertIsOnMainThread()
self.reportedApplicationState = .inactive
OWSLogger.info("")
DDLog.flushLog()
NotificationCenter.default.post(
name: .OWSApplicationWillResignActive,
object: nil
)
}
@objc private func applicationDidBecomeActive(notification: NSNotification) {
AssertIsOnMainThread()
self.reportedApplicationState = .active
OWSLogger.info("")
NotificationCenter.default.post(
name: .OWSApplicationDidBecomeActive,
object: nil
)
self.runAppActiveBlocks()
}
@objc private func applicationWillTerminate(notification: NSNotification) {
AssertIsOnMainThread()
OWSLogger.info("")
DDLog.flushLog()
}
// MARK: - AppContext Functions
func setStatusBarHidden(_ isHidden: Bool, animated isAnimated: Bool) {
UIApplication.shared.setStatusBarHidden(isHidden, with: (isAnimated ? .slide : .none))
}
func isAppForegroundAndActive() -> Bool {
return (reportedApplicationState == .active)
}
func isInBackground() -> Bool {
return (reportedApplicationState == .background)
}
func beginBackgroundTask(expirationHandler: @escaping BackgroundTaskExpirationHandler) -> UIBackgroundTaskIdentifier {
return UIApplication.shared.beginBackgroundTask(expirationHandler: expirationHandler)
}
func endBackgroundTask(_ backgroundTaskIdentifier: UIBackgroundTaskIdentifier) {
UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier)
}
func ensureSleepBlocking(_ shouldBeBlocking: Bool, blockingObjects: [Any]) {
if UIApplication.shared.isIdleTimerDisabled != shouldBeBlocking {
if shouldBeBlocking {
var logString: String = "Blocking sleep because of: \(String(describing: blockingObjects.first))"
if blockingObjects.count > 1 {
logString = "\(logString) (and \(blockingObjects.count - 1) others)"
}
OWSLogger.info(logString)
}
else {
OWSLogger.info("Unblocking Sleep.")
}
}
UIApplication.shared.isIdleTimerDisabled = shouldBeBlocking
}
func setMainAppBadgeNumber(_ value: Int) {
UIApplication.shared.applicationIconBadgeNumber = value
UserDefaults.sharedLokiProject?.setValue(value, forKey: "currentBadgeNumber")
}
func frontmostViewController() -> UIViewController? {
UIApplication.shared.frontmostViewControllerIgnoringAlerts
}
func setNetworkActivityIndicatorVisible(_ value: Bool) {
UIApplication.shared.isNetworkActivityIndicatorVisible = value
}
// MARK: -
func runNowOr(whenMainAppIsActive block: @escaping AppActiveBlock) {
Threading.dispatchMainThreadSafe { [weak self] in
if self?.isMainAppAndActive == true {
// App active blocks typically will be used to safely access the
// shared data container, so use a background task to protect this
// work.
var backgroundTask: OWSBackgroundTask? = OWSBackgroundTask(label: #function)
block()
if backgroundTask != nil { backgroundTask = nil }
return
}
self?.appActiveBlocks.append(block)
}
}
func runAppActiveBlocks() {
// App active blocks typically will be used to safely access the
// shared data container, so use a background task to protect this
// work.
var backgroundTask: OWSBackgroundTask? = OWSBackgroundTask(label: #function)
let appActiveBlocks: [AppActiveBlock] = self.appActiveBlocks
self.appActiveBlocks.removeAll()
appActiveBlocks.forEach { $0() }
if backgroundTask != nil { backgroundTask = nil }
}
func appDocumentDirectoryPath() -> String {
let targetPath: String? = FileManager.default
.urls(
for: .documentDirectory,
in: .userDomainMask
)
.last?
.path
owsAssertDebug(targetPath != nil)
return (targetPath ?? "")
}
func appSharedDataDirectoryPath() -> String {
let targetPath: String? = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: UserDefaults.applicationGroup)?
.path
owsAssertDebug(targetPath != nil)
return (targetPath ?? "")
}
func appUserDefaults() -> UserDefaults {
owsAssertDebug(UserDefaults.sharedLokiProject != nil)
return (UserDefaults.sharedLokiProject ?? UserDefaults.standard)
}
}

View File

@ -7,4 +7,3 @@
#import "OWSBezierPathView.h"
#import "OWSMessageTimerView.h"
#import "OWSWindowManager.h"
#import "MainAppContext.h"

View File

@ -6,6 +6,8 @@ import GRDB
import SessionMessagingKit
import SignalUtilitiesKit
import SignalCoreKit
import SessionUtilitiesKit
import SessionSnodeKit
/// There are two primary components in our system notification integration:
///

View File

@ -4,8 +4,10 @@ import Foundation
import Combine
import PushKit
import GRDB
import SessionMessagingKit
import SignalUtilitiesKit
import SignalCoreKit
import SessionUtilitiesKit
public enum PushRegistrationError: Error {
case assertionError(description: String)
@ -53,8 +55,6 @@ public enum PushRegistrationError: Error {
Logger.info("")
return registerUserNotificationSettings()
.subscribe(on: DispatchQueue.global(qos: .default))
.receive(on: DispatchQueue.main) // MUST be on main thread
.setFailureType(to: Error.self)
.tryFlatMap { _ -> AnyPublisher<(pushToken: String, voipToken: String), Error> in
#if targetEnvironment(simulator)
@ -75,26 +75,25 @@ public enum PushRegistrationError: Error {
// MARK: Vanilla push token
// Vanilla push token is obtained from the system via AppDelegate
public func didReceiveVanillaPushToken(_ tokenData: Data) {
public func didReceiveVanillaPushToken(_ tokenData: Data, using dependencies: Dependencies = Dependencies()) {
guard let vanillaTokenResolver = self.vanillaTokenResolver else {
owsFailDebug("publisher completion in \(#function) unexpectedly nil")
return
}
DispatchQueue.global(qos: .default).async {
DispatchQueue.global(qos: .default).async(using: dependencies) {
vanillaTokenResolver(Result.success(tokenData))
}
}
// Vanilla push token is obtained from the system via AppDelegate
@objc
public func didFailToReceiveVanillaPushToken(error: Error) {
public func didFailToReceiveVanillaPushToken(error: Error, using dependencies: Dependencies = Dependencies()) {
guard let vanillaTokenResolver = self.vanillaTokenResolver else {
owsFailDebug("publisher completion in \(#function) unexpectedly nil")
return
}
DispatchQueue.global(qos: .default).async {
DispatchQueue.global(qos: .default).async(using: dependencies) {
vanillaTokenResolver(Result.failure(error))
}
}
@ -115,9 +114,8 @@ public enum PushRegistrationError: Error {
* in this case we've verified that we *have* properly registered notification settings.
*/
private var isSusceptibleToFailedPushRegistration: Bool {
// Only affects users who have disabled both: background refresh *and* notifications
guard UIApplication.shared.backgroundRefreshStatus == .denied else {
guard DispatchQueue.main.sync(execute: { UIApplication.shared.backgroundRefreshStatus }) == .denied else {
return false
}
@ -142,19 +140,21 @@ public enum PushRegistrationError: Error {
// No pending vanilla token yet; create a new publisher
let publisher: AnyPublisher<Data, Error> = Deferred {
Future<Data, Error> { self.vanillaTokenResolver = $0 }
Future<Data, Error> {
self.vanillaTokenResolver = $0
// Tell the device to register for remote notifications
DispatchQueue.main.sync { UIApplication.shared.registerForRemoteNotifications() }
}
}
.shareReplay(1)
.eraseToAnyPublisher()
self.vanillaTokenPublisher = publisher
// Tell the device to register for remote notifications
DispatchQueue.main.sync { UIApplication.shared.registerForRemoteNotifications() }
return publisher
.timeout(
.seconds(10),
scheduler: DispatchQueue.main,
scheduler: DispatchQueue.global(qos: .default),
customError: { PushRegistrationError.timeout }
)
.catch { error -> AnyPublisher<Data, Error> in

View File

@ -39,29 +39,29 @@ public enum SyncPushTokensJob: JobExecutor {
guard isUsingFullAPNs else {
Just(dependencies.storage[.lastRecordedPushToken])
.setFailureType(to: Error.self)
.flatMap { lastRecordedPushToken -> AnyPublisher<String, Error> in
if let existingToken: String = lastRecordedPushToken {
SNLog("[SyncPushTokensJob] Unregister using last recorded push token: \(redact(existingToken))")
return Just(existingToken)
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
}
SNLog("[SyncPushTokensJob] Unregister using live token provided from device")
return PushRegistrationManager.shared.requestPushTokens()
.map { token, _ in token }
.eraseToAnyPublisher()
}
.flatMap { pushToken in PushNotificationAPI.unsubscribe(token: Data(hex: pushToken)) }
.map {
.flatMap { lastRecordedPushToken -> AnyPublisher<Void, Error> in
// Tell the device to unregister for remote notifications (essentially try to invalidate
// the token if needed
// the token if needed - we do this first to avoid wrid race conditions which could be
// triggered by the user immediately re-registering)
DispatchQueue.main.sync { UIApplication.shared.unregisterForRemoteNotifications() }
// Clear the old token
dependencies.storage.write(using: dependencies) { db in
db[.lastRecordedPushToken] = nil
}
return ()
// Unregister from our server
if let existingToken: String = lastRecordedPushToken {
SNLog("[SyncPushTokensJob] Unregister using last recorded push token: \(redact(existingToken))")
return PushNotificationAPI.unsubscribe(token: Data(hex: existingToken))
.map { _ in () }
.eraseToAnyPublisher()
}
SNLog("[SyncPushTokensJob] No previous token stored just triggering device unregister")
return Just(())
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
}
.subscribe(on: queue, using: dependencies)
.sinkUntilComplete(
@ -151,5 +151,9 @@ extension SyncPushTokensJob {
// MARK: - Convenience
private func redact(_ string: String) -> String {
return OWSIsDebugBuild() ? string : "[ READACTED \(string.prefix(2))...\(string.suffix(2)) ]"
#if DEBUG
return string
#else
return "[ READACTED \(string.prefix(2))...\(string.suffix(2)) ]"
#endif
}

View File

@ -6,6 +6,7 @@ import UserNotifications
import SessionMessagingKit
import SignalCoreKit
import SignalUtilitiesKit
import SessionUtilitiesKit
class UserNotificationConfig {

View File

@ -258,9 +258,9 @@ enum Onboarding {
// Notify the app that registration is complete
Identity.didRegister()
// Now that we have registered get the Snode pool and sync push tokens
// Now that we have registered get the Snode pool (just in case) - other non-blocking
// launch jobs will automatically be run because the app activation was triggered
GetSnodePoolJob.run()
SyncPushTokensJob.run(uploadOnlyIfStale: false)
}
}
}

View File

@ -6,6 +6,7 @@ import SessionUIKit
import SessionMessagingKit
import SessionSnodeKit
import SignalUtilitiesKit
import SessionUtilitiesKit
final class PNModeVC: BaseVC, OptionViewDelegate {
private let flow: Onboarding.Flow

View File

@ -4,6 +4,7 @@ import UIKit
import Sodium
import SessionUIKit
import SignalUtilitiesKit
import SessionUtilitiesKit
final class RegisterVC : BaseVC {
private var seed: Data! { didSet { updateKeyPair() } }

View File

@ -3,6 +3,7 @@
import UIKit
import SessionUIKit
import SignalUtilitiesKit
import SessionUtilitiesKit
final class AppearanceViewController: BaseVC {
// MARK: - Components

View File

@ -6,6 +6,7 @@ import GRDB
import DifferenceKit
import SessionUIKit
import SignalUtilitiesKit
import SessionUtilitiesKit
class BlockedContactsViewModel: SessionTableViewModel<NoNav, BlockedContactsViewModel.Section, Profile> {
// MARK: - Section

View File

@ -1,6 +1,7 @@
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import SessionUtilitiesKit
class ImagePickerHandler: NSObject, UIImagePickerControllerDelegate & UINavigationControllerDelegate {
private let onTransition: (UIViewController, TransitionType) -> Void

View File

@ -5,6 +5,7 @@ import SessionUIKit
import SessionSnodeKit
import SessionMessagingKit
import SignalUtilitiesKit
import SessionUtilitiesKit
final class NukeDataModal: Modal {
// MARK: - Initialization

View File

@ -2,6 +2,7 @@
import UIKit
import SessionUIKit
import SessionUtilitiesKit
public protocol CaptionContainerViewDelegate: AnyObject {
func captionContainerViewDidUpdateText(_ captionContainerView: CaptionContainerView)

View File

@ -4,6 +4,7 @@ import UIKit
import SessionUIKit
import SignalUtilitiesKit
import SessionMessagingKit
import SessionUtilitiesKit
public final class FullConversationCell: UITableViewCell, SwipeActionOptimisticCell {
public static let mutePrefix: String = "\u{e067} "

View File

@ -1,6 +1,6 @@
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import UIKit
import SessionUIKit
// MARK: - Main Types

View File

@ -1,6 +1,7 @@
import Foundation
import GRDB
import SessionSnodeKit
import SessionUtilitiesKit
final class IP2Country {
static var isInitialized = false
@ -12,16 +13,16 @@ final class IP2Country {
/// the **lower** bound of an IP range and the "registered_country_geoname_id" column contains the ID of the country corresponding
/// to that range. We look up an IP by finding the first index in the network column where the value is greater than the IP we're looking
/// up (converted to an integer). The IP we're looking up must then be in the range **before** that range.
private lazy var ipv4Table: [String:[Int]] = {
private lazy var ipv4Table: [String: [Int]] = {
let url = Bundle.main.url(forResource: "GeoLite2-Country-Blocks-IPv4", withExtension: nil)!
let data = try! Data(contentsOf: url)
return try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! [String:[Int]]
return try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! [String: [Int]]
}()
private lazy var countryNamesTable: [String:[String]] = {
private lazy var countryNamesTable: [String: [String]] = {
let url = Bundle.main.url(forResource: "GeoLite2-Country-Locations-English", withExtension: nil)!
let data = try! Data(contentsOf: url)
return try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! [String:[String]]
return try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! [String: [String]]
}()
// MARK: Lifecycle

View File

@ -4,6 +4,7 @@ import Foundation
import GRDB
import Curve25519Kit
import SessionMessagingKit
import SessionUtilitiesKit
enum MockDataGenerator {
// MARK: - Generation

View File

@ -3,6 +3,7 @@
import UIKit
import SessionMessagingKit
import SessionUIKit
import SessionUtilitiesKit
protocol SwipeActionOptimisticCell {
func optimisticUpdate(isMuted: Bool?, isBlocked: Bool?, isPinned: Bool?, hasUnread: Bool?)

View File

@ -5,6 +5,7 @@ import GRDB
import UserNotifications
import SignalUtilitiesKit
import SessionMessagingKit
import SessionUtilitiesKit
public class NSENotificationPresenter: NSObject, NotificationsProtocol {
private var notifications: [String: UNNotificationRequest] = [:]

View File

@ -9,6 +9,7 @@ import BackgroundTasks
import SessionMessagingKit
import SignalUtilitiesKit
import SignalCoreKit
import SessionUtilitiesKit
public final class NotificationServiceExtension: UNNotificationServiceExtension {
private var didPerformSetup = false
@ -25,8 +26,6 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension
self.contentHandler = contentHandler
self.request = request
Storage.resumeDatabaseAccess()
guard let notificationContent = request.content.mutableCopy() as? UNMutableNotificationContent else {
return self.completeSilenty()
}
@ -36,10 +35,16 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension
return self.completeSilenty()
}
/// Create the context if we don't have it (needed before _any_ interaction with the database)
if !HasAppContext() {
SetCurrentAppContext(NotificationServiceExtensionContext())
}
let isCallOngoing: Bool = (UserDefaults.sharedLokiProject?[.isCallOngoing])
.defaulting(to: false)
// Perform main setup
Storage.resumeDatabaseAccess()
DispatchQueue.main.sync { self.setUpIfNecessary() { } }
// Handle the push notification
@ -224,20 +229,10 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension
didPerformSetup = true
// This should be the first thing we do.
SetCurrentAppContext(NotificationServiceExtensionContext())
_ = AppVersion.sharedInstance()
Cryptography.seedRandom()
// We should never receive a non-voip notification on an app that doesn't support
// app extensions since we have to inform the service we wanted these, so in theory
// this path should never occur. However, the service does have our push token
// so it is possible that could change in the future. If it does, do nothing
// and don't disturb the user. Messages will be processed when they open the app.
guard Storage.shared[.isReadyForAppExtensions] else { return completeSilenty() }
AppSetup.setupEnvironment(
appSpecificBlock: {
Environment.shared?.notificationsManager.mutate {
@ -247,8 +242,22 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension
migrationsCompletion: { [weak self] result, needsConfigSync in
switch result {
// Only 'NSLog' works in the extension - viewable via Console.app
case .failure: NSLog("[NotificationServiceExtension] Failed to complete migrations")
case .failure(let error):
NSLog("[NotificationServiceExtension] Failed to complete migrations")
self?.completeSilenty()
case .success:
// We should never receive a non-voip notification on an app that doesn't support
// app extensions since we have to inform the service we wanted these, so in theory
// this path should never occur. However, the service does have our push token
// so it is possible that could change in the future. If it does, do nothing
// and don't disturb the user. Messages will be processed when they open the app.
guard Storage.shared[.isReadyForAppExtensions] else {
NSLog("[NotificationServiceExtension] Not ready for extensions")
self?.completeSilenty()
return
}
DispatchQueue.main.async {
self?.versionMigrationsDidComplete(needsConfigSync: needsConfigSync)
}

View File

@ -4,6 +4,7 @@
import Foundation
import SignalUtilitiesKit
import SessionUtilitiesKit
final class NotificationServiceExtensionContext : NSObject, AppContext {
let appLaunchTime = Date()
@ -31,10 +32,6 @@ final class NotificationServiceExtensionContext : NSObject, AppContext {
func isInBackground() -> Bool { true }
func mainApplicationStateOnLaunch() -> UIApplication.State { .inactive }
func appDatabaseBaseDirectoryPath() -> String {
return appSharedDataDirectoryPath()
}
func appDocumentDirectoryPath() -> String {
guard let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last else {
preconditionFailure("Couldn't get document directory.")
@ -43,14 +40,14 @@ final class NotificationServiceExtensionContext : NSObject, AppContext {
}
func appSharedDataDirectoryPath() -> String {
guard let groupContainerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: SignalApplicationGroup) else {
guard let groupContainerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: UserDefaults.applicationGroup) else {
preconditionFailure("Couldn't get shared data directory.")
}
return groupContainerURL.path
}
func appUserDefaults() -> UserDefaults {
guard let userDefaults = UserDefaults(suiteName: SignalApplicationGroup) else {
guard let userDefaults = UserDefaults.sharedLokiProject else {
preconditionFailure("Couldn't set up shared user defaults.")
}
return userDefaults

View File

@ -157,7 +157,7 @@ final class ShareAppExtensionContext: NSObject, AppContext {
func appSharedDataDirectoryPath() -> String {
let targetPath: String? = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: SignalApplicationGroup)?
.containerURL(forSecurityApplicationGroupIdentifier: UserDefaults.applicationGroup)?
.path
owsAssertDebug(targetPath != nil)
@ -165,10 +165,9 @@ final class ShareAppExtensionContext: NSObject, AppContext {
}
func appUserDefaults() -> UserDefaults {
let targetUserDefaults: UserDefaults? = UserDefaults(suiteName: SignalApplicationGroup)
owsAssertDebug(targetUserDefaults != nil)
owsAssertDebug(UserDefaults.sharedLokiProject != nil)
return (targetUserDefaults ?? UserDefaults.standard)
return (UserDefaults.sharedLokiProject ?? UserDefaults.standard)
}
func setStatusBarHidden(_ isHidden: Bool, animated isAnimated: Bool) {

View File

@ -7,6 +7,7 @@ import DifferenceKit
import SessionUIKit
import SignalUtilitiesKit
import SessionMessagingKit
import SessionSnodeKit
final class ThreadPickerVC: UIViewController, UITableViewDataSource, UITableViewDelegate, AttachmentApprovalViewControllerDelegate {
private let viewModel: ThreadPickerViewModel = ThreadPickerViewModel()

View File

@ -275,7 +275,7 @@ public enum OnionRequestAPI {
if let snode = snode {
if let path = paths.first(where: { !$0.contains(snode) }) {
buildPaths(reusing: paths, using: dependencies) // Re-build paths in the background
.subscribe(on: DispatchQueue.global(qos: .background))
.subscribe(on: DispatchQueue.global(qos: .background), using: dependencies)
.sink(receiveCompletion: { _ in cancellable = [] }, receiveValue: { _ in })
.store(in: &cancellable)

View File

@ -2,15 +2,6 @@
NS_ASSUME_NONNULL_BEGIN
static inline BOOL OWSIsDebugBuild()
{
#ifdef DEBUG
return YES;
#else
return NO;
#endif
}
// These are fired whenever the corresponding "main app" or "app extension"
// notification is fired.
//

View File

@ -62,8 +62,10 @@ public enum SNUserDefaults {
}
public extension UserDefaults {
public static let applicationGroup: String = "group.com.loki-project.loki-messenger"
@objc static var sharedLokiProject: UserDefaults? {
UserDefaults(suiteName: "group.com.loki-project.loki-messenger")
UserDefaults(suiteName: UserDefaults.applicationGroup)
}
}

View File

@ -4,6 +4,7 @@ import Foundation
import SessionUIKit
import SessionSnodeKit
import SessionMessagingKit
import SessionUtilitiesKit
public enum Configuration {
public static func performMainSetup() {

View File

@ -9,6 +9,7 @@ import CoreServices
import SessionUIKit
import SessionMessagingKit
import SignalCoreKit
import SessionUtilitiesKit
public protocol AttachmentApprovalViewControllerDelegate: AnyObject {
func attachmentApproval(

View File

@ -4,6 +4,7 @@ import Foundation
import UIKit
import SessionUIKit
import SignalCoreKit
import SessionUtilitiesKit
protocol AttachmentCaptionToolbarDelegate: AnyObject {
func attachmentCaptionToolbarDidEdit(_ attachmentCaptionToolbar: AttachmentCaptionToolbar)
@ -150,26 +151,7 @@ class AttachmentCaptionToolbar: UIView, UITextViewDelegate {
public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
let existingText: String = textView.text ?? ""
let proposedText: String = (existingText as NSString).replacingCharacters(in: range, with: text)
// Don't complicate things by mixing media attachments with oversize text attachments
guard proposedText.utf8.count < kOversizeTextMessageSizeThreshold else {
Logger.debug("long text was truncated")
self.lengthLimitLabel.isHidden = false
// `range` represents the section of the existing text we will replace. We can re-use that space.
// Range is in units of NSStrings's standard UTF-16 characters. Since some of those chars could be
// represented as single bytes in utf-8, while others may be 8 or more, the only way to be sure is
// to just measure the utf8 encoded bytes of the replaced substring.
let bytesAfterDelete: Int = (existingText as NSString).replacingCharacters(in: range, with: "").utf8.count
// Accept as much of the input as we can
let byteBudget: Int = Int(kOversizeTextMessageSizeThreshold) - bytesAfterDelete
if byteBudget >= 0, let acceptableNewText = text.truncated(toByteCount: UInt(byteBudget)) {
textView.text = (existingText as NSString).replacingCharacters(in: range, with: acceptableNewText)
}
return false
}
self.lengthLimitLabel.isHidden = true
// After verifying the byte-length is sufficiently small, verify the character count is within bounds.

View File

@ -5,6 +5,8 @@ import UIKit
import AVFoundation
import SessionUIKit
import SignalCoreKit
import SessionMessagingKit
import SessionUtilitiesKit
protocol AttachmentPrepViewControllerDelegate: AnyObject {
func prepViewControllerUpdateNavigationBar()

View File

@ -2,9 +2,10 @@
import Foundation
import UIKit
import SessionUIKit
import SignalCoreKit
import PureLayout
import SignalCoreKit
import SessionUIKit
import SessionUtilitiesKit
// Coincides with Android's max text message length
let kMaxMessageBodyCharacterCount = 2000
@ -228,25 +229,6 @@ class AttachmentTextToolbar: UIView, UITextViewDelegate {
let existingText: String = textView.text ?? ""
let proposedText: String = (existingText as NSString).replacingCharacters(in: range, with: text)
// Don't complicate things by mixing media attachments with oversize text attachments
guard proposedText.utf8.count < kOversizeTextMessageSizeThreshold else {
Logger.debug("long text was truncated")
self.lengthLimitLabel.isHidden = false
// `range` represents the section of the existing text we will replace. We can re-use that space.
// Range is in units of NSStrings's standard UTF-16 characters. Since some of those chars could be
// represented as single bytes in utf-8, while others may be 8 or more, the only way to be sure is
// to just measure the utf8 encoded bytes of the replaced substring.
let bytesAfterDelete: Int = (existingText as NSString).replacingCharacters(in: range, with: "").utf8.count
// Accept as much of the input as we can
let byteBudget: Int = Int(kOversizeTextMessageSizeThreshold) - bytesAfterDelete
if byteBudget >= 0, let acceptableNewText = text.truncated(toByteCount: UInt(byteBudget)) {
textView.text = (existingText as NSString).replacingCharacters(in: range, with: acceptableNewText)
}
return false
}
self.lengthLimitLabel.isHidden = true
// After verifying the byte-length is sufficiently small, verify the character count is within bounds.

View File

@ -3,6 +3,7 @@
import UIKit
import SessionUIKit
import SignalCoreKit
import SessionUtilitiesKit
public class EditorTextLayer: CATextLayer {
let itemId: String

View File

@ -3,6 +3,7 @@
import UIKit
import SessionUIKit
import SignalCoreKit
import SessionUtilitiesKit
public protocol ImageEditorCropViewControllerDelegate: AnyObject {
func cropDidComplete(transform: ImageEditorTransform)
@ -200,7 +201,7 @@ class ImageEditorCropViewController: OWSViewController {
case .topRight, .bottomRight:
cropCornerView.autoPinEdge(toSuperviewEdge: .right)
default:
owsFailDebug("Invalid crop region: \(cropRegion)")
owsFailDebug("Invalid crop region: \(String(describing: cropRegion))")
}
switch cropCornerView.cropRegion {
case .topLeft, .topRight:
@ -208,7 +209,7 @@ class ImageEditorCropViewController: OWSViewController {
case .bottomLeft, .bottomRight:
cropCornerView.autoPinEdge(toSuperviewEdge: .bottom)
default:
owsFailDebug("Invalid crop region: \(cropRegion)")
owsFailDebug("Invalid crop region: \(String(describing: cropRegion))")
}
}

View File

@ -2,6 +2,7 @@
import UIKit
import SignalCoreKit
import SessionUtilitiesKit
// Used to represent undo/redo operations.
//

View File

@ -2,6 +2,7 @@
import UIKit
import SignalCoreKit
import SessionUtilitiesKit
public struct ImageEditorPinchState {
public let centroid: CGPoint

View File

@ -3,6 +3,7 @@
//
import UIKit
import SessionUtilitiesKit
@objc
public class ImageEditorStrokeItem: ImageEditorItem {

View File

@ -8,6 +8,7 @@ import NVActivityIndicatorView
import SessionUIKit
import SessionMessagingKit
import SignalCoreKit
import SessionUtilitiesKit
public protocol MediaMessageViewAudioDelegate: AnyObject {
func progressChanged(_ progressSeconds: CGFloat, durationSeconds: CGFloat)

View File

@ -3,15 +3,5 @@
FOUNDATION_EXPORT double SignalUtilitiesKitVersionNumber;
FOUNDATION_EXPORT const unsigned char SignalUtilitiesKitVersionString[];
@import SessionMessagingKit;
@import SessionSnodeKit;
@import SessionUtilitiesKit;
#import <SignalUtilitiesKit/AppVersion.h>
#import <SignalUtilitiesKit/ByteParser.h>
#import <SignalUtilitiesKit/FunctionalUtil.h>
#import <SignalUtilitiesKit/NSURLSessionDataTask+StatusCode.h>
#import <SignalUtilitiesKit/OWSError.h>
#import <SignalUtilitiesKit/OWSOperation.h>
#import <SignalUtilitiesKit/OWSViewController.h>
#import <SignalUtilitiesKit/TSConstants.h>

View File

@ -7,6 +7,10 @@ import SessionMessagingKit
import SignalCoreKit
public class ScreenLock {
public enum ScreenLockError: Error {
case general(description: String)
}
public enum Outcome {
case success
case cancel
@ -54,11 +58,11 @@ public class ScreenLock {
switch outcome {
case .failure(let error):
Logger.error("local authentication failed with error: \(error)")
failure(self.authenticationError(errorDescription: error))
failure(ScreenLockError.general(description: error))
case .unexpectedFailure(let error):
Logger.error("local authentication failed with unexpected error: \(error)")
unexpectedFailure(self.authenticationError(errorDescription: error))
unexpectedFailure(ScreenLockError.general(description: error))
case .success:
Logger.verbose("local authentication succeeded.")
@ -203,11 +207,7 @@ public class ScreenLock {
}
}
return .failure(error:defaultErrorDescription)
}
private func authenticationError(errorDescription: String) -> Error {
return OWSErrorWithCodeDescription(.localAuthenticationError, errorDescription)
return .failure(error: defaultErrorDescription)
}
// MARK: - Context

View File

@ -5,6 +5,7 @@ import GRDB
import SessionMessagingKit
import SessionUtilitiesKit
import SessionUIKit
import SessionSnodeKit
public enum AppSetup {
private static let hasRun: Atomic<Bool> = Atomic(false)

View File

@ -1,40 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface ByteParser : NSObject
@property (nonatomic, readonly) BOOL hasError;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithData:(NSData *)data littleEndian:(BOOL)littleEndian;
#pragma mark - Short
- (uint16_t)shortAtIndex:(NSUInteger)index;
- (uint16_t)nextShort;
#pragma mark - Int
- (uint32_t)intAtIndex:(NSUInteger)index;
- (uint32_t)nextInt;
#pragma mark - Long
- (uint64_t)longAtIndex:(NSUInteger)index;
- (uint64_t)nextLong;
#pragma mark -
- (BOOL)readZero:(NSUInteger)length;
- (nullable NSData *)readBytes:(NSUInteger)length;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,143 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "ByteParser.h"
#import <SignalCoreKit/OWSAsserts.h>
NS_ASSUME_NONNULL_BEGIN
@interface ByteParser ()
@property (nonatomic, readonly) BOOL littleEndian;
@property (nonatomic, readonly) NSData *data;
@property (nonatomic) NSUInteger cursor;
@property (nonatomic) BOOL hasError;
@end
#pragma mark -
@implementation ByteParser
- (instancetype)initWithData:(NSData *)data littleEndian:(BOOL)littleEndian
{
if (self = [super init]) {
_littleEndian = littleEndian;
_data = data;
}
return self;
}
#pragma mark - Short
- (uint16_t)shortAtIndex:(NSUInteger)index
{
uint16_t value;
const size_t valueSize = sizeof(value);
OWSAssertDebug(valueSize == 2);
if (index + valueSize > self.data.length) {
self.hasError = YES;
return 0;
}
[self.data getBytes:&value range:NSMakeRange(index, valueSize)];
if (self.littleEndian) {
return CFSwapInt16LittleToHost(value);
} else {
return CFSwapInt16BigToHost(value);
}
}
- (uint16_t)nextShort
{
uint16_t value = [self shortAtIndex:self.cursor];
self.cursor += sizeof(value);
return value;
}
#pragma mark - Int
- (uint32_t)intAtIndex:(NSUInteger)index
{
uint32_t value;
const size_t valueSize = sizeof(value);
OWSAssertDebug(valueSize == 4);
if (index + valueSize > self.data.length) {
self.hasError = YES;
return 0;
}
[self.data getBytes:&value range:NSMakeRange(index, valueSize)];
if (self.littleEndian) {
return CFSwapInt32LittleToHost(value);
} else {
return CFSwapInt32BigToHost(value);
}
}
- (uint32_t)nextInt
{
uint32_t value = [self intAtIndex:self.cursor];
self.cursor += sizeof(value);
return value;
}
#pragma mark - Long
- (uint64_t)longAtIndex:(NSUInteger)index
{
uint64_t value;
const size_t valueSize = sizeof(value);
OWSAssertDebug(valueSize == 8);
if (index + valueSize > self.data.length) {
self.hasError = YES;
return 0;
}
[self.data getBytes:&value range:NSMakeRange(index, valueSize)];
if (self.littleEndian) {
return CFSwapInt64LittleToHost(value);
} else {
return CFSwapInt64BigToHost(value);
}
}
- (uint64_t)nextLong
{
uint64_t value = [self longAtIndex:self.cursor];
self.cursor += sizeof(value);
return value;
}
#pragma mark -
- (BOOL)readZero:(NSUInteger)length
{
NSData *_Nullable subdata = [self readBytes:length];
if (!subdata) {
return NO;
}
uint8_t bytes[length];
[subdata getBytes:bytes range:NSMakeRange(0, length)];
for (int i = 0; i < length; i++) {
if (bytes[i] != 0) {
return NO;
}
}
return YES;
}
- (nullable NSData *)readBytes:(NSUInteger)length
{
NSUInteger index = self.cursor;
if (index + length > self.data.length) {
self.hasError = YES;
return nil;
}
NSData *_Nullable subdata = [self.data subdataWithRange:NSMakeRange(index, length)];
self.cursor += length;
return subdata;
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,27 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSArray (FunctionalUtil)
/// Returns true when any of the items in this array match the given predicate.
- (bool)any:(int (^)(id item))predicate;
/// Returns true when all of the items in this array match the given predicate.
- (bool)all:(int (^)(id item))predicate;
/// Returns an array of all the results of passing items from this array through the given projection function.
- (NSArray *)map:(id (^)(id item))projection;
/// Returns an array of all the results of passing items from this array through the given projection function.
- (NSArray *)filter:(int (^)(id item))predicate;
- (NSDictionary *)groupBy:(id (^)(id value))keySelector;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,98 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import "FunctionalUtil.h"
#import <SignalCoreKit/OWSAsserts.h>
NS_ASSUME_NONNULL_BEGIN
@interface FUBadArgument : NSException
+ (FUBadArgument *) new:(NSString *)reason;
+ (void)raise:(NSString *)message;
@end
@implementation FUBadArgument
+ (FUBadArgument *) new:(NSString *)reason {
return [[FUBadArgument alloc] initWithName:@"Invalid Argument" reason:reason userInfo:nil];
}
+ (void)raise:(NSString *)message {
[FUBadArgument raise:@"Invalid Argument" format:@"%@", message];
}
@end
#define tskit_require(expr) \
if (!(expr)) { \
NSString *reason = \
[NSString stringWithFormat:@"require %@ (in %s at line %d)", (@ #expr), __FILE__, __LINE__]; \
OWSLogError(@"%@", reason); \
[FUBadArgument raise:reason]; \
};
@implementation NSArray (FunctionalUtil)
- (bool)any:(int (^)(id item))predicate {
tskit_require(predicate != nil);
for (id e in self) {
if (predicate(e)) {
return true;
}
}
return false;
}
- (bool)all:(int (^)(id item))predicate {
tskit_require(predicate != nil);
for (id e in self) {
if (!predicate(e)) {
return false;
}
}
return true;
}
- (NSArray *)map:(id (^)(id item))projection {
tskit_require(projection != nil);
NSMutableArray *r = [NSMutableArray arrayWithCapacity:self.count];
for (id e in self) {
[r addObject:projection(e)];
}
return r;
}
- (NSArray *)filter:(int (^)(id item))predicate {
tskit_require(predicate != nil);
NSMutableArray *r = [NSMutableArray array];
for (id e in self) {
if (predicate(e)) {
[r addObject:e];
}
}
return r;
}
- (NSDictionary *)groupBy:(id (^)(id value))keySelector {
tskit_require(keySelector != nil);
NSMutableDictionary *result = [NSMutableDictionary dictionary];
for (id item in self) {
id key = keySelector(item);
NSMutableArray *group = result[key];
if (group == nil) {
group = [NSMutableArray array];
result[key] = group;
}
[group addObject:item];
}
return result;
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,15 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSURLSessionTask (StatusCode)
- (long)statusCode;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,18 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import "NSURLSessionDataTask+StatusCode.h"
NS_ASSUME_NONNULL_BEGIN
@implementation NSURLSessionTask (StatusCode)
- (long)statusCode {
NSHTTPURLResponse *response = (NSHTTPURLResponse *)self.response;
return response.statusCode;
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,69 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
extern NSString *const OWSSignalServiceKitErrorDomain;
typedef NS_ENUM(NSInteger, OWSErrorCode) {
OWSErrorCodeInvalidMethodParameters = 11,
OWSErrorCodeUnableToProcessServerResponse = 12,
OWSErrorCodeFailedToDecodeJson = 13,
OWSErrorCodeFailedToEncodeJson = 14,
OWSErrorCodeFailedToDecodeQR = 15,
OWSErrorCodePrivacyVerificationFailure = 20,
OWSErrorCodeUntrustedIdentity = 25,
OWSErrorCodeFailedToSendOutgoingMessage = 30,
OWSErrorCodeAssertionFailure = 31,
OWSErrorCodeFailedToDecryptMessage = 100,
OWSErrorCodeFailedToDecryptUDMessage = 101,
OWSErrorCodeFailedToEncryptMessage = 110,
OWSErrorCodeFailedToEncryptUDMessage = 111,
OWSErrorCodeSignalServiceFailure = 1001,
OWSErrorCodeSignalServiceRateLimited = 1010,
OWSErrorCodeUserError = 2001,
OWSErrorCodeMessageSendDisabledDueToPreKeyUpdateFailures = 777405,
OWSErrorCodeMessageSendFailedToBlockList = 777406,
OWSErrorCodeMessageSendNoValidRecipients = 777407,
OWSErrorCodeContactsUpdaterRateLimit = 777408,
OWSErrorCodeCouldNotWriteAttachmentData = 777409,
OWSErrorCodeMessageDeletedBeforeSent = 777410,
OWSErrorCodeDatabaseConversionFatalError = 777411,
OWSErrorCodeMoveFileToSharedDataContainerError = 777412,
OWSErrorCodeRegistrationMissing2FAPIN = 777413,
OWSErrorCodeDebugLogUploadFailed = 777414,
// A non-recoverable error occured while exporting a backup.
OWSErrorCodeExportBackupFailed = 777415,
// A possibly recoverable error occured while exporting a backup.
OWSErrorCodeExportBackupError = 777416,
// A non-recoverable error occured while importing a backup.
OWSErrorCodeImportBackupFailed = 777417,
// A possibly recoverable error occured while importing a backup.
OWSErrorCodeImportBackupError = 777418,
// A non-recoverable while importing or exporting a backup.
OWSErrorCodeBackupFailure = 777419,
OWSErrorCodeLocalAuthenticationError = 777420,
OWSErrorCodeMessageRequestFailed = 777421,
OWSErrorCodeMessageResponseFailed = 777422,
OWSErrorCodeInvalidMessage = 777423,
OWSErrorCodeProfileUpdateFailed = 777424,
OWSErrorCodeAvatarWriteFailed = 777425,
OWSErrorCodeAvatarUploadFailed = 777426,
OWSErrorCodeNoSessionForTransientMessage,
};
extern NSString *const OWSErrorRecipientIdentifierKey;
extern NSError *OWSErrorWithCodeDescription(OWSErrorCode code, NSString *description);
extern NSError *OWSErrorMakeUntrustedIdentityError(NSString *description, NSString *recipientId);
extern NSError *OWSErrorMakeUnableToProcessServerResponseError(void);
extern NSError *OWSErrorMakeFailedToSendOutgoingMessageError(void);
extern NSError *OWSErrorMakeAssertionError(NSString *description);
extern NSError *OWSErrorMakeMessageSendDisabledDueToPreKeyUpdateFailuresError(void);
extern NSError *OWSErrorMakeMessageSendFailedDueToBlockListError(void);
extern NSError *OWSErrorMakeWriteAttachmentDataError(void);
NS_ASSUME_NONNULL_END

View File

@ -1,68 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSError.h"
#import <SignalCoreKit/OWSAsserts.h>
NS_ASSUME_NONNULL_BEGIN
NSString *const OWSSignalServiceKitErrorDomain = @"OWSSignalServiceKitErrorDomain";
NSString *const OWSErrorRecipientIdentifierKey = @"OWSErrorKeyRecipientIdentifier";
NSError *OWSErrorWithCodeDescription(OWSErrorCode code, NSString *description)
{
return [NSError errorWithDomain:OWSSignalServiceKitErrorDomain
code:code
userInfo:@{ NSLocalizedDescriptionKey: description }];
}
NSError *OWSErrorMakeUnableToProcessServerResponseError()
{
return OWSErrorWithCodeDescription(OWSErrorCodeUnableToProcessServerResponse,
NSLocalizedString(@"ERROR_DESCRIPTION_SERVER_FAILURE", @"Generic server error"));
}
NSError *OWSErrorMakeFailedToSendOutgoingMessageError()
{
return OWSErrorWithCodeDescription(OWSErrorCodeFailedToSendOutgoingMessage,
NSLocalizedString(@"ERROR_DESCRIPTION_CLIENT_SENDING_FAILURE", @"Generic notice when message failed to send."));
}
NSError *OWSErrorMakeAssertionError(NSString *description)
{
OWSCFailDebug(@"Assertion failed: %@", description);
return OWSErrorWithCodeDescription(OWSErrorCodeAssertionFailure,
NSLocalizedString(@"ERROR_DESCRIPTION_UNKNOWN_ERROR", @"Worst case generic error message"));
}
NSError *OWSErrorMakeUntrustedIdentityError(NSString *description, NSString *recipientId)
{
return [NSError
errorWithDomain:OWSSignalServiceKitErrorDomain
code:OWSErrorCodeUntrustedIdentity
userInfo:@{ NSLocalizedDescriptionKey : description, OWSErrorRecipientIdentifierKey : recipientId }];
}
NSError *OWSErrorMakeMessageSendDisabledDueToPreKeyUpdateFailuresError()
{
return OWSErrorWithCodeDescription(OWSErrorCodeMessageSendDisabledDueToPreKeyUpdateFailures,
NSLocalizedString(@"ERROR_DESCRIPTION_MESSAGE_SEND_DISABLED_PREKEY_UPDATE_FAILURES",
@"Error message indicating that message send is disabled due to prekey update failures"));
}
NSError *OWSErrorMakeMessageSendFailedDueToBlockListError()
{
return OWSErrorWithCodeDescription(OWSErrorCodeMessageSendFailedToBlockList,
NSLocalizedString(@"ERROR_DESCRIPTION_MESSAGE_SEND_FAILED_DUE_TO_BLOCK_LIST",
@"Error message indicating that message send failed due to block list"));
}
NSError *OWSErrorMakeWriteAttachmentDataError()
{
return OWSErrorWithCodeDescription(OWSErrorCodeCouldNotWriteAttachmentData,
NSLocalizedString(@"ERROR_DESCRIPTION_MESSAGE_SEND_FAILED_DUE_TO_FAILED_ATTACHMENT_WRITE",
@"Error message indicating that message send failed due to failed attachment write"));
}
NS_ASSUME_NONNULL_END

View File

@ -1,88 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, OWSOperationState) {
OWSOperationStateNew,
OWSOperationStateExecuting,
OWSOperationStateFinished
};
// A base class for implementing retryable operations.
// To utilize the retryable behavior:
// Set remainingRetries to something greater than 0, and when you're reporting an error,
// set `error.isRetryable = YES`.
// If the failure is one that will not succeed upon retry, set `error.isFatal = YES`.
//
// isRetryable and isFatal are opposites but not redundant.
//
// If a group message send fails, the send will be retried if any of the errors were retryable UNLESS
// any of the errors were fatal. Fatal errors trump retryable errors.
@interface OWSOperation : NSOperation
@property (readonly, nullable) NSError *failingError;
// Defaults to 0, set to greater than 0 in init if you'd like the operation to be retryable.
@property NSUInteger remainingRetries;
#pragma mark - Mandatory Subclass Overrides
// Called every retry, this is where the bulk of the operation's work should go.
- (void)run;
#pragma mark - Optional Subclass Overrides
// Called one time only
- (nullable NSError *)checkForPreconditionError;
// Called at most one time.
- (void)didSucceed;
// Called at most one time.
- (void)didCancel;
// Called zero or more times, retry may be possible
- (void)didReportError:(NSError *)error;
// Called at most one time, once retry is no longer possible.
- (void)didFailWithError:(NSError *)error NS_SWIFT_NAME(didFail(error:));
// How long to wait before retry, if possible
- (NSTimeInterval)retryInterval;
#pragma mark - Success/Error - Do Not Override
// Runs now if a retry timer has been set by a previous failure,
// otherwise assumes we're currently running and does nothing.
- (void)runAnyQueuedRetry;
// Report that the operation completed successfully.
//
// Each invocation of `run` must make exactly one call to one of: `reportSuccess`, `reportCancelled`, or `reportError:`
- (void)reportSuccess;
// Call this when you abort before completion due to being cancelled.
//
// Each invocation of `run` must make exactly one call to one of: `reportSuccess`, `reportCancelled`, or `reportError:`
- (void)reportCancelled;
// Report that the operation failed to complete due to an error.
//
// Each invocation of `run` must make exactly one call to one of: `reportSuccess`, `reportCancelled`, or `reportError:`
// You must ensure that `run` cannot succeed after calling `reportError`, e.g. generally you'll write something like
// this:
//
// [self reportError:someError];
// return;
//
// If the error is terminal, and you want to avoid retry, report an error with `error.isFatal = YES` otherwise the
// operation will retry if possible.
- (void)reportError:(NSError *)error;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,253 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import "OWSOperation.h"
#import "OWSError.h"
#import <SignalCoreKit/OWSAsserts.h>
#import <SignalCoreKit/NSObject+OWS.h>
#import <SessionUtilitiesKit/OWSBackgroundTask.h>
#import <SessionUtilitiesKit/NSTimer+Proxying.h>
NS_ASSUME_NONNULL_BEGIN
NSString *const OWSOperationKeyIsExecuting = @"isExecuting";
NSString *const OWSOperationKeyIsFinished = @"isFinished";
@interface OWSOperation ()
@property (nullable) NSError *failingError;
@property (atomic) OWSOperationState operationState;
@property (nonatomic) OWSBackgroundTask *backgroundTask;
// This property should only be accessed on the main queue.
@property (nonatomic) NSTimer *_Nullable retryTimer;
@end
@implementation OWSOperation
- (instancetype)init
{
self = [super init];
if (!self) {
return self;
}
_operationState = OWSOperationStateNew;
_backgroundTask = [OWSBackgroundTask backgroundTaskWithLabel:self.logTag];
// Operations are not retryable by default.
_remainingRetries = 0;
return self;
}
- (void)dealloc
{
OWSLogDebug(@"in dealloc");
}
#pragma mark - Subclass Overrides
// Called one time only
- (nullable NSError *)checkForPreconditionError
{
// OWSOperation have a notion of failure, which is inferred by the presence of a `failingError`.
//
// By default, any failing dependency cascades that failure to it's dependent.
// If you'd like different behavior, override this method (`checkForPreconditionError`) without calling `super`.
for (NSOperation *dependency in self.dependencies) {
if (![dependency isKindOfClass:[OWSOperation class]]) {
// Native operations, like NSOperation and NSBlockOperation have no notion of "failure".
// So there's no `failingError` to cascade.
continue;
}
OWSOperation *dependentOperation = (OWSOperation *)dependency;
// Don't proceed if dependency failed - surface the dependency's error.
NSError *_Nullable dependencyError = dependentOperation.failingError;
if (dependencyError != nil) {
return dependencyError;
}
}
return nil;
}
// Called every retry, this is where the bulk of the operation's work should go.
- (void)run
{
OWSAbstractMethod();
}
// Called at most one time.
- (void)didSucceed
{
// no-op
// Override in subclass if necessary
}
// Called at most one time.
- (void)didCancel
{
// no-op
// Override in subclass if necessary
}
// Called zero or more times, retry may be possible
- (void)didReportError:(NSError *)error
{
// no-op
// Override in subclass if necessary
}
// Called at most one time, once retry is no longer possible.
- (void)didFailWithError:(NSError *)error
{
// no-op
// Override in subclass if necessary
}
#pragma mark - NSOperation overrides
// Do not override this method in a subclass instead, override `run`
- (void)main
{
OWSLogDebug(@"started.");
NSError *_Nullable preconditionError = [self checkForPreconditionError];
if (preconditionError) {
[self failOperationWithError:preconditionError];
return;
}
if (self.isCancelled) {
[self reportCancelled];
return;
}
[self run];
}
- (void)runAnyQueuedRetry
{
dispatch_async(dispatch_get_main_queue(), ^{
NSTimer *_Nullable retryTimer = self.retryTimer;
self.retryTimer = nil;
[retryTimer invalidate];
if (retryTimer != nil) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self run];
});
} else {
OWSLogVerbose(@"not re-running since operation is already running.");
}
});
}
#pragma mark - Public Methods
// These methods are not intended to be subclassed
- (void)reportSuccess
{
OWSLogDebug(@"succeeded.");
[self didSucceed];
[self markAsComplete];
}
// These methods are not intended to be subclassed
- (void)reportCancelled
{
OWSLogDebug(@"cancelled.");
[self didCancel];
[self markAsComplete];
}
- (void)reportError:(NSError *)error
{
[self didReportError:error];
if (self.remainingRetries == 0) {
[self failOperationWithError:error];
return;
}
self.remainingRetries--;
dispatch_async(dispatch_get_main_queue(), ^{
OWSAssertDebug(self.retryTimer == nil);
[self.retryTimer invalidate];
// The `scheduledTimerWith*` methods add the timer to the current thread's RunLoop.
// Since Operations typically run on a background thread, that would mean the background
// thread's RunLoop. However, the OS can spin down background threads if there's no work
// being done, so we run the risk of the timer's RunLoop being deallocated before it's
// fired.
//
// To ensure the timer's thread sticks around, we schedule it while on the main RunLoop.
self.retryTimer = [NSTimer weakScheduledTimerWithTimeInterval:self.retryInterval
target:self
selector:@selector(runAnyQueuedRetry)
userInfo:nil
repeats:NO];
});
}
// Override in subclass if you want something more sophisticated, e.g. exponential backoff
- (NSTimeInterval)retryInterval
{
return 0.1;
}
#pragma mark - Life Cycle
- (void)failOperationWithError:(NSError *)error
{
OWSLogDebug(@"failed terminally.");
self.failingError = error;
[self didFailWithError:error];
[self markAsComplete];
}
- (BOOL)isExecuting
{
return self.operationState == OWSOperationStateExecuting;
}
- (BOOL)isFinished
{
return self.operationState == OWSOperationStateFinished;
}
- (void)start
{
[self willChangeValueForKey:OWSOperationKeyIsExecuting];
self.operationState = OWSOperationStateExecuting;
[self didChangeValueForKey:OWSOperationKeyIsExecuting];
[self main];
}
- (void)markAsComplete
{
[self willChangeValueForKey:OWSOperationKeyIsExecuting];
[self willChangeValueForKey:OWSOperationKeyIsFinished];
// Ensure we call the success or failure handler exactly once.
@synchronized(self)
{
OWSAssertDebug(self.operationState != OWSOperationStateFinished);
self.operationState = OWSOperationStateFinished;
}
[self didChangeValueForKey:OWSOperationKeyIsExecuting];
[self didChangeValueForKey:OWSOperationKeyIsFinished];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -3,6 +3,7 @@
import Foundation
import Reachability
import SignalCoreKit
import SessionMessagingKit
/// **Warning:** The simulator doesn't detect reachability correctly so if you are seeing odd/incorrect reachability states double
/// check on an actual device before trying to replace this implementation

View File

@ -1,318 +0,0 @@
// DO NOT EDIT.
// swift-format-ignore-file
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: SignalIOS.proto
//
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
//*
// Copyright (C) 2014-2016 Open Whisper Systems
//
// Licensed according to the LICENSE file in this repository.
/// iOS - since we use a modern proto-compiler, we must specify
/// the legacy proto format.
import Foundation
import SwiftProtobuf
// If the compiler emits an error on this type, it is because this file
// was generated by a version of the `protoc` Swift plug-in that is
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
struct IOSProtos_BackupSnapshot {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
var entity: [IOSProtos_BackupSnapshot.BackupEntity] = []
var unknownFields = SwiftProtobuf.UnknownStorage()
struct BackupEntity {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// @required
var type: IOSProtos_BackupSnapshot.BackupEntity.TypeEnum {
get {return _type ?? .unknown}
set {_type = newValue}
}
/// Returns true if `type` has been explicitly set.
var hasType: Bool {return self._type != nil}
/// Clears the value of `type`. Subsequent reads from it will return its default value.
mutating func clearType() {self._type = nil}
/// @required
var entityData: Data {
get {return _entityData ?? SwiftProtobuf.Internal.emptyData}
set {_entityData = newValue}
}
/// Returns true if `entityData` has been explicitly set.
var hasEntityData: Bool {return self._entityData != nil}
/// Clears the value of `entityData`. Subsequent reads from it will return its default value.
mutating func clearEntityData() {self._entityData = nil}
/// @required
var collection: String {
get {return _collection ?? String()}
set {_collection = newValue}
}
/// Returns true if `collection` has been explicitly set.
var hasCollection: Bool {return self._collection != nil}
/// Clears the value of `collection`. Subsequent reads from it will return its default value.
mutating func clearCollection() {self._collection = nil}
/// @required
var key: String {
get {return _key ?? String()}
set {_key = newValue}
}
/// Returns true if `key` has been explicitly set.
var hasKey: Bool {return self._key != nil}
/// Clears the value of `key`. Subsequent reads from it will return its default value.
mutating func clearKey() {self._key = nil}
var unknownFields = SwiftProtobuf.UnknownStorage()
enum TypeEnum: SwiftProtobuf.Enum {
typealias RawValue = Int
case unknown // = 0
case migration // = 1
case thread // = 2
case interaction // = 3
case attachment // = 4
case misc // = 5
init() {
self = .unknown
}
init?(rawValue: Int) {
switch rawValue {
case 0: self = .unknown
case 1: self = .migration
case 2: self = .thread
case 3: self = .interaction
case 4: self = .attachment
case 5: self = .misc
default: return nil
}
}
var rawValue: Int {
switch self {
case .unknown: return 0
case .migration: return 1
case .thread: return 2
case .interaction: return 3
case .attachment: return 4
case .misc: return 5
}
}
}
init() {}
fileprivate var _type: IOSProtos_BackupSnapshot.BackupEntity.TypeEnum? = nil
fileprivate var _entityData: Data? = nil
fileprivate var _collection: String? = nil
fileprivate var _key: String? = nil
}
init() {}
}
#if swift(>=4.2)
extension IOSProtos_BackupSnapshot.BackupEntity.TypeEnum: CaseIterable {
// Support synthesized by the compiler.
}
#endif // swift(>=4.2)
struct IOSProtos_DeviceName {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// @required
var ephemeralPublic: Data {
get {return _ephemeralPublic ?? SwiftProtobuf.Internal.emptyData}
set {_ephemeralPublic = newValue}
}
/// Returns true if `ephemeralPublic` has been explicitly set.
var hasEphemeralPublic: Bool {return self._ephemeralPublic != nil}
/// Clears the value of `ephemeralPublic`. Subsequent reads from it will return its default value.
mutating func clearEphemeralPublic() {self._ephemeralPublic = nil}
/// @required
var syntheticIv: Data {
get {return _syntheticIv ?? SwiftProtobuf.Internal.emptyData}
set {_syntheticIv = newValue}
}
/// Returns true if `syntheticIv` has been explicitly set.
var hasSyntheticIv: Bool {return self._syntheticIv != nil}
/// Clears the value of `syntheticIv`. Subsequent reads from it will return its default value.
mutating func clearSyntheticIv() {self._syntheticIv = nil}
/// @required
var ciphertext: Data {
get {return _ciphertext ?? SwiftProtobuf.Internal.emptyData}
set {_ciphertext = newValue}
}
/// Returns true if `ciphertext` has been explicitly set.
var hasCiphertext: Bool {return self._ciphertext != nil}
/// Clears the value of `ciphertext`. Subsequent reads from it will return its default value.
mutating func clearCiphertext() {self._ciphertext = nil}
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
fileprivate var _ephemeralPublic: Data? = nil
fileprivate var _syntheticIv: Data? = nil
fileprivate var _ciphertext: Data? = nil
}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "IOSProtos"
extension IOSProtos_BackupSnapshot: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".BackupSnapshot"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "entity"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeRepeatedMessageField(value: &self.entity)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.entity.isEmpty {
try visitor.visitRepeatedMessageField(value: self.entity, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: IOSProtos_BackupSnapshot, rhs: IOSProtos_BackupSnapshot) -> Bool {
if lhs.entity != rhs.entity {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension IOSProtos_BackupSnapshot.BackupEntity: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = IOSProtos_BackupSnapshot.protoMessageName + ".BackupEntity"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "type"),
2: .same(proto: "entityData"),
3: .same(proto: "collection"),
4: .same(proto: "key"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularEnumField(value: &self._type)
case 2: try decoder.decodeSingularBytesField(value: &self._entityData)
case 3: try decoder.decodeSingularStringField(value: &self._collection)
case 4: try decoder.decodeSingularStringField(value: &self._key)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if let v = self._type {
try visitor.visitSingularEnumField(value: v, fieldNumber: 1)
}
if let v = self._entityData {
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
}
if let v = self._collection {
try visitor.visitSingularStringField(value: v, fieldNumber: 3)
}
if let v = self._key {
try visitor.visitSingularStringField(value: v, fieldNumber: 4)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: IOSProtos_BackupSnapshot.BackupEntity, rhs: IOSProtos_BackupSnapshot.BackupEntity) -> Bool {
if lhs._type != rhs._type {return false}
if lhs._entityData != rhs._entityData {return false}
if lhs._collection != rhs._collection {return false}
if lhs._key != rhs._key {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension IOSProtos_BackupSnapshot.BackupEntity.TypeEnum: SwiftProtobuf._ProtoNameProviding {
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
0: .same(proto: "UNKNOWN"),
1: .same(proto: "MIGRATION"),
2: .same(proto: "THREAD"),
3: .same(proto: "INTERACTION"),
4: .same(proto: "ATTACHMENT"),
5: .same(proto: "MISC"),
]
}
extension IOSProtos_DeviceName: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".DeviceName"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "ephemeralPublic"),
2: .same(proto: "syntheticIv"),
3: .same(proto: "ciphertext"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularBytesField(value: &self._ephemeralPublic)
case 2: try decoder.decodeSingularBytesField(value: &self._syntheticIv)
case 3: try decoder.decodeSingularBytesField(value: &self._ciphertext)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if let v = self._ephemeralPublic {
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
}
if let v = self._syntheticIv {
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
}
if let v = self._ciphertext {
try visitor.visitSingularBytesField(value: v, fieldNumber: 3)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: IOSProtos_DeviceName, rhs: IOSProtos_DeviceName) -> Bool {
if lhs._ephemeralPublic != rhs._ephemeralPublic {return false}
if lhs._syntheticIv != rhs._syntheticIv {return false}
if lhs._ciphertext != rhs._ciphertext {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}

View File

@ -1,409 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import Foundation
// WARNING: This code is generated. Only edit within the markers.
public enum SignalIOSProtoError: Error {
case invalidProtobuf(description: String)
}
// MARK: - SignalIOSProtoBackupSnapshotBackupEntity
@objc public class SignalIOSProtoBackupSnapshotBackupEntity: NSObject {
// MARK: - SignalIOSProtoBackupSnapshotBackupEntityType
@objc public enum SignalIOSProtoBackupSnapshotBackupEntityType: Int32 {
case unknown = 0
case migration = 1
case thread = 2
case interaction = 3
case attachment = 4
case misc = 5
}
private class func SignalIOSProtoBackupSnapshotBackupEntityTypeWrap(_ value: IOSProtos_BackupSnapshot.BackupEntity.TypeEnum) -> SignalIOSProtoBackupSnapshotBackupEntityType {
switch value {
case .unknown: return .unknown
case .migration: return .migration
case .thread: return .thread
case .interaction: return .interaction
case .attachment: return .attachment
case .misc: return .misc
}
}
private class func SignalIOSProtoBackupSnapshotBackupEntityTypeUnwrap(_ value: SignalIOSProtoBackupSnapshotBackupEntityType) -> IOSProtos_BackupSnapshot.BackupEntity.TypeEnum {
switch value {
case .unknown: return .unknown
case .migration: return .migration
case .thread: return .thread
case .interaction: return .interaction
case .attachment: return .attachment
case .misc: return .misc
}
}
// MARK: - SignalIOSProtoBackupSnapshotBackupEntityBuilder
@objc public class func builder(type: SignalIOSProtoBackupSnapshotBackupEntityType, entityData: Data, collection: String, key: String) -> SignalIOSProtoBackupSnapshotBackupEntityBuilder {
return SignalIOSProtoBackupSnapshotBackupEntityBuilder(type: type, entityData: entityData, collection: collection, key: key)
}
// asBuilder() constructs a builder that reflects the proto's contents.
@objc public func asBuilder() -> SignalIOSProtoBackupSnapshotBackupEntityBuilder {
let builder = SignalIOSProtoBackupSnapshotBackupEntityBuilder(type: type, entityData: entityData, collection: collection, key: key)
return builder
}
@objc public class SignalIOSProtoBackupSnapshotBackupEntityBuilder: NSObject {
private var proto = IOSProtos_BackupSnapshot.BackupEntity()
@objc fileprivate override init() {}
@objc fileprivate init(type: SignalIOSProtoBackupSnapshotBackupEntityType, entityData: Data, collection: String, key: String) {
super.init()
setType(type)
setEntityData(entityData)
setCollection(collection)
setKey(key)
}
@objc public func setType(_ valueParam: SignalIOSProtoBackupSnapshotBackupEntityType) {
proto.type = SignalIOSProtoBackupSnapshotBackupEntityTypeUnwrap(valueParam)
}
@objc public func setEntityData(_ valueParam: Data) {
proto.entityData = valueParam
}
@objc public func setCollection(_ valueParam: String) {
proto.collection = valueParam
}
@objc public func setKey(_ valueParam: String) {
proto.key = valueParam
}
@objc public func build() throws -> SignalIOSProtoBackupSnapshotBackupEntity {
return try SignalIOSProtoBackupSnapshotBackupEntity.parseProto(proto)
}
@objc public func buildSerializedData() throws -> Data {
return try SignalIOSProtoBackupSnapshotBackupEntity.parseProto(proto).serializedData()
}
}
fileprivate let proto: IOSProtos_BackupSnapshot.BackupEntity
@objc public let type: SignalIOSProtoBackupSnapshotBackupEntityType
@objc public let entityData: Data
@objc public let collection: String
@objc public let key: String
private init(proto: IOSProtos_BackupSnapshot.BackupEntity,
type: SignalIOSProtoBackupSnapshotBackupEntityType,
entityData: Data,
collection: String,
key: String) {
self.proto = proto
self.type = type
self.entityData = entityData
self.collection = collection
self.key = key
}
@objc
public func serializedData() throws -> Data {
return try self.proto.serializedData()
}
@objc public class func parseData(_ serializedData: Data) throws -> SignalIOSProtoBackupSnapshotBackupEntity {
let proto = try IOSProtos_BackupSnapshot.BackupEntity(serializedData: serializedData)
return try parseProto(proto)
}
fileprivate class func parseProto(_ proto: IOSProtos_BackupSnapshot.BackupEntity) throws -> SignalIOSProtoBackupSnapshotBackupEntity {
guard proto.hasType else {
throw SignalIOSProtoError.invalidProtobuf(description: "\(logTag) missing required field: type")
}
let type = SignalIOSProtoBackupSnapshotBackupEntityTypeWrap(proto.type)
guard proto.hasEntityData else {
throw SignalIOSProtoError.invalidProtobuf(description: "\(logTag) missing required field: entityData")
}
let entityData = proto.entityData
guard proto.hasCollection else {
throw SignalIOSProtoError.invalidProtobuf(description: "\(logTag) missing required field: collection")
}
let collection = proto.collection
guard proto.hasKey else {
throw SignalIOSProtoError.invalidProtobuf(description: "\(logTag) missing required field: key")
}
let key = proto.key
// MARK: - Begin Validation Logic for SignalIOSProtoBackupSnapshotBackupEntity -
// MARK: - End Validation Logic for SignalIOSProtoBackupSnapshotBackupEntity -
let result = SignalIOSProtoBackupSnapshotBackupEntity(proto: proto,
type: type,
entityData: entityData,
collection: collection,
key: key)
return result
}
@objc public override var debugDescription: String {
return "\(proto)"
}
}
#if DEBUG
extension SignalIOSProtoBackupSnapshotBackupEntity {
@objc public func serializedDataIgnoringErrors() -> Data? {
return try! self.serializedData()
}
}
extension SignalIOSProtoBackupSnapshotBackupEntity.SignalIOSProtoBackupSnapshotBackupEntityBuilder {
@objc public func buildIgnoringErrors() -> SignalIOSProtoBackupSnapshotBackupEntity? {
return try! self.build()
}
}
#endif
// MARK: - SignalIOSProtoBackupSnapshot
@objc public class SignalIOSProtoBackupSnapshot: NSObject {
// MARK: - SignalIOSProtoBackupSnapshotBuilder
@objc public class func builder() -> SignalIOSProtoBackupSnapshotBuilder {
return SignalIOSProtoBackupSnapshotBuilder()
}
// asBuilder() constructs a builder that reflects the proto's contents.
@objc public func asBuilder() -> SignalIOSProtoBackupSnapshotBuilder {
let builder = SignalIOSProtoBackupSnapshotBuilder()
builder.setEntity(entity)
return builder
}
@objc public class SignalIOSProtoBackupSnapshotBuilder: NSObject {
private var proto = IOSProtos_BackupSnapshot()
@objc fileprivate override init() {}
@objc public func addEntity(_ valueParam: SignalIOSProtoBackupSnapshotBackupEntity) {
var items = proto.entity
items.append(valueParam.proto)
proto.entity = items
}
@objc public func setEntity(_ wrappedItems: [SignalIOSProtoBackupSnapshotBackupEntity]) {
proto.entity = wrappedItems.map { $0.proto }
}
@objc public func build() throws -> SignalIOSProtoBackupSnapshot {
return try SignalIOSProtoBackupSnapshot.parseProto(proto)
}
@objc public func buildSerializedData() throws -> Data {
return try SignalIOSProtoBackupSnapshot.parseProto(proto).serializedData()
}
}
fileprivate let proto: IOSProtos_BackupSnapshot
@objc public let entity: [SignalIOSProtoBackupSnapshotBackupEntity]
private init(proto: IOSProtos_BackupSnapshot,
entity: [SignalIOSProtoBackupSnapshotBackupEntity]) {
self.proto = proto
self.entity = entity
}
@objc
public func serializedData() throws -> Data {
return try self.proto.serializedData()
}
@objc public class func parseData(_ serializedData: Data) throws -> SignalIOSProtoBackupSnapshot {
let proto = try IOSProtos_BackupSnapshot(serializedData: serializedData)
return try parseProto(proto)
}
fileprivate class func parseProto(_ proto: IOSProtos_BackupSnapshot) throws -> SignalIOSProtoBackupSnapshot {
var entity: [SignalIOSProtoBackupSnapshotBackupEntity] = []
entity = try proto.entity.map { try SignalIOSProtoBackupSnapshotBackupEntity.parseProto($0) }
// MARK: - Begin Validation Logic for SignalIOSProtoBackupSnapshot -
// MARK: - End Validation Logic for SignalIOSProtoBackupSnapshot -
let result = SignalIOSProtoBackupSnapshot(proto: proto,
entity: entity)
return result
}
@objc public override var debugDescription: String {
return "\(proto)"
}
}
#if DEBUG
extension SignalIOSProtoBackupSnapshot {
@objc public func serializedDataIgnoringErrors() -> Data? {
return try! self.serializedData()
}
}
extension SignalIOSProtoBackupSnapshot.SignalIOSProtoBackupSnapshotBuilder {
@objc public func buildIgnoringErrors() -> SignalIOSProtoBackupSnapshot? {
return try! self.build()
}
}
#endif
// MARK: - SignalIOSProtoDeviceName
@objc public class SignalIOSProtoDeviceName: NSObject {
// MARK: - SignalIOSProtoDeviceNameBuilder
@objc public class func builder(ephemeralPublic: Data, syntheticIv: Data, ciphertext: Data) -> SignalIOSProtoDeviceNameBuilder {
return SignalIOSProtoDeviceNameBuilder(ephemeralPublic: ephemeralPublic, syntheticIv: syntheticIv, ciphertext: ciphertext)
}
// asBuilder() constructs a builder that reflects the proto's contents.
@objc public func asBuilder() -> SignalIOSProtoDeviceNameBuilder {
let builder = SignalIOSProtoDeviceNameBuilder(ephemeralPublic: ephemeralPublic, syntheticIv: syntheticIv, ciphertext: ciphertext)
return builder
}
@objc public class SignalIOSProtoDeviceNameBuilder: NSObject {
private var proto = IOSProtos_DeviceName()
@objc fileprivate override init() {}
@objc fileprivate init(ephemeralPublic: Data, syntheticIv: Data, ciphertext: Data) {
super.init()
setEphemeralPublic(ephemeralPublic)
setSyntheticIv(syntheticIv)
setCiphertext(ciphertext)
}
@objc public func setEphemeralPublic(_ valueParam: Data) {
proto.ephemeralPublic = valueParam
}
@objc public func setSyntheticIv(_ valueParam: Data) {
proto.syntheticIv = valueParam
}
@objc public func setCiphertext(_ valueParam: Data) {
proto.ciphertext = valueParam
}
@objc public func build() throws -> SignalIOSProtoDeviceName {
return try SignalIOSProtoDeviceName.parseProto(proto)
}
@objc public func buildSerializedData() throws -> Data {
return try SignalIOSProtoDeviceName.parseProto(proto).serializedData()
}
}
fileprivate let proto: IOSProtos_DeviceName
@objc public let ephemeralPublic: Data
@objc public let syntheticIv: Data
@objc public let ciphertext: Data
private init(proto: IOSProtos_DeviceName,
ephemeralPublic: Data,
syntheticIv: Data,
ciphertext: Data) {
self.proto = proto
self.ephemeralPublic = ephemeralPublic
self.syntheticIv = syntheticIv
self.ciphertext = ciphertext
}
@objc
public func serializedData() throws -> Data {
return try self.proto.serializedData()
}
@objc public class func parseData(_ serializedData: Data) throws -> SignalIOSProtoDeviceName {
let proto = try IOSProtos_DeviceName(serializedData: serializedData)
return try parseProto(proto)
}
fileprivate class func parseProto(_ proto: IOSProtos_DeviceName) throws -> SignalIOSProtoDeviceName {
guard proto.hasEphemeralPublic else {
throw SignalIOSProtoError.invalidProtobuf(description: "\(logTag) missing required field: ephemeralPublic")
}
let ephemeralPublic = proto.ephemeralPublic
guard proto.hasSyntheticIv else {
throw SignalIOSProtoError.invalidProtobuf(description: "\(logTag) missing required field: syntheticIv")
}
let syntheticIv = proto.syntheticIv
guard proto.hasCiphertext else {
throw SignalIOSProtoError.invalidProtobuf(description: "\(logTag) missing required field: ciphertext")
}
let ciphertext = proto.ciphertext
// MARK: - Begin Validation Logic for SignalIOSProtoDeviceName -
// MARK: - End Validation Logic for SignalIOSProtoDeviceName -
let result = SignalIOSProtoDeviceName(proto: proto,
ephemeralPublic: ephemeralPublic,
syntheticIv: syntheticIv,
ciphertext: ciphertext)
return result
}
@objc public override var debugDescription: String {
return "\(proto)"
}
}
#if DEBUG
extension SignalIOSProtoDeviceName {
@objc public func serializedDataIgnoringErrors() -> Data? {
return try! self.serializedData()
}
}
extension SignalIOSProtoDeviceName.SignalIOSProtoDeviceNameBuilder {
@objc public func buildIgnoringErrors() -> SignalIOSProtoDeviceName? {
return try! self.build()
}
}
#endif

View File

@ -2,6 +2,7 @@
import Foundation
import SignalCoreKit
import SessionUtilitiesKit
public class SwiftSingletons: NSObject {
public static let shared = SwiftSingletons()

View File

@ -1,78 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
#ifndef TextSecureKit_Constants_h
#define TextSecureKit_Constants_h
extern const NSUInteger kOversizeTextMessageSizeThreshold;
typedef NS_ENUM(NSInteger, TSWhisperMessageType) {
TSUnknownMessageType = 0,
TSEncryptedWhisperMessageType = 1,
TSIgnoreOnIOSWhisperMessageType = 2, // on droid this is the prekey bundle message irrelevant for us
TSPreKeyWhisperMessageType = 3,
TSUnencryptedWhisperMessageType = 4,
TSUnidentifiedSenderMessageType = 6,
TSClosedGroupCiphertextMessageType = 7,
TSFallbackMessageType = 101
};
#pragma mark Server Address
#define textSecureHTTPTimeOut 10
#define kLegalTermsUrlString @"https://getsession.org/privacy-policy/"
//#ifndef DEBUG
// Production
#define textSecureWebSocketAPI @"wss://textsecure-service.whispersystems.org/v1/websocket/"
#define textSecureCDNServerURL @"https://cdn.signal.org"
// Use same reflector for service and CDN
#define textSecureServiceReflectorHost @"europe-west1-signal-cdn-reflector.cloudfunctions.net"
#define textSecureCDNReflectorHost @"europe-west1-signal-cdn-reflector.cloudfunctions.net"
#define contactDiscoveryURL @"https://api.directory.signal.org"
#define kUDTrustRoot @"BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF"
#define USING_PRODUCTION_SERVICE
//#else
// Staging
//#define textSecureWebSocketAPI @"wss://textsecure-service-staging.whispersystems.org/v1/websocket/"
//#define textSecureServerURL @"https://textsecure-service-staging.whispersystems.org/"
//#define textSecureCDNServerURL @"https://cdn-staging.signal.org"
//#define textSecureServiceReflectorHost @"meek-signal-service-staging.appspot.com";
//#define textSecureCDNReflectorHost @"meek-signal-cdn-staging.appspot.com";
//#define contactDiscoveryURL @"https://api-staging.directory.signal.org"
//#define kUDTrustRoot @"BbqY1DzohE4NUZoVF+L18oUPrK3kILllLEJh2UnPSsEx"
//#endif
BOOL IsUsingProductionService(void);
#define textSecureAccountsAPI @"v1/accounts"
#define textSecureAttributesAPI @"/attributes/"
#define textSecureMessagesAPI @"v1/messages/"
#define textSecureKeysAPI @"v2/keys"
#define textSecureSignedKeysAPI @"v2/keys/signed"
#define textSecureDirectoryAPI @"v1/directory"
#define textSecureAttachmentsAPI @"v1/attachments"
#define textSecureDeviceProvisioningCodeAPI @"v1/devices/provisioning/code"
#define textSecureDeviceProvisioningAPIFormat @"v1/provisioning/%@"
#define textSecureDevicesAPIFormat @"v1/devices/%@"
#define textSecureProfileAPIFormat @"v1/profile/%@"
#define textSecureSetProfileNameAPIFormat @"v1/profile/name/%@"
#define textSecureProfileAvatarFormAPI @"v1/profile/form/avatar"
#define textSecure2FAAPI @"/v1/accounts/pin"
#define SignalApplicationGroup @"group.com.loki-project.loki-messenger"
#endif
NS_ASSUME_NONNULL_END

View File

@ -1,20 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import "TSConstants.h"
NS_ASSUME_NONNULL_BEGIN
const NSUInteger kOversizeTextMessageSizeThreshold = 2 * 1024;
BOOL IsUsingProductionService()
{
#ifdef USING_PRODUCTION_SERVICE
return YES;
#else
return NO;
#endif
}
NS_ASSUME_NONNULL_END

View File

@ -3,6 +3,7 @@
import Foundation
import SessionUIKit
import SignalCoreKit
import SessionUtilitiesKit
public extension UIEdgeInsets {
init(top: CGFloat, leading: CGFloat, bottom: CGFloat, trailing: CGFloat) {

View File

@ -2,6 +2,7 @@
import UIKit
import SessionUIKit
import SessionUtilitiesKit
public extension UIViewController {
func findFrontmostViewController(ignoringAlerts: Bool) -> UIViewController {