From 45e782c243aafec6476066817236707427197336 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 2 Aug 2018 15:18:40 -0400 Subject: [PATCH 1/6] Revamp orphan data cleaner. --- Signal.xcodeproj/project.pbxproj | 281 ++++--- Signal/src/AppDelegate.m | 11 +- Signal/src/Jobs/SyncPushTokensJob.swift | 4 +- .../DebugUI/DebugUIDiskUsage.m | 6 +- Signal/src/util/MainAppContext.m | 52 ++ Signal/src/util/OWSOrphanDataCleaner.h | 21 + Signal/src/util/OWSOrphanDataCleaner.m | 683 ++++++++++++++++++ SignalMessaging/environment/AppSetup.m | 1 + SignalMessaging/environment/Environment.m | 2 +- .../environment/VersionMigrations.m | 4 +- SignalMessaging/profiles/OWSUserProfile.h | 1 + SignalMessaging/profiles/OWSUserProfile.m | 28 + SignalMessaging/views/OWSAlerts.swift | 2 +- .../Attachments/OWSAttachmentsProcessor.m | 5 +- .../Messages/Attachments/TSAttachmentStream.h | 3 + .../src/Messages/Interactions/TSInteraction.m | 4 - .../src/Messages/OWSBatchMessageProcessor.m | 3 +- .../src/Messages/OWSDisappearingMessagesJob.m | 6 +- .../src/Messages/OWSMessageReceiver.m | 4 +- .../src/Network/WebSockets/TSSocketManager.m | 5 +- .../src/Storage/OWSIncomingMessageFinder.m | 2 +- .../src/Storage/OWSOrphanedDataCleaner.h | 30 - .../src/Storage/OWSOrphanedDataCleaner.m | 286 -------- SignalServiceKit/src/Util/AppContext.h | 3 + SignalServiceKit/src/Util/AppReadiness.m | 12 +- SignalServiceKit/src/Util/AppVersion.h | 22 +- SignalServiceKit/src/Util/AppVersion.m | 26 +- .../ShareViewController.swift | 6 +- .../utils/ShareAppExtensionContext.m | 5 + 29 files changed, 1011 insertions(+), 507 deletions(-) create mode 100644 Signal/src/util/OWSOrphanDataCleaner.h create mode 100644 Signal/src/util/OWSOrphanDataCleaner.m delete mode 100644 SignalServiceKit/src/Storage/OWSOrphanedDataCleaner.h delete mode 100644 SignalServiceKit/src/Storage/OWSOrphanedDataCleaner.m diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index f406974082..299b140fc0 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -35,12 +35,7 @@ 340FC8BB204DAC8D007AEB0F /* OWSAddToContactViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8A1204DAC8D007AEB0F /* OWSAddToContactViewController.m */; }; 340FC8BC204DAC8D007AEB0F /* FingerprintViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8A2204DAC8D007AEB0F /* FingerprintViewController.m */; }; 340FC8BD204DAC8D007AEB0F /* ShowGroupMembersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8A6204DAC8D007AEB0F /* ShowGroupMembersViewController.m */; }; - 340FC8C0204DB7D2007AEB0F /* OWSBackupExportJob.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8BF204DB7D2007AEB0F /* OWSBackupExportJob.m */; }; 340FC8C5204DE223007AEB0F /* DebugUIBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8C4204DE223007AEB0F /* DebugUIBackup.m */; }; - 340FC8C7204DE64D007AEB0F /* OWSBackupAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8C6204DE64D007AEB0F /* OWSBackupAPI.swift */; }; - 340FC8CA20517B84007AEB0F /* OWSBackupImportJob.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8C820517B84007AEB0F /* OWSBackupImportJob.m */; }; - 340FC8CD20518C77007AEB0F /* OWSBackupJob.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8CC20518C76007AEB0F /* OWSBackupJob.m */; }; - 340FC8D0205BF2FA007AEB0F /* OWSBackupIO.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8CE205BF2FA007AEB0F /* OWSBackupIO.m */; }; 341F2C0F1F2B8AE700D07D6B /* DebugUIMisc.m in Sources */ = {isa = PBXBuildFile; fileRef = 341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */; }; 34219801210612F600C57195 /* iRate.m in Sources */ = {isa = PBXBuildFile; fileRef = 342197FF210612F600C57195 /* iRate.m */; }; 3421980F21061A0700C57195 /* UIColor+JSQMessages.m in Sources */ = {isa = PBXBuildFile; fileRef = 3421980521061A0600C57195 /* UIColor+JSQMessages.m */; }; @@ -81,6 +76,29 @@ 34480B641FD0A98800BC14EF /* UIView+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 34480B601FD0A98800BC14EF /* UIView+OWS.m */; }; 34480B671FD0AA9400BC14EF /* UIFont+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 34480B651FD0AA9400BC14EF /* UIFont+OWS.m */; }; 34480B681FD0AA9400BC14EF /* UIFont+OWS.h in Headers */ = {isa = PBXBuildFile; fileRef = 34480B661FD0AA9400BC14EF /* UIFont+OWS.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3448259D21138BAF00DB4BD8 /* AppUpdateNag.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448255321138BAE00DB4BD8 /* AppUpdateNag.m */; }; + 3448259E21138BAF00DB4BD8 /* RegistrationUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448255521138BAE00DB4BD8 /* RegistrationUtils.m */; }; + 3448259F21138BAF00DB4BD8 /* OWSBackupExportJob.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448255621138BAE00DB4BD8 /* OWSBackupExportJob.m */; }; + 344825A021138BAF00DB4BD8 /* OWSBackupLazyRestoreJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448255921138BAE00DB4BD8 /* OWSBackupLazyRestoreJob.swift */; }; + 344825A121138BAF00DB4BD8 /* Pastelog.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448255A21138BAE00DB4BD8 /* Pastelog.m */; }; + 344825A221138BAF00DB4BD8 /* OWSScreenLockUI.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448255B21138BAE00DB4BD8 /* OWSScreenLockUI.m */; }; + 344825A921138BAF00DB4BD8 /* UIResponder+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448256B21138BAE00DB4BD8 /* UIResponder+OWS.swift */; }; + 344825AB21138BAF00DB4BD8 /* FunctionalUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448256D21138BAE00DB4BD8 /* FunctionalUtil.m */; }; + 344825AD21138BAF00DB4BD8 /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448256F21138BAE00DB4BD8 /* DateUtil.m */; }; + 344825B121138BAF00DB4BD8 /* TextFieldHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448257421138BAE00DB4BD8 /* TextFieldHelper.swift */; }; + 344825B321138BAF00DB4BD8 /* OWSBackupIO.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448257721138BAE00DB4BD8 /* OWSBackupIO.m */; }; + 344825B421138BAF00DB4BD8 /* OWSBackupImportJob.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448257821138BAE00DB4BD8 /* OWSBackupImportJob.m */; }; + 344825B621138BAF00DB4BD8 /* UIViewController+Permissions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448258021138BAE00DB4BD8 /* UIViewController+Permissions.m */; }; + 344825B721138BAF00DB4BD8 /* OWSBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448258321138BAE00DB4BD8 /* OWSBackup.m */; }; + 344825B821138BAF00DB4BD8 /* MainAppContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448258521138BAE00DB4BD8 /* MainAppContext.m */; }; + 344825B921138BAF00DB4BD8 /* NSString+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448258721138BAE00DB4BD8 /* NSString+OWS.m */; }; + 344825BA21138BAF00DB4BD8 /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448258A21138BAE00DB4BD8 /* Platform.swift */; }; + 344825BB21138BAF00DB4BD8 /* OWSOrphanDataCleaner.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448258B21138BAE00DB4BD8 /* OWSOrphanDataCleaner.m */; }; + 344825BC21138BAF00DB4BD8 /* AppStoreRating.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448258C21138BAE00DB4BD8 /* AppStoreRating.m */; }; + 344825BD21138BAF00DB4BD8 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3448258D21138BAE00DB4BD8 /* Launch Screen.storyboard */; }; + 344825C021138BAF00DB4BD8 /* OWSAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448259421138BAE00DB4BD8 /* OWSAnalytics.swift */; }; + 344825C221138BAF00DB4BD8 /* OWSBackupJob.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448259821138BAE00DB4BD8 /* OWSBackupJob.m */; }; + 344825C321138BAF00DB4BD8 /* OWSBackupAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448259921138BAE00DB4BD8 /* OWSBackupAPI.swift */; }; 344D6CEA20069E070042AF96 /* SelectRecipientViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 344D6CE620069E060042AF96 /* SelectRecipientViewController.h */; }; 344D6CEB20069E070042AF96 /* SelectRecipientViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 344D6CE720069E060042AF96 /* SelectRecipientViewController.m */; }; 344D6CEC20069E070042AF96 /* NewNonContactConversationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 344D6CE820069E070042AF96 /* NewNonContactConversationViewController.m */; }; @@ -180,10 +198,8 @@ 3496744D2076768700080B5F /* OWSMessageBubbleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3496744C2076768700080B5F /* OWSMessageBubbleView.m */; }; 3496744F2076ACD000080B5F /* LongTextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3496744E2076ACCE00080B5F /* LongTextViewController.swift */; }; 34A55F3720485465002CC6DE /* OWS2FARegistrationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */; }; - 34A910601FFEB114000C4745 /* OWSBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A9105F1FFEB114000C4745 /* OWSBackup.m */; }; 34ABB2C42090C59700C727A6 /* OWSResaveCollectionDBMigration.m in Sources */ = {isa = PBXBuildFile; fileRef = 34ABB2C22090C59600C727A6 /* OWSResaveCollectionDBMigration.m */; }; 34ABB2C52090C59700C727A6 /* OWSResaveCollectionDBMigration.h in Headers */ = {isa = PBXBuildFile; fileRef = 34ABB2C32090C59700C727A6 /* OWSResaveCollectionDBMigration.h */; }; - 34B0796D1FCF46B100E248C2 /* MainAppContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B0796B1FCF46B000E248C2 /* MainAppContext.m */; }; 34B3F8751E8DF1700035BE1A /* CallViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F83B1E8DF1700035BE1A /* CallViewController.swift */; }; 34B3F8771E8DF1700035BE1A /* ContactsPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F83E1E8DF1700035BE1A /* ContactsPicker.swift */; }; 34B3F87B1E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8441E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift */; }; @@ -207,7 +223,6 @@ 34C82E5120F8E1F300E9688D /* Theme.h in Headers */ = {isa = PBXBuildFile; fileRef = 34C82E4F20F8E1F000E9688D /* Theme.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34C82E5220F8E1F300E9688D /* Theme.m in Sources */ = {isa = PBXBuildFile; fileRef = 34C82E5020F8E1F100E9688D /* Theme.m */; }; 34CA631B2097806F00E526A0 /* OWSContactShareView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CA631A2097806E00E526A0 /* OWSContactShareView.m */; }; - 34CCAF381F0C0599004084F4 /* AppUpdateNag.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CCAF371F0C0599004084F4 /* AppUpdateNag.m */; }; 34CE88E71F2FB9A10098030F /* ProfileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CE88E61F2FB9A10098030F /* ProfileViewController.m */; }; 34CF0787203E6B78005C4D61 /* busy_tone_ansi.caf in Resources */ = {isa = PBXBuildFile; fileRef = 34CF0783203E6B77005C4D61 /* busy_tone_ansi.caf */; }; 34CF0788203E6B78005C4D61 /* ringback_tone_ansi.caf in Resources */ = {isa = PBXBuildFile; fileRef = 34CF0784203E6B77005C4D61 /* ringback_tone_ansi.caf */; }; @@ -230,8 +245,6 @@ 34D1F0C01F8EC1760066283D /* MessageRecipientStatusUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D1F0BF1F8EC1760066283D /* MessageRecipientStatusUtils.swift */; }; 34D2015120DC160E00A6FD3A /* ContactCellView.h in Headers */ = {isa = PBXBuildFile; fileRef = 34D2014F20DC160D00A6FD3A /* ContactCellView.h */; }; 34D2015220DC160E00A6FD3A /* ContactCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D2015020DC160D00A6FD3A /* ContactCellView.m */; }; - 34D2CCD220618B3000CB1A14 /* OWSBackupLazyRestoreJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D2CCD120618B2F00CB1A14 /* OWSBackupLazyRestoreJob.swift */; }; - 34D2CCDA2062E7D000CB1A14 /* OWSScreenLockUI.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D2CCD92062E7D000CB1A14 /* OWSScreenLockUI.m */; }; 34D2CCDF206939B400CB1A14 /* DebugUIMessagesAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D2CCDB206939B100CB1A14 /* DebugUIMessagesAction.m */; }; 34D2CCE0206939B400CB1A14 /* DebugUIMessagesAssetLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D2CCDC206939B200CB1A14 /* DebugUIMessagesAssetLoader.m */; }; 34D5872F208E2C4200D2255A /* OWS109OutgoingMessageState.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D5872D208E2C4100D2255A /* OWS109OutgoingMessageState.m */; }; @@ -241,7 +254,6 @@ 34D8C0281ED3673300188D7C /* DebugUITableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D8C0261ED3673300188D7C /* DebugUITableViewController.m */; }; 34D8C02B1ED3685800188D7C /* DebugUIContacts.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D8C02A1ED3685800188D7C /* DebugUIContacts.m */; }; 34D920E720E179C200D51158 /* OWSMessageFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D920E620E179C200D51158 /* OWSMessageFooterView.m */; }; - 34D99C931F2937CC00D284D6 /* OWSAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */; }; 34DB0BED2011548B007B313F /* OWSDatabaseConverterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DB0BEC2011548B007B313F /* OWSDatabaseConverterTest.m */; }; 34DBF003206BD5A500025978 /* OWSMessageTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DBEFFF206BD5A400025978 /* OWSMessageTextView.m */; }; 34DBF004206BD5A500025978 /* OWSBubbleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DBF001206BD5A500025978 /* OWSBubbleView.m */; }; @@ -249,7 +261,6 @@ 34E3E5681EC4B19400495BAC /* AudioProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E3E5671EC4B19400495BAC /* AudioProgressView.swift */; }; 34E3EF0D1EFC235B007F6822 /* DebugUIDiskUsage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */; }; 34E3EF101EFC2684007F6822 /* DebugUIPage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E3EF0F1EFC2684007F6822 /* DebugUIPage.m */; }; - 34E5DC8220D8050D00C08145 /* RegistrationUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E5DC8120D8050D00C08145 /* RegistrationUtils.m */; }; 34E88D262098C5AE00A608F4 /* ContactViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E88D252098C5AE00A608F4 /* ContactViewController.swift */; }; 34E8A8D12085238A00B272B1 /* ProtoParsingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E8A8D02085238900B272B1 /* ProtoParsingTest.m */; }; 34F308A21ECB469700BB7697 /* OWSBezierPathView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F308A11ECB469700BB7697 /* OWSBezierPathView.m */; }; @@ -271,7 +282,6 @@ 450C801120AD1CDB00F3A091 /* ReturnToCallViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A60E7220AC674100FB1ABF /* ReturnToCallViewController.swift */; }; 450C801220AD1D5B00F3A091 /* UIDevice+featureSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45BB93371E688E14001E3939 /* UIDevice+featureSupport.swift */; }; 450D19131F85236600970622 /* RemoteVideoView.m in Sources */ = {isa = PBXBuildFile; fileRef = 450D19121F85236600970622 /* RemoteVideoView.m */; }; - 450DF2051E0D74AC003D14BE /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 450DF2041E0D74AC003D14BE /* Platform.swift */; }; 450DF2091E0DD2C6003D14BE /* UserNotificationsAdaptee.swift in Sources */ = {isa = PBXBuildFile; fileRef = 450DF2081E0DD2C6003D14BE /* UserNotificationsAdaptee.swift */; }; 451166C01FD86B98000739BA /* AccountManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 451166BF1FD86B98000739BA /* AccountManager.swift */; }; 451573962061B49500803601 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 451573952061B49500803601 /* GradientView.swift */; }; @@ -311,7 +321,6 @@ 451F8A4B1FD715E1005CB9DA /* OWSGroupAvatarBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 45666EC71D994C0D008FE134 /* OWSGroupAvatarBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 452037D11EE84975004E4CDF /* DebugUISessionState.m in Sources */ = {isa = PBXBuildFile; fileRef = 452037D01EE84975004E4CDF /* DebugUISessionState.m */; }; 4520D8D51D417D8E00123472 /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4520D8D41D417D8E00123472 /* Photos.framework */; }; - 4521C3C01F59F3BA00B4C582 /* TextFieldHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4521C3BF1F59F3BA00B4C582 /* TextFieldHelper.swift */; }; 452314A01F7E9E18003A428C /* DirectionalPanGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4523149F1F7E9E18003A428C /* DirectionalPanGestureRecognizer.swift */; }; 4523D016206EDC2B00A2AB51 /* LRUCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4523D015206EDC2B00A2AB51 /* LRUCache.swift */; }; 452B999020A34B6B006F2F9E /* AddContactShareToExistingContactViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 452B998F20A34B6B006F2F9E /* AddContactShareToExistingContactViewController.swift */; }; @@ -340,20 +349,17 @@ 454A965A1FD6017E008D2A0E /* SignalAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D913491F62D4A500722898 /* SignalAttachment.swift */; }; 454A965B1FD601BF008D2A0E /* MediaMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34CA1C281F7164F700E51C51 /* MediaMessageView.swift */; }; 454A965F1FD60EA3008D2A0E /* OWSFlatButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 454A965E1FD60EA2008D2A0E /* OWSFlatButton.swift */; }; - 454EBAB41F2BE14C00ACE0BB /* OWSAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */; }; 4551DB5A205C562300C8AE75 /* Collection+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4551DB59205C562300C8AE75 /* Collection+OWS.swift */; }; 4556FA681F54AA9500AF40DD /* DebugUIProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4556FA671F54AA9500AF40DD /* DebugUIProfile.swift */; }; 455A16DD1F1FEA0000F86704 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 455A16DB1F1FEA0000F86704 /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 455A16DE1F1FEA0000F86704 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 455A16DC1F1FEA0000F86704 /* MetalKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 455AC69E1F4F8B0300134004 /* ImageCacheTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 455AC69D1F4F8B0300134004 /* ImageCacheTest.swift */; }; 45638BDC1F3DD0D400128435 /* DebugUICalling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45638BDB1F3DD0D400128435 /* DebugUICalling.swift */; }; - 45638BDF1F3DDB2200128435 /* MessageSender+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45638BDE1F3DDB2200128435 /* MessageSender+Promise.swift */; }; 4565ED06200EA29900C46DBB /* VideoPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453034AA200289F50018945D /* VideoPlayerView.swift */; }; 45666F581D9B2880008FE134 /* OWSScrubbingLogFormatterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 45666F571D9B2880008FE134 /* OWSScrubbingLogFormatterTest.m */; }; 456C38961DC7B882007536A7 /* PromiseKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 451DE9F11DC1585F00810E42 /* PromiseKit.framework */; }; 456F6E2F1E261D1000FD2210 /* PeerConnectionClientTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 456F6E2E1E261D1000FD2210 /* PeerConnectionClientTest.swift */; }; 4574A5D61DD6704700C6B692 /* CallService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4574A5D51DD6704700C6B692 /* CallService.swift */; }; - 4579431E1E7C8CE9008ED0C0 /* Pastelog.m in Sources */ = {isa = PBXBuildFile; fileRef = 4579431D1E7C8CE9008ED0C0 /* Pastelog.m */; }; 45794E861E00620000066731 /* CallUIAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45794E851E00620000066731 /* CallUIAdapter.swift */; }; 457C87B82032645C008D52D6 /* DebugUINotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 457C87B72032645C008D52D6 /* DebugUINotifications.swift */; }; 457F671B20746193000EABCD /* QuotedReplyPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 457F671A20746193000EABCD /* QuotedReplyPreview.swift */; }; @@ -374,7 +380,6 @@ 45A6DAD61EBBF85500893231 /* ReminderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A6DAD51EBBF85500893231 /* ReminderView.swift */; }; 45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */; }; 45B27B862037FFB400A539DF /* DebugUIFileBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B27B852037FFB400A539DF /* DebugUIFileBrowser.swift */; }; - 45B5360E206DD8BB00D61655 /* UIResponder+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B5360D206DD8BB00D61655 /* UIResponder+OWS.swift */; }; 45B74A742044AAB600CD42F8 /* aurora-quiet.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 45B74A5B2044AAB300CD42F8 /* aurora-quiet.aifc */; }; 45B74A752044AAB600CD42F8 /* synth-quiet.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 45B74A5C2044AAB300CD42F8 /* synth-quiet.aifc */; }; 45B74A762044AAB600CD42F8 /* keys-quiet.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 45B74A5D2044AAB400CD42F8 /* keys-quiet.aifc */; }; @@ -402,8 +407,6 @@ 45BC829D1FD9C4B400011CF3 /* ShareViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45BC829C1FD9C4B400011CF3 /* ShareViewDelegate.swift */; }; 45BD60821DE9547E00A8F436 /* Contacts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45BD60811DE9547E00A8F436 /* Contacts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 45BE4EA22012AD2000935E59 /* DisappearingTimerConfigurationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45BE4EA12012AD2000935E59 /* DisappearingTimerConfigurationView.swift */; }; - 45C0DC1B1E68FE9000E04C47 /* UIApplication+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C0DC1A1E68FE9000E04C47 /* UIApplication+OWS.swift */; }; - 45C0DC1E1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */; }; 45C9DEB81DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C9DEB71DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift */; }; 45CB2FA81CB7146C00E1B343 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 45CB2FA71CB7146C00E1B343 /* Launch Screen.storyboard */; }; 45CD81EF1DC030E7004C9430 /* SyncPushTokensJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45CD81EE1DC030E7004C9430 /* SyncPushTokensJob.swift */; }; @@ -443,7 +446,6 @@ 768A1A2B17FC9CD300E00ED8 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 768A1A2A17FC9CD300E00ED8 /* libz.dylib */; }; 76C87F19181EFCE600C4ACAB /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */; }; 76EB054018170B33006006FC /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB03C318170B33006006FC /* AppDelegate.m */; }; - 76EB063A18170B33006006FC /* FunctionalUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04EB18170B33006006FC /* FunctionalUtil.m */; }; 954AEE6A1DF33E01002E5410 /* ContactsPickerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954AEE681DF33D32002E5410 /* ContactsPickerTest.swift */; }; A10FDF79184FB4BB007FF963 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */; }; A11CD70D17FA230600A2D1B1 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A11CD70C17FA230600A2D1B1 /* QuartzCore.framework */; }; @@ -483,16 +485,13 @@ B660F6DB1C29868000687D6E /* FunctionalUtilTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6AD1C29868000687D6E /* FunctionalUtilTest.m */; }; B660F6E01C29868000687D6E /* UtilTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6B41C29868000687D6E /* UtilTest.m */; }; B660F7561C29988E00687D6E /* PushManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B9ECFB198B31BA00C620D3 /* PushManager.m */; }; - B660F7721C29988E00687D6E /* AppStoreRating.m in Sources */ = {isa = PBXBuildFile; fileRef = B6DA6B061B8A2F9A00CA6F98 /* AppStoreRating.m */; }; B66DBF4A19D5BBC8006EA940 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B66DBF4919D5BBC8006EA940 /* Images.xcassets */; }; B67EBF5D19194AC60084CCFD /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B67EBF5C19194AC60084CCFD /* Settings.bundle */; }; B69CD25119773E79005CE69A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B69CD25019773E79005CE69A /* XCTest.framework */; }; B6B226971BE4B7D200860F4D /* ContactsUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6B226961BE4B7D200860F4D /* ContactsUI.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; B6B9ECFC198B31BA00C620D3 /* PushManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B9ECFB198B31BA00C620D3 /* PushManager.m */; }; - B6DA6B071B8A2F9A00CA6F98 /* AppStoreRating.m in Sources */ = {isa = PBXBuildFile; fileRef = B6DA6B061B8A2F9A00CA6F98 /* AppStoreRating.m */; }; B6F509971AA53F760068F56A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B6F509951AA53F760068F56A /* Localizable.strings */; }; B6FE7EB71ADD62FA00A6D22F /* PushKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6FE7EB61ADD62FA00A6D22F /* PushKit.framework */; }; - B90418E6183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; }; B9EB5ABD1884C002007CBB57 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9EB5ABC1884C002007CBB57 /* MessageUI.framework */; }; BFF3FB9730634F37D25903F4 /* Pods_Signal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D17BB5C25D615AB49813100C /* Pods_Signal.framework */; }; CC875800737563D6891B741D /* Pods_SignalTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 748A5CAEDD7C919FC64C6807 /* Pods_SignalTests.framework */; }; @@ -511,7 +510,6 @@ D24B5BD5169F568C00681372 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D24B5BD4169F568C00681372 /* AudioToolbox.framework */; }; D2AEACDC16C426DA00C364C0 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2AEACDB16C426DA00C364C0 /* CFNetwork.framework */; }; E1368CBE18A1C36B00109378 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9EB5ABC1884C002007CBB57 /* MessageUI.framework */; }; - EF764C351DB67CC5000D9A87 /* UIViewController+Permissions.m in Sources */ = {isa = PBXBuildFile; fileRef = EF764C341DB67CC5000D9A87 /* UIViewController+Permissions.m */; }; FC3BD9881A30A790005B96BB /* Social.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC3BD9871A30A790005B96BB /* Social.framework */; }; FC5CDF391A3393DD00B47253 /* error_white@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC5CDF371A3393DD00B47253 /* error_white@2x.png */; }; FC5CDF3A1A3393DD00B47253 /* warning_white@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC5CDF381A3393DD00B47253 /* warning_white@2x.png */; }; @@ -646,17 +644,8 @@ 340FC8A4204DAC8D007AEB0F /* AddToGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddToGroupViewController.h; sourceTree = ""; }; 340FC8A5204DAC8D007AEB0F /* FingerprintViewScanController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FingerprintViewScanController.h; sourceTree = ""; }; 340FC8A6204DAC8D007AEB0F /* ShowGroupMembersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShowGroupMembersViewController.m; sourceTree = ""; }; - 340FC8BE204DB7D1007AEB0F /* OWSBackupExportJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupExportJob.h; sourceTree = ""; }; - 340FC8BF204DB7D2007AEB0F /* OWSBackupExportJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupExportJob.m; sourceTree = ""; }; 340FC8C3204DE223007AEB0F /* DebugUIBackup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIBackup.h; sourceTree = ""; }; 340FC8C4204DE223007AEB0F /* DebugUIBackup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIBackup.m; sourceTree = ""; }; - 340FC8C6204DE64D007AEB0F /* OWSBackupAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSBackupAPI.swift; sourceTree = ""; }; - 340FC8C820517B84007AEB0F /* OWSBackupImportJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupImportJob.m; sourceTree = ""; }; - 340FC8C920517B84007AEB0F /* OWSBackupImportJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupImportJob.h; sourceTree = ""; }; - 340FC8CB20518C76007AEB0F /* OWSBackupJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupJob.h; sourceTree = ""; }; - 340FC8CC20518C76007AEB0F /* OWSBackupJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupJob.m; sourceTree = ""; }; - 340FC8CE205BF2FA007AEB0F /* OWSBackupIO.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupIO.m; sourceTree = ""; }; - 340FC8CF205BF2FA007AEB0F /* OWSBackupIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupIO.h; sourceTree = ""; }; 341458471FBE11C4005ABCF9 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = translations/fa.lproj/Localizable.strings; sourceTree = ""; }; 341F2C0D1F2B8AE700D07D6B /* DebugUIMisc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIMisc.h; sourceTree = ""; }; 341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIMisc.m; sourceTree = ""; }; @@ -712,6 +701,45 @@ 34480B601FD0A98800BC14EF /* UIView+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+OWS.m"; sourceTree = ""; }; 34480B651FD0AA9400BC14EF /* UIFont+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+OWS.m"; sourceTree = ""; }; 34480B661FD0AA9400BC14EF /* UIFont+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+OWS.h"; sourceTree = ""; }; + 3448255321138BAE00DB4BD8 /* AppUpdateNag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppUpdateNag.m; sourceTree = ""; }; + 3448255421138BAE00DB4BD8 /* UIViewController+Permissions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+Permissions.h"; sourceTree = ""; }; + 3448255521138BAE00DB4BD8 /* RegistrationUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegistrationUtils.m; sourceTree = ""; }; + 3448255621138BAE00DB4BD8 /* OWSBackupExportJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupExportJob.m; sourceTree = ""; }; + 3448255721138BAE00DB4BD8 /* AppStoreRating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppStoreRating.h; sourceTree = ""; }; + 3448255821138BAE00DB4BD8 /* OWSOrphanDataCleaner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSOrphanDataCleaner.h; sourceTree = ""; }; + 3448255921138BAE00DB4BD8 /* OWSBackupLazyRestoreJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSBackupLazyRestoreJob.swift; sourceTree = ""; }; + 3448255A21138BAE00DB4BD8 /* Pastelog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Pastelog.m; sourceTree = ""; }; + 3448255B21138BAE00DB4BD8 /* OWSScreenLockUI.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSScreenLockUI.m; sourceTree = ""; }; + 3448256821138BAE00DB4BD8 /* MainAppContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainAppContext.h; sourceTree = ""; }; + 3448256921138BAE00DB4BD8 /* OWSBackup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackup.h; sourceTree = ""; }; + 3448256B21138BAE00DB4BD8 /* UIResponder+OWS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIResponder+OWS.swift"; sourceTree = ""; }; + 3448256D21138BAE00DB4BD8 /* FunctionalUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FunctionalUtil.m; sourceTree = ""; }; + 3448256F21138BAE00DB4BD8 /* DateUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DateUtil.m; sourceTree = ""; }; + 3448257421138BAE00DB4BD8 /* TextFieldHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldHelper.swift; sourceTree = ""; }; + 3448257721138BAE00DB4BD8 /* OWSBackupIO.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupIO.m; sourceTree = ""; }; + 3448257821138BAE00DB4BD8 /* OWSBackupImportJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupImportJob.m; sourceTree = ""; }; + 3448257921138BAE00DB4BD8 /* UIViewController+CameraPermissions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+CameraPermissions.h"; sourceTree = ""; }; + 3448257A21138BAE00DB4BD8 /* OWSBackupJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupJob.h; sourceTree = ""; }; + 3448257E21138BAE00DB4BD8 /* OWSBackupExportJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupExportJob.h; sourceTree = ""; }; + 3448257F21138BAE00DB4BD8 /* RegistrationUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegistrationUtils.h; sourceTree = ""; }; + 3448258021138BAE00DB4BD8 /* UIViewController+Permissions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+Permissions.m"; sourceTree = ""; }; + 3448258121138BAE00DB4BD8 /* AppUpdateNag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppUpdateNag.h; sourceTree = ""; }; + 3448258321138BAE00DB4BD8 /* OWSBackup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackup.m; sourceTree = ""; }; + 3448258521138BAE00DB4BD8 /* MainAppContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainAppContext.m; sourceTree = ""; }; + 3448258721138BAE00DB4BD8 /* NSString+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+OWS.m"; sourceTree = ""; }; + 3448258821138BAE00DB4BD8 /* OWSScreenLockUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSScreenLockUI.h; sourceTree = ""; }; + 3448258921138BAE00DB4BD8 /* Pastelog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pastelog.h; sourceTree = ""; }; + 3448258A21138BAE00DB4BD8 /* Platform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Platform.swift; sourceTree = ""; }; + 3448258B21138BAE00DB4BD8 /* OWSOrphanDataCleaner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSOrphanDataCleaner.m; sourceTree = ""; }; + 3448258C21138BAE00DB4BD8 /* AppStoreRating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppStoreRating.m; sourceTree = ""; }; + 3448258D21138BAE00DB4BD8 /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = ""; }; + 3448259221138BAE00DB4BD8 /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = ""; }; + 3448259421138BAE00DB4BD8 /* OWSAnalytics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSAnalytics.swift; sourceTree = ""; }; + 3448259521138BAE00DB4BD8 /* FunctionalUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionalUtil.h; sourceTree = ""; }; + 3448259821138BAE00DB4BD8 /* OWSBackupJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupJob.m; sourceTree = ""; }; + 3448259921138BAE00DB4BD8 /* OWSBackupAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSBackupAPI.swift; sourceTree = ""; }; + 3448259A21138BAE00DB4BD8 /* OWSBackupImportJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupImportJob.h; sourceTree = ""; }; + 3448259B21138BAE00DB4BD8 /* OWSBackupIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupIO.h; sourceTree = ""; }; 34491FC11FB0F78500B3E5A3 /* my */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = my; path = translations/my.lproj/Localizable.strings; sourceTree = ""; }; 344D6CE620069E060042AF96 /* SelectRecipientViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SelectRecipientViewController.h; path = SignalMessaging/contacts/SelectRecipientViewController.h; sourceTree = SOURCE_ROOT; }; 344D6CE720069E060042AF96 /* SelectRecipientViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SelectRecipientViewController.m; path = SignalMessaging/contacts/SelectRecipientViewController.m; sourceTree = SOURCE_ROOT; }; @@ -820,12 +848,8 @@ 3496744E2076ACCE00080B5F /* LongTextViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LongTextViewController.swift; sourceTree = ""; }; 34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWS2FARegistrationViewController.m; sourceTree = ""; }; 34A55F3620485464002CC6DE /* OWS2FARegistrationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWS2FARegistrationViewController.h; sourceTree = ""; }; - 34A9105E1FFEB113000C4745 /* OWSBackup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackup.h; sourceTree = ""; }; - 34A9105F1FFEB114000C4745 /* OWSBackup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackup.m; sourceTree = ""; }; 34ABB2C22090C59600C727A6 /* OWSResaveCollectionDBMigration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSResaveCollectionDBMigration.m; sourceTree = ""; }; 34ABB2C32090C59700C727A6 /* OWSResaveCollectionDBMigration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSResaveCollectionDBMigration.h; sourceTree = ""; }; - 34B0796B1FCF46B000E248C2 /* MainAppContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainAppContext.m; sourceTree = ""; }; - 34B0796C1FCF46B000E248C2 /* MainAppContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainAppContext.h; sourceTree = ""; }; 34B0796E1FD07B1E00E248C2 /* SignalShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SignalShareExtension.entitlements; sourceTree = ""; }; 34B3F8391E8DF1700035BE1A /* AttachmentSharing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AttachmentSharing.h; sourceTree = ""; }; 34B3F83A1E8DF1700035BE1A /* AttachmentSharing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AttachmentSharing.m; sourceTree = ""; }; @@ -867,8 +891,6 @@ 34CA1C281F7164F700E51C51 /* MediaMessageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaMessageView.swift; sourceTree = ""; }; 34CA63192097806E00E526A0 /* OWSContactShareView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSContactShareView.h; sourceTree = ""; }; 34CA631A2097806E00E526A0 /* OWSContactShareView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactShareView.m; sourceTree = ""; }; - 34CCAF361F0C0599004084F4 /* AppUpdateNag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppUpdateNag.h; sourceTree = ""; }; - 34CCAF371F0C0599004084F4 /* AppUpdateNag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppUpdateNag.m; sourceTree = ""; }; 34CE88E51F2FB9A10098030F /* ProfileViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProfileViewController.h; sourceTree = ""; }; 34CE88E61F2FB9A10098030F /* ProfileViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProfileViewController.m; sourceTree = ""; }; 34CF0783203E6B77005C4D61 /* busy_tone_ansi.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = busy_tone_ansi.caf; path = Signal/AudioFiles/busy_tone_ansi.caf; sourceTree = SOURCE_ROOT; }; @@ -905,9 +927,6 @@ 34D1F0BF1F8EC1760066283D /* MessageRecipientStatusUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageRecipientStatusUtils.swift; sourceTree = ""; }; 34D2014F20DC160D00A6FD3A /* ContactCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContactCellView.h; path = SignalMessaging/Views/ContactCellView.h; sourceTree = SOURCE_ROOT; }; 34D2015020DC160D00A6FD3A /* ContactCellView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ContactCellView.m; path = SignalMessaging/Views/ContactCellView.m; sourceTree = SOURCE_ROOT; }; - 34D2CCD120618B2F00CB1A14 /* OWSBackupLazyRestoreJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSBackupLazyRestoreJob.swift; sourceTree = ""; }; - 34D2CCD82062E7D000CB1A14 /* OWSScreenLockUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSScreenLockUI.h; sourceTree = ""; }; - 34D2CCD92062E7D000CB1A14 /* OWSScreenLockUI.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSScreenLockUI.m; sourceTree = ""; }; 34D2CCDB206939B100CB1A14 /* DebugUIMessagesAction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIMessagesAction.m; sourceTree = ""; }; 34D2CCDC206939B200CB1A14 /* DebugUIMessagesAssetLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIMessagesAssetLoader.m; sourceTree = ""; }; 34D2CCDD206939B200CB1A14 /* DebugUIMessagesAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIMessagesAction.h; sourceTree = ""; }; @@ -928,7 +947,6 @@ 34D920E620E179C200D51158 /* OWSMessageFooterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSMessageFooterView.m; sourceTree = ""; }; 34D99C8A1F27B13B00D284D6 /* OWSViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSViewController.h; sourceTree = ""; }; 34D99C8B1F27B13B00D284D6 /* OWSViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSViewController.m; sourceTree = ""; }; - 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSAnalytics.swift; sourceTree = ""; }; 34DB0BEB2011548A007B313F /* OWSDatabaseConverterTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSDatabaseConverterTest.h; sourceTree = ""; }; 34DB0BEC2011548B007B313F /* OWSDatabaseConverterTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDatabaseConverterTest.m; sourceTree = ""; }; 34DBEFFF206BD5A400025978 /* OWSMessageTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSMessageTextView.m; sourceTree = ""; }; @@ -942,8 +960,6 @@ 34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIDiskUsage.m; sourceTree = ""; }; 34E3EF0E1EFC2684007F6822 /* DebugUIPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIPage.h; sourceTree = ""; }; 34E3EF0F1EFC2684007F6822 /* DebugUIPage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIPage.m; sourceTree = ""; }; - 34E5DC8020D8050D00C08145 /* RegistrationUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegistrationUtils.h; sourceTree = ""; }; - 34E5DC8120D8050D00C08145 /* RegistrationUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegistrationUtils.m; sourceTree = ""; }; 34E88D252098C5AE00A608F4 /* ContactViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactViewController.swift; sourceTree = ""; }; 34E8A8D02085238900B272B1 /* ProtoParsingTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProtoParsingTest.m; sourceTree = ""; }; 34F308A01ECB469700BB7697 /* OWSBezierPathView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBezierPathView.h; sourceTree = ""; }; @@ -959,7 +975,6 @@ 4509E7991DD653700025A59F /* WebRTC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebRTC.framework; path = Carthage/Build/iOS/WebRTC.framework; sourceTree = ""; }; 450D19111F85236600970622 /* RemoteVideoView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RemoteVideoView.h; sourceTree = ""; }; 450D19121F85236600970622 /* RemoteVideoView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RemoteVideoView.m; sourceTree = ""; }; - 450DF2041E0D74AC003D14BE /* Platform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Platform.swift; sourceTree = ""; }; 450DF2081E0DD2C6003D14BE /* UserNotificationsAdaptee.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = UserNotificationsAdaptee.swift; path = UserInterface/Notifications/UserNotificationsAdaptee.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; 451166BF1FD86B98000739BA /* AccountManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountManager.swift; sourceTree = ""; }; 451573952061B49500803601 /* GradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = GradientView.swift; path = SignalMessaging/Views/GradientView.swift; sourceTree = SOURCE_ROOT; }; @@ -971,7 +986,6 @@ 452037CF1EE84975004E4CDF /* DebugUISessionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUISessionState.h; sourceTree = ""; }; 452037D01EE84975004E4CDF /* DebugUISessionState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUISessionState.m; sourceTree = ""; }; 4520D8D41D417D8E00123472 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = System/Library/Frameworks/Photos.framework; sourceTree = SDKROOT; }; - 4521C3BF1F59F3BA00B4C582 /* TextFieldHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldHelper.swift; sourceTree = ""; }; 4523149F1F7E9E18003A428C /* DirectionalPanGestureRecognizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DirectionalPanGestureRecognizer.swift; sourceTree = ""; }; 4523D015206EDC2B00A2AB51 /* LRUCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LRUCache.swift; sourceTree = ""; }; 452B998F20A34B6B006F2F9E /* AddContactShareToExistingContactViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddContactShareToExistingContactViewController.swift; sourceTree = ""; }; @@ -1007,7 +1021,6 @@ 455A16DC1F1FEA0000F86704 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; }; 455AC69D1F4F8B0300134004 /* ImageCacheTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageCacheTest.swift; sourceTree = ""; }; 45638BDB1F3DD0D400128435 /* DebugUICalling.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugUICalling.swift; sourceTree = ""; }; - 45638BDE1F3DDB2200128435 /* MessageSender+Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MessageSender+Promise.swift"; sourceTree = ""; }; 45666EC41D99483D008FE134 /* OWSAvatarBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSAvatarBuilder.h; sourceTree = ""; }; 45666EC51D99483D008FE134 /* OWSAvatarBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSAvatarBuilder.m; sourceTree = ""; }; 45666EC71D994C0D008FE134 /* OWSGroupAvatarBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSGroupAvatarBuilder.h; sourceTree = ""; }; @@ -1017,8 +1030,6 @@ 456D0FD81F631F4E008499CD /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lt; path = translations/lt.lproj/Localizable.strings; sourceTree = ""; }; 456F6E2E1E261D1000FD2210 /* PeerConnectionClientTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerConnectionClientTest.swift; sourceTree = ""; }; 4574A5D51DD6704700C6B692 /* CallService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = CallService.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - 4579431C1E7C8CE9008ED0C0 /* Pastelog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pastelog.h; sourceTree = ""; }; - 4579431D1E7C8CE9008ED0C0 /* Pastelog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Pastelog.m; sourceTree = ""; }; 45794E851E00620000066731 /* CallUIAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CallUIAdapter.swift; path = UserInterface/CallUIAdapter.swift; sourceTree = ""; }; 457C87B72032645C008D52D6 /* DebugUINotifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugUINotifications.swift; sourceTree = ""; }; 457F671A20746193000EABCD /* QuotedReplyPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuotedReplyPreview.swift; sourceTree = ""; }; @@ -1049,7 +1060,6 @@ 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TurnServerInfo.swift; sourceTree = ""; }; 45B201741DAECBFD00C461E0 /* Signal-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Signal-Bridging-Header.h"; sourceTree = ""; }; 45B27B852037FFB400A539DF /* DebugUIFileBrowser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugUIFileBrowser.swift; sourceTree = ""; }; - 45B5360D206DD8BB00D61655 /* UIResponder+OWS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "UIResponder+OWS.swift"; path = "util/UI Categories/UIResponder+OWS.swift"; sourceTree = ""; }; 45B74A5B2044AAB300CD42F8 /* aurora-quiet.aifc */ = {isa = PBXFileReference; lastKnownFileType = file; path = "aurora-quiet.aifc"; sourceTree = ""; }; 45B74A5C2044AAB300CD42F8 /* synth-quiet.aifc */ = {isa = PBXFileReference; lastKnownFileType = file; path = "synth-quiet.aifc"; sourceTree = ""; }; 45B74A5D2044AAB400CD42F8 /* keys-quiet.aifc */ = {isa = PBXFileReference; lastKnownFileType = file; path = "keys-quiet.aifc"; sourceTree = ""; }; @@ -1080,8 +1090,6 @@ 45BC829C1FD9C4B400011CF3 /* ShareViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewDelegate.swift; sourceTree = ""; }; 45BD60811DE9547E00A8F436 /* Contacts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Contacts.framework; path = System/Library/Frameworks/Contacts.framework; sourceTree = SDKROOT; }; 45BE4EA12012AD2000935E59 /* DisappearingTimerConfigurationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisappearingTimerConfigurationView.swift; sourceTree = ""; }; - 45C0DC1A1E68FE9000E04C47 /* UIApplication+OWS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIApplication+OWS.swift"; sourceTree = ""; }; - 45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIStoryboard+OWS.swift"; sourceTree = ""; }; 45C9DEB71DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebRTCCallMessageHandler.swift; sourceTree = ""; }; 45CB2FA71CB7146C00E1B343 /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = "Launch Screen.storyboard"; path = "Signal/src/util/Launch Screen.storyboard"; sourceTree = SOURCE_ROOT; }; 45CD81EE1DC030E7004C9430 /* SyncPushTokensJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyncPushTokensJob.swift; sourceTree = ""; }; @@ -1127,8 +1135,6 @@ 76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; }; 76EB03C218170B33006006FC /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 76EB03C318170B33006006FC /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 76EB04EA18170B33006006FC /* FunctionalUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionalUtil.h; sourceTree = ""; }; - 76EB04EB18170B33006006FC /* FunctionalUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FunctionalUtil.m; sourceTree = ""; }; 76EB052E18170B33006006FC /* ContactTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactTableViewCell.h; sourceTree = ""; }; 76EB052F18170B33006006FC /* ContactTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactTableViewCell.m; sourceTree = ""; }; 8981C8F64D94D3C52EB67A2C /* Pods-SignalTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignalTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-SignalTests/Pods-SignalTests.test.xcconfig"; sourceTree = ""; }; @@ -1210,12 +1216,8 @@ B6B9ECFA198B31BA00C620D3 /* PushManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = PushManager.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; B6B9ECFB198B31BA00C620D3 /* PushManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = PushManager.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; B6BC3D0C1AA544B100C2907F /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = translations/da.lproj/Localizable.strings; sourceTree = ""; }; - B6DA6B051B8A2F9A00CA6F98 /* AppStoreRating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppStoreRating.h; sourceTree = ""; }; - B6DA6B061B8A2F9A00CA6F98 /* AppStoreRating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppStoreRating.m; sourceTree = ""; }; B6F509961AA53F760068F56A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = translations/en.lproj/Localizable.strings; sourceTree = ""; }; B6FE7EB61ADD62FA00A6D22F /* PushKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PushKit.framework; path = System/Library/Frameworks/PushKit.framework; sourceTree = SDKROOT; }; - B90418E4183E9DD40038554A /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = ""; }; - B90418E5183E9DD40038554A /* DateUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DateUtil.m; sourceTree = ""; }; B97940251832BD2400BD66CB /* UIUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIUtil.h; sourceTree = ""; }; B97940261832BD2400BD66CB /* UIUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIUtil.m; sourceTree = ""; }; B9EB5ABC1884C002007CBB57 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; @@ -1237,8 +1239,6 @@ DF728B4B438716EAF95CEC18 /* Pods-Signal.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Signal.app store release.xcconfig"; path = "Pods/Target Support Files/Pods-Signal/Pods-Signal.app store release.xcconfig"; sourceTree = ""; }; E1A0AD8B16E13FDD0071E604 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; E85DB184824BA9DC302EC8B3 /* Pods-SignalTests.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignalTests.app store release.xcconfig"; path = "Pods/Target Support Files/Pods-SignalTests/Pods-SignalTests.app store release.xcconfig"; sourceTree = ""; }; - EF764C331DB67CC5000D9A87 /* UIViewController+Permissions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIViewController+Permissions.h"; path = "util/UIViewController+Permissions.h"; sourceTree = ""; }; - EF764C341DB67CC5000D9A87 /* UIViewController+Permissions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIViewController+Permissions.m"; path = "util/UIViewController+Permissions.m"; sourceTree = ""; }; FC3BD9871A30A790005B96BB /* Social.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Social.framework; path = System/Library/Frameworks/Social.framework; sourceTree = SDKROOT; }; FC5CDF371A3393DD00B47253 /* error_white@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "error_white@2x.png"; sourceTree = ""; }; FC5CDF381A3393DD00B47253 /* warning_white@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "warning_white@2x.png"; sourceTree = ""; }; @@ -1588,6 +1588,60 @@ path = categories; sourceTree = ""; }; + 3448255121138BAE00DB4BD8 /* util */ = { + isa = PBXGroup; + children = ( + 3448255721138BAE00DB4BD8 /* AppStoreRating.h */, + 3448258C21138BAE00DB4BD8 /* AppStoreRating.m */, + 3448258121138BAE00DB4BD8 /* AppUpdateNag.h */, + 3448255321138BAE00DB4BD8 /* AppUpdateNag.m */, + 3448259221138BAE00DB4BD8 /* DateUtil.h */, + 3448256F21138BAE00DB4BD8 /* DateUtil.m */, + 3448259521138BAE00DB4BD8 /* FunctionalUtil.h */, + 3448256D21138BAE00DB4BD8 /* FunctionalUtil.m */, + 3448258D21138BAE00DB4BD8 /* Launch Screen.storyboard */, + 3448256821138BAE00DB4BD8 /* MainAppContext.h */, + 3448258521138BAE00DB4BD8 /* MainAppContext.m */, + 3448258721138BAE00DB4BD8 /* NSString+OWS.m */, + 3448259421138BAE00DB4BD8 /* OWSAnalytics.swift */, + 3448256921138BAE00DB4BD8 /* OWSBackup.h */, + 3448258321138BAE00DB4BD8 /* OWSBackup.m */, + 3448259921138BAE00DB4BD8 /* OWSBackupAPI.swift */, + 3448257E21138BAE00DB4BD8 /* OWSBackupExportJob.h */, + 3448255621138BAE00DB4BD8 /* OWSBackupExportJob.m */, + 3448259A21138BAE00DB4BD8 /* OWSBackupImportJob.h */, + 3448257821138BAE00DB4BD8 /* OWSBackupImportJob.m */, + 3448259B21138BAE00DB4BD8 /* OWSBackupIO.h */, + 3448257721138BAE00DB4BD8 /* OWSBackupIO.m */, + 3448257A21138BAE00DB4BD8 /* OWSBackupJob.h */, + 3448259821138BAE00DB4BD8 /* OWSBackupJob.m */, + 3448255921138BAE00DB4BD8 /* OWSBackupLazyRestoreJob.swift */, + 3448255821138BAE00DB4BD8 /* OWSOrphanDataCleaner.h */, + 3448258B21138BAE00DB4BD8 /* OWSOrphanDataCleaner.m */, + 3448258821138BAE00DB4BD8 /* OWSScreenLockUI.h */, + 3448255B21138BAE00DB4BD8 /* OWSScreenLockUI.m */, + 3448258921138BAE00DB4BD8 /* Pastelog.h */, + 3448255A21138BAE00DB4BD8 /* Pastelog.m */, + 3448258A21138BAE00DB4BD8 /* Platform.swift */, + 3448257F21138BAE00DB4BD8 /* RegistrationUtils.h */, + 3448255521138BAE00DB4BD8 /* RegistrationUtils.m */, + 3448257421138BAE00DB4BD8 /* TextFieldHelper.swift */, + 3448256A21138BAE00DB4BD8 /* UI Categories */, + 3448257921138BAE00DB4BD8 /* UIViewController+CameraPermissions.h */, + 3448255421138BAE00DB4BD8 /* UIViewController+Permissions.h */, + 3448258021138BAE00DB4BD8 /* UIViewController+Permissions.m */, + ); + path = util; + sourceTree = ""; + }; + 3448256A21138BAE00DB4BD8 /* UI Categories */ = { + isa = PBXGroup; + children = ( + 3448256B21138BAE00DB4BD8 /* UIResponder+OWS.swift */, + ); + path = "UI Categories"; + sourceTree = ""; + }; 3448BFC01EDF0EA7005B2D69 /* ConversationView */ = { isa = PBXGroup; children = ( @@ -2134,7 +2188,7 @@ 45B201741DAECBFD00C461E0 /* Signal-Bridging-Header.h */, 45CD81A41DBFF8CF004C9430 /* Storyboards */, 450DF2061E0DD28D003D14BE /* UserInterface */, - 76EB04C818170B33006006FC /* util */, + 3448255121138BAE00DB4BD8 /* util */, ); path = src; sourceTree = ""; @@ -2177,45 +2231,6 @@ path = network; sourceTree = ""; }; - 76EB04C818170B33006006FC /* util */ = { - isa = PBXGroup; - children = ( - B6DA6B051B8A2F9A00CA6F98 /* AppStoreRating.h */, - B6DA6B061B8A2F9A00CA6F98 /* AppStoreRating.m */, - 34CCAF361F0C0599004084F4 /* AppUpdateNag.h */, - 34CCAF371F0C0599004084F4 /* AppUpdateNag.m */, - B90418E4183E9DD40038554A /* DateUtil.h */, - B90418E5183E9DD40038554A /* DateUtil.m */, - 76EB04EA18170B33006006FC /* FunctionalUtil.h */, - 76EB04EB18170B33006006FC /* FunctionalUtil.m */, - 34B0796C1FCF46B000E248C2 /* MainAppContext.h */, - 34B0796B1FCF46B000E248C2 /* MainAppContext.m */, - 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */, - 34A9105E1FFEB113000C4745 /* OWSBackup.h */, - 34A9105F1FFEB114000C4745 /* OWSBackup.m */, - 340FC8C6204DE64D007AEB0F /* OWSBackupAPI.swift */, - 340FC8BE204DB7D1007AEB0F /* OWSBackupExportJob.h */, - 340FC8BF204DB7D2007AEB0F /* OWSBackupExportJob.m */, - 340FC8C920517B84007AEB0F /* OWSBackupImportJob.h */, - 340FC8C820517B84007AEB0F /* OWSBackupImportJob.m */, - 340FC8CF205BF2FA007AEB0F /* OWSBackupIO.h */, - 340FC8CE205BF2FA007AEB0F /* OWSBackupIO.m */, - 340FC8CB20518C76007AEB0F /* OWSBackupJob.h */, - 340FC8CC20518C76007AEB0F /* OWSBackupJob.m */, - 34D2CCD120618B2F00CB1A14 /* OWSBackupLazyRestoreJob.swift */, - 34D2CCD82062E7D000CB1A14 /* OWSScreenLockUI.h */, - 34D2CCD92062E7D000CB1A14 /* OWSScreenLockUI.m */, - 4579431C1E7C8CE9008ED0C0 /* Pastelog.h */, - 4579431D1E7C8CE9008ED0C0 /* Pastelog.m */, - 450DF2041E0D74AC003D14BE /* Platform.swift */, - 34E5DC8020D8050D00C08145 /* RegistrationUtils.h */, - 34E5DC8120D8050D00C08145 /* RegistrationUtils.m */, - 4521C3BF1F59F3BA00B4C582 /* TextFieldHelper.swift */, - FCFA64B11A24F29E0007FB87 /* UI Categories */, - ); - path = util; - sourceTree = ""; - }; 76EB052B18170B33006006FC /* Views */ = { isa = PBXGroup; children = ( @@ -2471,20 +2486,6 @@ name = "Supporting Files"; sourceTree = ""; }; - FCFA64B11A24F29E0007FB87 /* UI Categories */ = { - isa = PBXGroup; - children = ( - 45638BDE1F3DDB2200128435 /* MessageSender+Promise.swift */, - 45C0DC1A1E68FE9000E04C47 /* UIApplication+OWS.swift */, - 45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */, - EF764C331DB67CC5000D9A87 /* UIViewController+Permissions.h */, - EF764C341DB67CC5000D9A87 /* UIViewController+Permissions.m */, - 45B5360D206DD8BB00D61655 /* UIResponder+OWS.swift */, - ); - name = "UI Categories"; - path = ..; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -2877,6 +2878,7 @@ 45B74A772044AAB600CD42F8 /* hello.aifc in Resources */, 45B74A7C2044AAB600CD42F8 /* hello-quiet.aifc in Resources */, 45B74A792044AAB600CD42F8 /* input.aifc in Resources */, + 344825BD21138BAF00DB4BD8 /* Launch Screen.storyboard in Resources */, 45B74A8C2044AAB600CD42F8 /* input-quiet.aifc in Resources */, 45B74A7A2044AAB600CD42F8 /* keys.aifc in Resources */, 45B74A762044AAB600CD42F8 /* keys-quiet.aifc in Resources */, @@ -3270,7 +3272,9 @@ buildActionMask = 2147483647; files = ( 4CC0B59C20EC5F2E00CF6EE0 /* ConversationConfigurationSyncOperation.swift in Sources */, + 344825B121138BAF00DB4BD8 /* TextFieldHelper.swift in Sources */, 3461293E1FD1D72B00532771 /* ExperienceUpgradeFinder.swift in Sources */, + 344825BA21138BAF00DB4BD8 /* Platform.swift in Sources */, 34D1F0BD1F8D108C0066283D /* AttachmentUploadView.m in Sources */, 452EC6DF205E9E30000E787C /* MediaGalleryViewController.swift in Sources */, 34386A52207D0C01009F5D9C /* HomeViewCell.m in Sources */, @@ -3279,31 +3283,31 @@ 34D8C02B1ED3685800188D7C /* DebugUIContacts.m in Sources */, 45C9DEB81DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift in Sources */, 34D1F0501F7D45A60066283D /* GifPickerCell.swift in Sources */, - 34D99C931F2937CC00D284D6 /* OWSAnalytics.swift in Sources */, 340FC8B8204DAC8D007AEB0F /* AddToGroupViewController.m in Sources */, 341F2C0F1F2B8AE700D07D6B /* DebugUIMisc.m in Sources */, 340FC8AF204DAC8D007AEB0F /* OWSLinkDeviceViewController.m in Sources */, 34E3EF0D1EFC235B007F6822 /* DebugUIDiskUsage.m in Sources */, + 344825B921138BAF00DB4BD8 /* NSString+OWS.m in Sources */, 454A84042059C787008B8C75 /* MediaTileViewController.swift in Sources */, 340FC8B4204DAC8D007AEB0F /* OWSBackupSettingsViewController.m in Sources */, 34D1F0871F8678AA0066283D /* ConversationViewItem.m in Sources */, - B6DA6B071B8A2F9A00CA6F98 /* AppStoreRating.m in Sources */, 451A13B11E13DED2000A50FD /* CallNotificationsAdapter.swift in Sources */, 348570A820F67575004FF32B /* OWSMessageHeaderView.m in Sources */, 450DF2091E0DD2C6003D14BE /* UserNotificationsAdaptee.swift in Sources */, + 344825A121138BAF00DB4BD8 /* Pastelog.m in Sources */, 34D1F0AB1F867BFC0066283D /* OWSContactOffersCell.m in Sources */, - 340FC8C7204DE64D007AEB0F /* OWSBackupAPI.swift in Sources */, 343A65981FC4CFE7000477A1 /* ConversationScrollButton.m in Sources */, 34386A51207D0C01009F5D9C /* HomeViewController.m in Sources */, + 344825A021138BAF00DB4BD8 /* OWSBackupLazyRestoreJob.swift in Sources */, 34D1F0A91F867BFC0066283D /* ConversationViewCell.m in Sources */, 4505C2BF1E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */, - 34CCAF381F0C0599004084F4 /* AppUpdateNag.m in Sources */, - EF764C351DB67CC5000D9A87 /* UIViewController+Permissions.m in Sources */, 45CD81EF1DC030E7004C9430 /* SyncPushTokensJob.swift in Sources */, 34D2CCE0206939B400CB1A14 /* DebugUIMessagesAssetLoader.m in Sources */, 45794E861E00620000066731 /* CallUIAdapter.swift in Sources */, 340FC8BA204DAC8D007AEB0F /* FingerprintViewScanController.m in Sources */, + 344825B721138BAF00DB4BD8 /* OWSBackup.m in Sources */, 4585C4681ED8F8D200896AEA /* SafetyNumberConfirmationAlert.swift in Sources */, + 344825BC21138BAF00DB4BD8 /* AppStoreRating.m in Sources */, 4C20B2B920CA10DE001BAC90 /* ConversationSearchViewController.swift in Sources */, 450D19131F85236600970622 /* RemoteVideoView.m in Sources */, B6B9ECFC198B31BA00C620D3 /* PushManager.m in Sources */, @@ -3311,7 +3315,6 @@ 45DF5DF21DDB843F00C936C7 /* CompareSafetyNumbersActivity.swift in Sources */, 458DE9D91DEE7B360071BB03 /* OWSWebRTCDataProtos.pb.m in Sources */, 451166C01FD86B98000739BA /* AccountManager.swift in Sources */, - 34D2CCD220618B3000CB1A14 /* OWSBackupLazyRestoreJob.swift in Sources */, 3430FE181F7751D4000EC51B /* GiphyAPI.swift in Sources */, 34A55F3720485465002CC6DE /* OWS2FARegistrationViewController.m in Sources */, 340FC8AD204DAC8D007AEB0F /* OWSLinkedDevicesTableViewController.m in Sources */, @@ -3320,14 +3323,12 @@ 3496744F2076ACD000080B5F /* LongTextViewController.swift in Sources */, 34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */, 34B3F8931E8DF1710035BE1A /* SignalsNavigationController.m in Sources */, - 76EB063A18170B33006006FC /* FunctionalUtil.m in Sources */, + 3448259E21138BAF00DB4BD8 /* RegistrationUtils.m in Sources */, 34F308A21ECB469700BB7697 /* OWSBezierPathView.m in Sources */, 45B27B862037FFB400A539DF /* DebugUIFileBrowser.swift in Sources */, 34CE88E71F2FB9A10098030F /* ProfileViewController.m in Sources */, 3403B95D20EA9527001A1F44 /* OWSContactShareButtonsView.m in Sources */, - 34B0796D1FCF46B100E248C2 /* MainAppContext.m in Sources */, 34E3EF101EFC2684007F6822 /* DebugUIPage.m in Sources */, - 340FC8CD20518C77007AEB0F /* OWSBackupJob.m in Sources */, 34D1F0AE1F867BFC0066283D /* OWSMessageCell.m in Sources */, 4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */, 4CB5F26720F6E1E2004D1B42 /* MenuActionsViewController.swift in Sources */, @@ -3337,27 +3338,27 @@ 452037D11EE84975004E4CDF /* DebugUISessionState.m in Sources */, D221A09A169C9E5E00537ABF /* main.m in Sources */, 34B3F87B1E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift in Sources */, - 34E5DC8220D8050D00C08145 /* RegistrationUtils.m in Sources */, 452EA09E1EA7ABE00078744B /* AttachmentPointerView.swift in Sources */, 45638BDC1F3DD0D400128435 /* DebugUICalling.swift in Sources */, 45464DBC1DFA041F001D3FD6 /* DataChannelMessage.swift in Sources */, 34E3E5681EC4B19400495BAC /* AudioProgressView.swift in Sources */, 34D1F0521F7E8EA30066283D /* GiphyDownloader.swift in Sources */, 340FC8BC204DAC8D007AEB0F /* FingerprintViewController.m in Sources */, - 450DF2051E0D74AC003D14BE /* Platform.swift in Sources */, 340FC8B2204DAC8D007AEB0F /* AdvancedSettingsTableViewController.m in Sources */, 452B999020A34B6B006F2F9E /* AddContactShareToExistingContactViewController.swift in Sources */, + 344825B421138BAF00DB4BD8 /* OWSBackupImportJob.m in Sources */, 346129991FD1E4DA00532771 /* SignalApp.m in Sources */, 34BECE301F7ABCF800D7438D /* GifPickerLayout.swift in Sources */, 343A65951FC47D5E000477A1 /* DebugUISyncMessages.m in Sources */, - 45C0DC1E1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */, 452ECA4D1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */, 4556FA681F54AA9500AF40DD /* DebugUIProfile.swift in Sources */, 45A6DAD61EBBF85500893231 /* ReminderView.swift in Sources */, + 344825BB21138BAF00DB4BD8 /* OWSOrphanDataCleaner.m in Sources */, 34D1F0881F8678AA0066283D /* ConversationViewLayout.m in Sources */, 452314A01F7E9E18003A428C /* DirectionalPanGestureRecognizer.swift in Sources */, 34330AA31E79686200DF2FB9 /* OWSProgressView.m in Sources */, 45D2AC02204885170033C692 /* OWS2FAReminderViewController.swift in Sources */, + 344825A921138BAF00DB4BD8 /* UIResponder+OWS.swift in Sources */, 4542DF54208D40AC007B4E76 /* LoadingViewController.swift in Sources */, 34D5CCA91EAE3D30005515DB /* AvatarViewHelper.m in Sources */, 34D1F0B71F87F8850066283D /* OWSGenericAttachmentView.m in Sources */, @@ -3366,15 +3367,16 @@ 34B3F8801E8DF1700035BE1A /* InviteFlow.swift in Sources */, 457C87B82032645C008D52D6 /* DebugUINotifications.swift in Sources */, 4C13C9F620E57BA30089A98B /* ColorPickerViewController.swift in Sources */, - 340FC8D0205BF2FA007AEB0F /* OWSBackupIO.m in Sources */, 458E38371D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m in Sources */, 4517642B1DE939FD00EDB8B9 /* ContactCell.swift in Sources */, + 344825B621138BAF00DB4BD8 /* UIViewController+Permissions.m in Sources */, 340FC8AB204DAC8D007AEB0F /* DomainFrontingCountryViewController.m in Sources */, 3496744D2076768700080B5F /* OWSMessageBubbleView.m in Sources */, 34B3F8751E8DF1700035BE1A /* CallViewController.swift in Sources */, 34D8C0281ED3673300188D7C /* DebugUITableViewController.m in Sources */, 34219801210612F600C57195 /* iRate.m in Sources */, 45F32C222057297A00A300D5 /* MediaDetailViewController.m in Sources */, + 344825C021138BAF00DB4BD8 /* OWSAnalytics.swift in Sources */, 34B3F8851E8DF1700035BE1A /* NewGroupViewController.m in Sources */, 34D8C0271ED3673300188D7C /* DebugUIMessages.m in Sources */, 34DBF003206BD5A500025978 /* OWSMessageTextView.m in Sources */, @@ -3382,29 +3384,30 @@ 34B3F8821E8DF1700035BE1A /* NewContactThreadViewController.m in Sources */, 45D308AD2049A439000189E4 /* PinEntryView.m in Sources */, 340FC8B1204DAC8D007AEB0F /* BlockListViewController.m in Sources */, - 45B5360E206DD8BB00D61655 /* UIResponder+OWS.swift in Sources */, + 344825A221138BAF00DB4BD8 /* OWSScreenLockUI.m in Sources */, + 3448259F21138BAF00DB4BD8 /* OWSBackupExportJob.m in Sources */, 45F659821E1BE77000444429 /* NonCallKitCallUIAdaptee.swift in Sources */, + 344825C321138BAF00DB4BD8 /* OWSBackupAPI.swift in Sources */, 45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */, 34B3F8771E8DF1700035BE1A /* ContactsPicker.swift in Sources */, - 45C0DC1B1E68FE9000E04C47 /* UIApplication+OWS.swift in Sources */, - 45638BDF1F3DDB2200128435 /* MessageSender+Promise.swift in Sources */, 45FBC5C81DF8575700E9B410 /* CallKitCallManager.swift in Sources */, 4539B5861F79348F007141FF /* PushRegistrationManager.swift in Sources */, 45FBC5D11DF8592E00E9B410 /* SignalCall.swift in Sources */, 340FC8BB204DAC8D007AEB0F /* OWSAddToContactViewController.m in Sources */, - 340FC8C0204DB7D2007AEB0F /* OWSBackupExportJob.m in Sources */, + 3448259D21138BAF00DB4BD8 /* AppUpdateNag.m in Sources */, 45F32C232057297A00A300D5 /* MediaPageViewController.swift in Sources */, 3466087420E5649700AFFE73 /* OWSLayerView.swift in Sources */, 340FC8A7204DAC8D007AEB0F /* RegistrationViewController.m in Sources */, 452C468F1E427E200087B011 /* OutboundCallInitiator.swift in Sources */, - 34D2CCDA2062E7D000CB1A14 /* OWSScreenLockUI.m in Sources */, 45F170BB1E2FC5D3003FC1F2 /* CallAudioService.swift in Sources */, 345BC30C2047030700257B7C /* OWS2FASettingsViewController.m in Sources */, - 340FC8CA20517B84007AEB0F /* OWSBackupImportJob.m in Sources */, 340FC8B7204DAC8D007AEB0F /* OWSConversationSettingsViewController.m in Sources */, + 344825AD21138BAF00DB4BD8 /* DateUtil.m in Sources */, 34BECE2E1F7ABCE000D7438D /* GifPickerViewController.swift in Sources */, 34D1F0C01F8EC1760066283D /* MessageRecipientStatusUtils.swift in Sources */, + 344825AB21138BAF00DB4BD8 /* FunctionalUtil.m in Sources */, 45F659731E1BD99C00444429 /* CallKitCallUIAdaptee.swift in Sources */, + 344825B321138BAF00DB4BD8 /* OWSBackupIO.m in Sources */, 34277A5E20751BDC006049F2 /* OWSQuotedMessageView.m in Sources */, 458DE9D61DEE3FD00071BB03 /* PeerConnectionClient.swift in Sources */, 45DDA6242090CEB500DE97F8 /* ConversationHeaderView.swift in Sources */, @@ -3412,6 +3415,7 @@ 34D1F0841F8678AA0066283D /* ConversationInputToolbar.m in Sources */, 457F671B20746193000EABCD /* QuotedReplyPreview.swift in Sources */, 34DBF004206BD5A500025978 /* OWSBubbleView.m in Sources */, + 344825B821138BAF00DB4BD8 /* MainAppContext.m in Sources */, 34E88D262098C5AE00A608F4 /* ContactViewController.swift in Sources */, 76EB054018170B33006006FC /* AppDelegate.m in Sources */, 34D1F0831F8678AA0066283D /* ConversationInputTextView.m in Sources */, @@ -3423,24 +3427,21 @@ 4574A5D61DD6704700C6B692 /* CallService.swift in Sources */, 340FC8A8204DAC8D007AEB0F /* CodeVerificationViewController.m in Sources */, 3461299C1FD1EA9E00532771 /* NotificationsManager.m in Sources */, - 4521C3C01F59F3BA00B4C582 /* TextFieldHelper.swift in Sources */, 34D2CCDF206939B400CB1A14 /* DebugUIMessagesAction.m in Sources */, + 344825C221138BAF00DB4BD8 /* OWSBackupJob.m in Sources */, 340FC8AC204DAC8D007AEB0F /* PrivacySettingsTableViewController.m in Sources */, 340FC8C5204DE223007AEB0F /* DebugUIBackup.m in Sources */, 4C11AA5020FD59C700351FBD /* MessageStatusView.swift in Sources */, 340FC8AE204DAC8D007AEB0F /* OWSSoundSettingsViewController.m in Sources */, - 4579431E1E7C8CE9008ED0C0 /* Pastelog.m in Sources */, 340FC8B0204DAC8D007AEB0F /* AddToBlockListViewController.m in Sources */, 340FC8B3204DAC8D007AEB0F /* AppSettingsViewController.m in Sources */, 346B66311F4E29B200E5122F /* CropScaleImageViewController.swift in Sources */, 45E5A6991F61E6DE001E4A8A /* MarqueeLabel.swift in Sources */, - 34A910601FFEB114000C4745 /* OWSBackup.m in Sources */, 34D1F0B01F867BFC0066283D /* OWSSystemMessageCell.m in Sources */, 45A663C51F92EC760027B59E /* GroupTableViewCell.swift in Sources */, 34CA631B2097806F00E526A0 /* OWSContactShareView.m in Sources */, 34D1F0861F8678AA0066283D /* ConversationViewController.m in Sources */, 3427C64320F500E000EEC730 /* OWSMessageTimerView.m in Sources */, - B90418E6183E9DD40038554A /* DateUtil.m in Sources */, 340FC8BD204DAC8D007AEB0F /* ShowGroupMembersViewController.m in Sources */, 459311FC1D75C948008DD4F0 /* OWSDeviceTableViewCell.m in Sources */, ); @@ -3460,8 +3461,6 @@ B660F7561C29988E00687D6E /* PushManager.m in Sources */, 34DB0BED2011548B007B313F /* OWSDatabaseConverterTest.m in Sources */, 45360B911F952AA900FA666C /* MarqueeLabel.swift in Sources */, - 454EBAB41F2BE14C00ACE0BB /* OWSAnalytics.swift in Sources */, - B660F7721C29988E00687D6E /* AppStoreRating.m in Sources */, 954AEE6A1DF33E01002E5410 /* ContactsPickerTest.swift in Sources */, 45666F581D9B2880008FE134 /* OWSScrubbingLogFormatterTest.m in Sources */, B660F6E01C29868000687D6E /* UtilTest.m in Sources */, diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 08de4d05c6..087db1f241 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -12,6 +12,7 @@ #import "NotificationsManager.h" #import "OWS2FASettingsViewController.h" #import "OWSBackup.h" +#import "OWSOrphanDataCleaner.h" #import "OWSScreenLockUI.h" #import "Pastelog.h" #import "PushManager.h" @@ -43,7 +44,6 @@ #import #import #import -#import #import #import #import @@ -149,7 +149,7 @@ static NSTimeInterval launchStartedAt; return YES; } - [AppVersion instance]; + [AppVersion sharedInstance]; [self startupLogging]; @@ -314,6 +314,7 @@ static NSTimeInterval launchStartedAt; return NO; } + OWSAssert(backgroundTask); backgroundTask = nil; return YES; @@ -325,7 +326,7 @@ static NSTimeInterval launchStartedAt; self.didAppLaunchFail = YES; // We perform a subset of the [application:didFinishLaunchingWithOptions:]. - [AppVersion instance]; + [AppVersion sharedInstance]; [self startupLogging]; self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; @@ -1061,7 +1062,7 @@ static NSTimeInterval launchStartedAt; [DeviceSleepManager.sharedInstance removeBlockWithBlockObject:self]; - [AppVersion.instance mainAppLaunchDidComplete]; + [AppVersion.sharedInstance mainAppLaunchDidComplete]; [Environment.current.contactsManager loadSignalAccountsFromCache]; [Environment.current.contactsManager startObserving]; @@ -1090,7 +1091,7 @@ static NSTimeInterval launchStartedAt; // TODO: Orphan cleanup is somewhat expensive - not least in doing a bunch // of disk access. We might want to only run it "once per version" // or something like that in production. - [OWSOrphanedDataCleaner auditAndCleanupAsync:nil]; + [OWSOrphanDataCleaner auditOnLaunchIfNecessary]; #endif [OWSProfileManager.sharedManager fetchLocalUsersProfile]; diff --git a/Signal/src/Jobs/SyncPushTokensJob.swift b/Signal/src/Jobs/SyncPushTokensJob.swift index d1d396beef..1546e39c99 100644 --- a/Signal/src/Jobs/SyncPushTokensJob.swift +++ b/Signal/src/Jobs/SyncPushTokensJob.swift @@ -53,7 +53,7 @@ class SyncPushTokensJob: NSObject { shouldUploadTokens = true } - if AppVersion.instance().lastAppVersion != AppVersion.instance().currentAppVersion { + if AppVersion.sharedInstance().lastAppVersion != AppVersion.sharedInstance().currentAppVersion { Logger.info("\(self.TAG) Uploading due to fresh install or app upgrade.") shouldUploadTokens = true } @@ -79,7 +79,7 @@ class SyncPushTokensJob: NSObject { return runPromise } - // MARK - objc wrappers, since objc can't use swift parameterized types + // MARK: - objc wrappers, since objc can't use swift parameterized types @objc class func run(accountManager: AccountManager, preferences: OWSPreferences) -> AnyPromise { let promise: Promise = self.run(accountManager: accountManager, preferences: preferences) diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIDiskUsage.m b/Signal/src/ViewControllers/DebugUI/DebugUIDiskUsage.m index 082db9d8e8..90c973b223 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIDiskUsage.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIDiskUsage.m @@ -3,10 +3,10 @@ // #import "DebugUIDiskUsage.h" +#import "OWSOrphanDataCleaner.h" #import "OWSTableViewController.h" #import "Signal-Swift.h" #import -#import #import #import #import @@ -28,11 +28,11 @@ NS_ASSUME_NONNULL_BEGIN items:@[ [OWSTableItem itemWithTitle:@"Audit & Log" actionBlock:^{ - [OWSOrphanedDataCleaner auditAsync]; + [OWSOrphanDataCleaner auditAndCleanup:NO]; }], [OWSTableItem itemWithTitle:@"Audit & Clean Up" actionBlock:^{ - [OWSOrphanedDataCleaner auditAndCleanupAsync:nil]; + [OWSOrphanDataCleaner auditAndCleanup:YES]; }], [OWSTableItem itemWithTitle:@"Save All Attachments" actionBlock:^{ diff --git a/Signal/src/util/MainAppContext.m b/Signal/src/util/MainAppContext.m index dffe0aa766..03d0e61bb0 100644 --- a/Signal/src/util/MainAppContext.m +++ b/Signal/src/util/MainAppContext.m @@ -8,6 +8,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -15,6 +16,8 @@ NS_ASSUME_NONNULL_BEGIN @property (atomic) UIApplicationState reportedApplicationState; +@property (nonatomic, nullable) NSMutableArray *appActiveBlocks; + @end #pragma mark - @@ -54,6 +57,10 @@ NS_ASSUME_NONNULL_BEGIN name:UIApplicationWillTerminateNotification object:nil]; + // We can't use OWSSingletonAssert() since it uses the app context. + + self.appActiveBlocks = [NSMutableArray new]; + return self; } @@ -108,6 +115,8 @@ NS_ASSUME_NONNULL_BEGIN DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); [NSNotificationCenter.defaultCenter postNotificationName:OWSApplicationDidBecomeActiveNotification object:nil]; + + [self runAppActiveBlocks]; } - (void)applicationWillTerminate:(NSNotification *)notification @@ -228,6 +237,49 @@ NS_ASSUME_NONNULL_BEGIN [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:value]; } +#pragma mark - + +- (void)runNowOrWhenMainAppIsActive:(AppActiveBlock)block +{ + OWSAssert(block); + + 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(); + OWSAssert(backgroundTask); + backgroundTask = nil; + return; + } + + [self.appActiveBlocks addObject:block]; + }); +} + +- (void)runAppActiveBlocks +{ + OWSAssertIsOnMainThread(); + OWSAssert(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 *appActiveBlocks = [self.appActiveBlocks copy]; + [self.appActiveBlocks removeAllObjects]; + for (AppActiveBlock block in appActiveBlocks) { + block(); + } + + OWSAssert(backgroundTask); + backgroundTask = nil; +} + @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/util/OWSOrphanDataCleaner.h b/Signal/src/util/OWSOrphanDataCleaner.h new file mode 100644 index 0000000000..55debda6e6 --- /dev/null +++ b/Signal/src/util/OWSOrphanDataCleaner.h @@ -0,0 +1,21 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +NS_ASSUME_NONNULL_BEGIN + +// Notes: +// +// * On disk, we only bother cleaning up files, not directories. +@interface OWSOrphanDataCleaner : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +// This is exposed for the debug UI. ++ (void)auditAndCleanup:(BOOL)shouldCleanup; + ++ (void)auditOnLaunchIfNecessary; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Signal/src/util/OWSOrphanDataCleaner.m b/Signal/src/util/OWSOrphanDataCleaner.m new file mode 100644 index 0000000000..128f902b31 --- /dev/null +++ b/Signal/src/util/OWSOrphanDataCleaner.m @@ -0,0 +1,683 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +#import "OWSOrphanDataCleaner.h" +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +NSString *const OWSOrphanDataCleaner_Collection = @"OWSOrphanDataCleaner_Collection"; +NSString *const OWSOrphanDataCleaner_LastCleaningVersionKey = @"OWSOrphanDataCleaner_LastCleaningVersionKey"; + +@interface OWSOrphanData : NSObject + +@property (nonatomic) NSSet *interactionIds; +@property (nonatomic) NSSet *attachmentIds; +@property (nonatomic) NSSet *filePaths; + +@end + +#pragma mark - + +@implementation OWSOrphanData + +@end + +#pragma mark - + +typedef void (^OrphanDataBlock)(OWSOrphanData *); + +@implementation OWSOrphanDataCleaner + +// Unlike CurrentAppContext().isMainAppAndActive, this method can be safely +// invoked off the main thread. ++ (BOOL)isMainAppAndActive +{ + return CurrentAppContext().reportedApplicationState == UIApplicationStateActive; +} + ++ (void)printPaths:(NSArray *)paths label:(NSString *)label +{ + for (NSString *path in [paths sortedArrayUsingSelector:@selector(compare:)]) { + DDLogDebug(@"%@ %@: %@", self.logTag, label, path); + } +} + ++ (long long)fileSizeOfFilePath:(NSString *)filePath +{ + NSError *error; + NSNumber *fileSize = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:&error][NSFileSize]; + if (error) { + if ([error.domain isEqualToString:NSCocoaErrorDomain] && error.code == 260) { + DDLogWarn(@"%@ can't find size of missing file: %@", self.logTag, filePath); + } else { + OWSProdLogAndFail(@"%@ attributesOfItemAtPath: %@ error: %@", self.logTag, filePath, error); + } + return 0; + } + return fileSize.longLongValue; +} + ++ (nullable NSNumber *)fileSizeOfFilePathsSafe:(NSArray *)filePaths +{ + long long result = 0; + for (NSString *filePath in filePaths) { + if (!self.isMainAppAndActive) { + return nil; + } + result += [self fileSizeOfFilePath:filePath]; + } + return @(result); +} + ++ (nullable NSSet *)filePathsInDirectorySafe:(NSString *)dirPath +{ + NSMutableSet *filePaths = [NSMutableSet new]; + if (![[NSFileManager defaultManager] fileExistsAtPath:dirPath]) { + return filePaths; + } + NSError *error; + NSArray *fileNames = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:dirPath error:&error]; + if (error) { + OWSProdLogAndFail(@"%@ contentsOfDirectoryAtPath error: %@", self.logTag, error); + return [NSSet new]; + } + for (NSString *fileName in fileNames) { + if (!self.isMainAppAndActive) { + return nil; + } + NSString *filePath = [dirPath stringByAppendingPathComponent:fileName]; + BOOL isDirectory; + [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory]; + if (isDirectory) { + NSSet *_Nullable dirPaths = [self filePathsInDirectorySafe:filePath]; + if (!dirPaths) { + return nil; + } + [filePaths unionSet:dirPaths]; + } else { + [filePaths addObject:filePath]; + } + } + return filePaths; +} + +// This method finds (but does not delete): +// +// * Orphan TSInteractions (with no thread). +// * Orphan TSAttachments (with no message). +// * Orphan attachment files (with no corresponding TSAttachment). +// * Orphan profile avatars. +// * Temporary files (all). +// +// It also finds (we don't clean these up). +// +// * Missing attachment files (cannot be cleaned up). +// These are attachments which have no file on disk. They should be extremely rare - +// the only cases I have seen are probably due to debugging. +// They can't be cleaned up - we don't want to delete the TSAttachmentStream or +// its corresponding message. Better that the broken message shows up in the +// conversation view. ++ (void)findOrphanDataWithRetries:(NSInteger)remainingRetries + databaseConnection:(YapDatabaseConnection *)databaseConnection + success:(OrphanDataBlock)success + failure:(dispatch_block_t)failure +{ + OWSAssert(databaseConnection); + + if (remainingRetries < 1) { + DDLogInfo(@"%@ Aborting orphan data search.", self.logTag); + dispatch_async(self.workQueue, ^{ + failure(); + }); + return; + } + + // Wait until the app is active... + [CurrentAppContext() runNowOrWhenMainAppIsActive:^{ + // ...but perform the work off the main thread. + dispatch_async(self.workQueue, ^{ + OWSOrphanData *_Nullable orphanData = [self findOrphanDataSync:databaseConnection]; + if (orphanData) { + success(orphanData); + } else { + [self findOrphanDataWithRetries:remainingRetries - 1 + databaseConnection:databaseConnection + success:success + failure:failure]; + } + }); + }]; +} + +// Returns nil on failure, usually indicating that the search +// aborted due to the app resigning active. This method is extremely careful to +// abort if the app resigns active, in order to avoid 0xdead10cc crashes. ++ (nullable OWSOrphanData *)findOrphanDataSync:(YapDatabaseConnection *)databaseConnection +{ + OWSAssert(databaseConnection); + + __block BOOL shouldAbort = NO; + + // LOG_ALL_FILE_PATHS can be used to determine if there are other kinds of files + // that we're not cleaning up. +//#define LOG_ALL_FILE_PATHS +#ifdef LOG_ALL_FILE_PATHS + { + NSString *documentDirPath = [OWSFileSystem appDocumentDirectoryPath]; + NSArray *_Nullable allDocumentFilePaths = + [self filePathsInDirectorySafe:documentDirPath].allObjects; + allDocumentFilePaths = [allDocumentFilePaths sortedArrayUsingSelector:@selector(compare:)]; + NSString *attachmentsFolder = [TSAttachmentStream attachmentsFolder]; + for (NSString *filePath in allDocumentFilePaths) { + if ([filePath hasPrefix:attachmentsFolder]) { + continue; + } + DDLogVerbose(@"%@ non-attachment file: %@", self.logTag, filePath); + } + } + { + NSString *documentDirPath = [OWSFileSystem appSharedDataDirectoryPath]; + NSArray *_Nullable allDocumentFilePaths = + [self filePathsInDirectorySafe:documentDirPath].allObjects; + allDocumentFilePaths = [allDocumentFilePaths sortedArrayUsingSelector:@selector(compare:)]; + NSString *attachmentsFolder = [TSAttachmentStream attachmentsFolder]; + for (NSString *filePath in allDocumentFilePaths) { + if ([filePath hasPrefix:attachmentsFolder]) { + continue; + } + DDLogVerbose(@"%@ non-attachment file: %@", self.logTag, filePath); + } + } +#endif + + // We treat _all_ temp files as orphan files. This is safe + // because temp files only need to be retained for the + // a single launch of the app. Since our "date threshold" + // for deletion is relative to the current launch time, + // all temp files currently in use should be safe. + NSString *temporaryDirectory = NSTemporaryDirectory(); + NSArray *_Nullable tempFilePaths = [self filePathsInDirectorySafe:temporaryDirectory].allObjects; + if (!tempFilePaths || !self.isMainAppAndActive) { + return nil; + } + +#ifdef LOG_ALL_FILE_PATHS + { + NSDateFormatter *dateFormatter = [NSDateFormatter new]; + [dateFormatter setDateStyle:NSDateFormatterLongStyle]; + [dateFormatter setTimeStyle:NSDateFormatterLongStyle]; + + tempFilePaths = [tempFilePaths sortedArrayUsingSelector:@selector(compare:)]; + for (NSString *filePath in tempFilePaths) { + NSError *error; + NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:&error]; + if (!attributes || error) { + OWSProdLogAndFail(@"%@ Could not get attributes of file at: %@", self.logTag, filePath); + continue; + } + DDLogVerbose(@"%@ temp file: %@, %@", + self.logTag, + filePath, + [dateFormatter stringFromDate:attributes.fileModificationDate]); + } + } +#endif + + NSString *legacyAttachmentsDirPath = TSAttachmentStream.legacyAttachmentsDirPath; + NSString *sharedDataAttachmentsDirPath = TSAttachmentStream.sharedDataAttachmentsDirPath; + NSSet *_Nullable legacyAttachmentFilePaths = [self filePathsInDirectorySafe:legacyAttachmentsDirPath]; + if (!legacyAttachmentFilePaths || !self.isMainAppAndActive) { + return nil; + } + NSSet *_Nullable sharedDataAttachmentFilePaths = + [self filePathsInDirectorySafe:sharedDataAttachmentsDirPath]; + if (!sharedDataAttachmentFilePaths || !self.isMainAppAndActive) { + return nil; + } + + NSString *legacyProfileAvatarsDirPath = OWSUserProfile.legacyProfileAvatarsDirPath; + NSString *sharedDataProfileAvatarsDirPath = OWSUserProfile.sharedDataProfileAvatarsDirPath; + NSSet *_Nullable legacyProfileAvatarsFilePaths = + [self filePathsInDirectorySafe:legacyProfileAvatarsDirPath]; + if (!legacyProfileAvatarsFilePaths || !self.isMainAppAndActive) { + return nil; + } + NSSet *_Nullable sharedDataProfileAvatarFilePaths = + [self filePathsInDirectorySafe:sharedDataProfileAvatarsDirPath]; + if (!sharedDataProfileAvatarFilePaths || !self.isMainAppAndActive) { + return nil; + } + + NSMutableSet *allFilePaths = [NSMutableSet new]; + [allFilePaths unionSet:legacyAttachmentFilePaths]; + [allFilePaths unionSet:sharedDataAttachmentFilePaths]; + [allFilePaths unionSet:legacyProfileAvatarsFilePaths]; + [allFilePaths unionSet:sharedDataProfileAvatarFilePaths]; + [allFilePaths addObjectsFromArray:tempFilePaths]; + + NSSet *profileAvatarFilePaths = [OWSUserProfile allProfileAvatarFilePaths]; + + if (!self.isMainAppAndActive) { + return nil; + } + + NSNumber *_Nullable totalFileSize = [self fileSizeOfFilePathsSafe:allFilePaths.allObjects]; + + if (!totalFileSize || !self.isMainAppAndActive) { + return nil; + } + + NSUInteger fileCount = allFilePaths.count; + + // Attachments + __block int attachmentStreamCount = 0; + NSMutableSet *allAttachmentFilePaths = [NSMutableSet new]; + NSMutableSet *allAttachmentIds = [NSMutableSet new]; + // Threads + __block NSSet *threadIds; + // Messages + NSMutableSet *orphanInteractionIds = [NSMutableSet new]; + NSMutableSet *messageAttachmentIds = [NSMutableSet new]; + NSMutableSet *quotedReplyThumbnailAttachmentIds = [NSMutableSet new]; + NSMutableSet *contactShareAvatarAttachmentIds = [NSMutableSet new]; + [databaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + [transaction + enumerateKeysAndObjectsInCollection:TSAttachmentStream.collection + usingBlock:^(NSString *key, TSAttachment *attachment, BOOL *stop) { + if (!self.isMainAppAndActive) { + shouldAbort = YES; + *stop = YES; + return; + } + if (![attachment isKindOfClass:[TSAttachmentStream class]]) { + return; + } + [allAttachmentIds addObject:attachment.uniqueId]; + + TSAttachmentStream *attachmentStream = (TSAttachmentStream *)attachment; + attachmentStreamCount++; + NSString *_Nullable filePath = [attachmentStream filePath]; + if (filePath) { + [allAttachmentFilePaths addObject:filePath]; + } else { + OWSProdLogAndFail(@"%@ attachment has no file path.", self.logTag); + } + + NSString *_Nullable thumbnailPath = [attachmentStream thumbnailPath]; + if (thumbnailPath.length > 0) { + [allAttachmentFilePaths addObject:thumbnailPath]; + } + }]; + + if (shouldAbort) { + return; + } + + threadIds = [NSSet setWithArray:[transaction allKeysInCollection:TSThread.collection]]; + + [transaction + enumerateKeysAndObjectsInCollection:TSMessage.collection + usingBlock:^(NSString *key, TSInteraction *interaction, BOOL *stop) { + if (!self.isMainAppAndActive) { + shouldAbort = YES; + *stop = YES; + return; + } + if (interaction.uniqueThreadId.length < 1 + || ![threadIds containsObject:interaction.uniqueThreadId]) { + [orphanInteractionIds addObject:interaction.uniqueId]; + } + + if (![interaction isKindOfClass:[TSMessage class]]) { + return; + } + + TSMessage *message = (TSMessage *)interaction; + if (message.attachmentIds.count > 0) { + [messageAttachmentIds addObjectsFromArray:message.attachmentIds]; + } + + TSQuotedMessage *_Nullable quotedMessage = message.quotedMessage; + if (quotedMessage) { + [quotedReplyThumbnailAttachmentIds + addObjectsFromArray:quotedMessage.thumbnailAttachmentStreamIds]; + } + + OWSContact *_Nullable contactShare = message.contactShare; + if (contactShare && contactShare.avatarAttachmentId) { + [contactShareAvatarAttachmentIds + addObject:contactShare.avatarAttachmentId]; + } + }]; + }]; + if (shouldAbort) { + return nil; + } + + DDLogDebug(@"%@ fileCount: %zu", self.logTag, fileCount); + DDLogDebug(@"%@ totalFileSize: %lld", self.logTag, totalFileSize.longLongValue); + DDLogDebug(@"%@ attachmentStreams: %d", self.logTag, attachmentStreamCount); + DDLogDebug(@"%@ attachmentStreams with file paths: %zu", self.logTag, allAttachmentFilePaths.count); + + NSMutableSet *orphanFilePaths = [allFilePaths mutableCopy]; + [orphanFilePaths minusSet:allAttachmentFilePaths]; + [orphanFilePaths minusSet:profileAvatarFilePaths]; + NSMutableSet *missingAttachmentFilePaths = [allAttachmentFilePaths mutableCopy]; + [missingAttachmentFilePaths minusSet:allFilePaths]; + + DDLogDebug(@"%@ orphan file paths: %zu", self.logTag, orphanFilePaths.count); + DDLogDebug(@"%@ missing attachment file paths: %zu", self.logTag, missingAttachmentFilePaths.count); + + [self printPaths:orphanFilePaths.allObjects label:@"orphan file paths"]; + [self printPaths:missingAttachmentFilePaths.allObjects label:@"missing attachment file paths"]; + + DDLogDebug(@"%@ attachmentIds: %zu", self.logTag, allAttachmentIds.count); + DDLogDebug(@"%@ messageAttachmentIds: %zu", self.logTag, messageAttachmentIds.count); + DDLogDebug(@"%@ quotedReplyThumbnailAttachmentIds: %zu", self.logTag, quotedReplyThumbnailAttachmentIds.count); + DDLogDebug(@"%@ contactShareAvatarAttachmentIds: %zu", self.logTag, contactShareAvatarAttachmentIds.count); + + NSMutableSet *orphanAttachmentIds = [allAttachmentIds mutableCopy]; + [orphanAttachmentIds minusSet:messageAttachmentIds]; + [orphanAttachmentIds minusSet:quotedReplyThumbnailAttachmentIds]; + [orphanAttachmentIds minusSet:contactShareAvatarAttachmentIds]; + NSMutableSet *missingAttachmentIds = [messageAttachmentIds mutableCopy]; + [missingAttachmentIds minusSet:allAttachmentIds]; + + DDLogDebug(@"%@ orphan attachmentIds: %zu", self.logTag, orphanAttachmentIds.count); + DDLogDebug(@"%@ missing attachmentIds: %zu", self.logTag, missingAttachmentIds.count); + DDLogDebug(@"%@ orphan interactions: %zu", self.logTag, orphanInteractionIds.count); + + OWSOrphanData *result = [OWSOrphanData new]; + result.interactionIds = [orphanInteractionIds copy]; + result.attachmentIds = [orphanAttachmentIds copy]; + result.filePaths = [orphanFilePaths copy]; + return result; +} + ++ (void)auditOnLaunchIfNecessary +{ + OWSAssertIsOnMainThread(); + + OWSPrimaryStorage *primaryStorage = [OWSPrimaryStorage sharedManager]; + YapDatabaseConnection *databaseConnection = primaryStorage.newDatabaseConnection; + + // In production, only clean up once per app version. +#ifndef DEBUG + NSString *_Nullable lastCleaningVersion = + [databaseConnection stringForKey:OWSOrphanDataCleaner_LastCleaningVersionKey + inCollection:OWSOrphanDataCleaner_Collection]; + NSString *currentAppVersion = AppVersion.sharedInstance.currentAppVersion; + if (lastCleaningVersion && [lastCleaningVersion isEqualToString:currentAppVersion]) { + DDLogVerbose(@"%@ skipping orphan data cleanup; already done on %@.", self.logTag, currentAppVersion); + return; + } +#endif + + // If we want to be cautious, we can disable orphan deletion using + // flag - the cleanup will just be a dry run with logging. + BOOL shouldRemoveOrphans = YES; + [self auditAndCleanup:shouldRemoveOrphans databaseConnection:databaseConnection]; +} + ++ (void)auditAndCleanup:(BOOL)shouldRemoveOrphans +{ + OWSPrimaryStorage *primaryStorage = [OWSPrimaryStorage sharedManager]; + YapDatabaseConnection *databaseConnection = primaryStorage.newDatabaseConnection; + + [self auditAndCleanup:shouldRemoveOrphans databaseConnection:databaseConnection]; +} + +// We use the lowest priority possible. ++ (dispatch_queue_t)workQueue +{ + return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0); +} + ++ (void)auditAndCleanup:(BOOL)shouldRemoveOrphans databaseConnection:(YapDatabaseConnection *)databaseConnection +{ + OWSAssertIsOnMainThread(); + OWSAssert(databaseConnection); + + if (!AppReadiness.isAppReady) { + OWSProdLogAndFail(@"%@ can't audit orphan data until app is ready.", self.logTag); + return; + } + if (!CurrentAppContext().isMainApp) { + OWSProdLogAndFail(@"%@ can't audit orphan data in app extensions.", self.logTag); + return; + } + + // Orphan cleanup has two risks: + // + // * As a long-running process that involves access to the + // shared data container, it could cause 0xdead10cc. + // * It could accidentally delete data still in use, + // e.g. a profile avatar which has been saved to disk + // but whose OWSUserProfile hasn't been saved yet. + // + // To prevent 0xdead10cc, the cleaner continually checks + // whether the app has resigned active. If so, it aborts. + // Each phase (search, re-search, processing) retries N times, + // then gives up until the next app launch. + // + // To prevent accidental data deletion, we take the following + // measures: + // + // * Only cleanup data of the following types (which should + // include all relevant app data): profile avatar, + // attachment, temporary files (including temporary + // attachments). + // * We don't delete any data created more recently than N seconds + // _before_ when the app launched. This prevents any stray data + // currently in use by the app from being accidentally cleaned + // up. + const NSInteger kMaxRetries = 3; + [self findOrphanDataWithRetries:kMaxRetries + databaseConnection:databaseConnection + success:^(OWSOrphanData *orphanData) { + [self processOrphans:orphanData + remainingRetries:kMaxRetries + databaseConnection:databaseConnection + shouldRemoveOrphans:shouldRemoveOrphans + success:^{ + DDLogInfo(@"%@ Completed orphan data cleanup.", self.logTag); + + [databaseConnection setObject:AppVersion.sharedInstance.currentAppVersion + forKey:OWSOrphanDataCleaner_LastCleaningVersionKey + inCollection:OWSOrphanDataCleaner_Collection]; + } + failure:^{ + DDLogInfo(@"%@ Aborting orphan data cleanup.", self.logTag); + }]; + } + failure:^{ + DDLogInfo(@"%@ Aborting orphan data cleanup.", self.logTag); + }]; +} + +// Returns NO on failure, usually indicating that orphan processing +// aborted due to the app resigning active. This method is extremely careful to +// abort if the app resigns active, in order to avoid 0xdead10cc crashes. ++ (void)processOrphans:(OWSOrphanData *)orphanData + remainingRetries:(NSInteger)remainingRetries + databaseConnection:(YapDatabaseConnection *)databaseConnection + shouldRemoveOrphans:(BOOL)shouldRemoveOrphans + success:(dispatch_block_t)success + failure:(dispatch_block_t)failure +{ + OWSAssert(databaseConnection); + OWSAssert(orphanData); + + if (remainingRetries < 1) { + DDLogInfo(@"%@ Aborting orphan data audit.", self.logTag); + dispatch_async(self.workQueue, ^{ + failure(); + }); + return; + } + + // Wait until the app is active... + [CurrentAppContext() runNowOrWhenMainAppIsActive:^{ + // ...but perform the work off the main thread. + dispatch_async(self.workQueue, ^{ + if ([self processOrphansSync:orphanData + databaseConnection:databaseConnection + shouldRemoveOrphans:shouldRemoveOrphans]) { + success(); + return; + } else { + [self processOrphans:orphanData + remainingRetries:remainingRetries - 1 + databaseConnection:databaseConnection + shouldRemoveOrphans:shouldRemoveOrphans + success:success + failure:failure]; + } + }); + }]; +} + +// Returns NO on failure, usually indicating that orphan processing +// aborted due to the app resigning active. This method is extremely careful to +// abort if the app resigns active, in order to avoid 0xdead10cc crashes. ++ (BOOL)processOrphansSync:(OWSOrphanData *)orphanData + databaseConnection:(YapDatabaseConnection *)databaseConnection + shouldRemoveOrphans:(BOOL)shouldRemoveOrphans +{ + OWSAssert(databaseConnection); + OWSAssert(orphanData); + + __block BOOL shouldAbort = NO; + + // We need to avoid cleaning up new attachments and files that are still in the process of + // being created/written, so we don't clean up anything recent. + const NSTimeInterval kMinimumOrphanAgeSeconds = CurrentAppContext().isRunningTests ? 0.f : 15 * kMinuteInterval; + NSDate *appLaunchTime = AppVersion.sharedInstance.appLaunchTime; + NSTimeInterval thresholdTimestamp = appLaunchTime.timeIntervalSince1970 - kMinimumOrphanAgeSeconds; + NSDate *thresholdDate = [NSDate dateWithTimeIntervalSince1970:thresholdTimestamp]; + [databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + NSUInteger interactionsRemoved = 0; + for (NSString *interactionId in orphanData.interactionIds) { + if (!self.isMainAppAndActive) { + shouldAbort = YES; + return; + } + TSInteraction *_Nullable interaction = + [TSInteraction fetchObjectWithUniqueID:interactionId transaction:transaction]; + if (!interaction) { + // This could just be a race condition, but it should be very unlikely. + DDLogWarn(@"%@ Could not load interaction: %@", self.logTag, interactionId); + continue; + } + // Don't delete interactions which were created in the last N minutes. + NSDate *creationDate = [NSDate ows_dateWithMillisecondsSince1970:interaction.timestamp]; + if ([creationDate isAfterDate:thresholdDate]) { + DDLogInfo(@"%@ Skipping orphan interaction due to age: %f", + self.logTag, + fabs(creationDate.timeIntervalSinceNow)); + continue; + } + DDLogInfo(@"%@ Removing orphan message: %@", self.logTag, interaction.uniqueId); + interactionsRemoved++; + if (!shouldRemoveOrphans) { + continue; + } + [interaction removeWithTransaction:transaction]; + } + DDLogInfo(@"%@ Deleted orphan interactions: %zu", self.logTag, interactionsRemoved); + + NSUInteger attachmentsRemoved = 0; + for (NSString *attachmentId in orphanData.attachmentIds) { + if (!self.isMainAppAndActive) { + shouldAbort = YES; + return; + } + TSAttachment *_Nullable attachment = + [TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction]; + if (!attachment) { + // This can happen on launch since we sync contacts/groups, especially if you have a lot of attachments + // to churn through, it's likely it's been deleted since starting this job. + DDLogWarn(@"%@ Could not load attachment: %@", self.logTag, attachmentId); + continue; + } + if (![attachment isKindOfClass:[TSAttachmentStream class]]) { + continue; + } + TSAttachmentStream *attachmentStream = (TSAttachmentStream *)attachment; + // Don't delete attachments which were created in the last N minutes. + NSDate *creationDate = attachmentStream.creationTimestamp; + if ([creationDate isAfterDate:thresholdDate]) { + DDLogInfo(@"%@ Skipping orphan attachment due to age: %f", + self.logTag, + fabs(creationDate.timeIntervalSinceNow)); + continue; + } + DDLogInfo(@"%@ Removing orphan attachmentStream: %@", self.logTag, attachmentStream.uniqueId); + attachmentsRemoved++; + if (!shouldRemoveOrphans) { + continue; + } + [attachmentStream removeWithTransaction:transaction]; + } + DDLogInfo(@"%@ Deleted orphan attachments: %zu", self.logTag, attachmentsRemoved); + }]; + + if (shouldAbort) { + return nil; + } + + NSUInteger filesRemoved = 0; + NSArray *filePaths = [orphanData.filePaths.allObjects sortedArrayUsingSelector:@selector(compare:)]; + for (NSString *filePath in filePaths) { + if (!self.isMainAppAndActive) { + return nil; + } + + NSError *error; + NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:&error]; + if (!attributes || error) { + OWSProdLogAndFail(@"%@ Could not get attributes of file at: %@", self.logTag, filePath); + continue; + } + // Don't delete files which were created in the last N minutes. + NSDate *creationDate = attributes.fileModificationDate; + if ([creationDate isAfterDate:thresholdDate]) { + DDLogInfo(@"%@ Skipping orphan attachment file due to age: %f", + self.logTag, + fabs([creationDate timeIntervalSinceNow])); + continue; + } + DDLogInfo(@"%@ Deleting orphan attachment file: %@", self.logTag, filePath); + filesRemoved++; + if (!shouldRemoveOrphans) { + continue; + } + [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error]; + if (error) { + OWSProdLogAndFail(@"%@ Could not remove orphan file at: %@", self.logTag, filePath); + } + } + DDLogInfo(@"%@ Deleted orphan attachment files: %zu", self.logTag, filesRemoved); + + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/SignalMessaging/environment/AppSetup.m b/SignalMessaging/environment/AppSetup.m index bf9f372612..4064b9f2a1 100644 --- a/SignalMessaging/environment/AppSetup.m +++ b/SignalMessaging/environment/AppSetup.m @@ -58,6 +58,7 @@ NS_ASSUME_NONNULL_BEGIN migrationCompletion(); + OWSAssert(backgroundTask); backgroundTask = nil; }]; }]; diff --git a/SignalMessaging/environment/Environment.m b/SignalMessaging/environment/Environment.m index 7756b2061b..f8d2300940 100644 --- a/SignalMessaging/environment/Environment.m +++ b/SignalMessaging/environment/Environment.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "Environment.h" diff --git a/SignalMessaging/environment/VersionMigrations.m b/SignalMessaging/environment/VersionMigrations.m index b9312489b5..42ed27e45d 100644 --- a/SignalMessaging/environment/VersionMigrations.m +++ b/SignalMessaging/environment/VersionMigrations.m @@ -40,8 +40,8 @@ NS_ASSUME_NONNULL_BEGIN OWSAssert([Environment current]); OWSAssert(completion); - NSString *previousVersion = AppVersion.instance.lastAppVersion; - NSString *currentVersion = AppVersion.instance.currentAppVersion; + NSString *previousVersion = AppVersion.sharedInstance.lastAppVersion; + NSString *currentVersion = AppVersion.sharedInstance.currentAppVersion; DDLogInfo(@"%@ Checking migrations. currentVersion: %@, lastRanVersion: %@", self.logTag, diff --git a/SignalMessaging/profiles/OWSUserProfile.h b/SignalMessaging/profiles/OWSUserProfile.h index 1d68916aa6..d63ccd39ae 100644 --- a/SignalMessaging/profiles/OWSUserProfile.h +++ b/SignalMessaging/profiles/OWSUserProfile.h @@ -71,6 +71,7 @@ extern NSString *const kLocalProfileUniqueId; + (nullable NSError *)migrateToSharedData; + (NSString *)profileAvatarsDirPath; + (void)resetProfileStorage; ++ (NSSet *)allProfileAvatarFilePaths; @end diff --git a/SignalMessaging/profiles/OWSUserProfile.m b/SignalMessaging/profiles/OWSUserProfile.m index 180ab4925e..daa4648d2e 100644 --- a/SignalMessaging/profiles/OWSUserProfile.m +++ b/SignalMessaging/profiles/OWSUserProfile.m @@ -12,6 +12,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -437,6 +438,33 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; } } ++ (NSSet *)allProfileAvatarFilePaths +{ + NSString *profileAvatarsDirPath = self.profileAvatarsDirPath; + NSMutableSet *profileAvatarFilePaths = [NSMutableSet new]; + + [OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + [OWSUserProfile + enumerateCollectionObjectsWithTransaction:transaction + usingBlock:^(id object, BOOL *stop) { + if (![object isKindOfClass:[OWSUserProfile class]]) { + OWSProdLogAndFail(@"%@ unexpected object in user profiles: %@", + self.logTag, + [object class]); + return; + } + OWSUserProfile *userProfile = object; + if (!userProfile.avatarFileName) { + return; + } + NSString *filePath = [profileAvatarsDirPath + stringByAppendingPathComponent:userProfile.avatarFileName]; + [profileAvatarFilePaths addObject:filePath]; + }]; + }]; + return [profileAvatarFilePaths copy]; +} + @end NS_ASSUME_NONNULL_END diff --git a/SignalMessaging/views/OWSAlerts.swift b/SignalMessaging/views/OWSAlerts.swift index 344bff32f6..2c3fdfcee2 100644 --- a/SignalMessaging/views/OWSAlerts.swift +++ b/SignalMessaging/views/OWSAlerts.swift @@ -88,7 +88,7 @@ import Foundation // Don't show the nag to users who have just launched // the app for the first time. - guard AppVersion.instance().lastAppVersion != nil else { + guard AppVersion.sharedInstance().lastAppVersion != nil else { return } diff --git a/SignalServiceKit/src/Messages/Attachments/OWSAttachmentsProcessor.m b/SignalServiceKit/src/Messages/Attachments/OWSAttachmentsProcessor.m index 4ceab32f1b..e82355fccd 100644 --- a/SignalServiceKit/src/Messages/Attachments/OWSAttachmentsProcessor.m +++ b/SignalServiceKit/src/Messages/Attachments/OWSAttachmentsProcessor.m @@ -122,7 +122,8 @@ static const CGFloat kAttachmentDownloadProgressTheta = 0.001f; { OWSAssert(transaction); - __block OWSBackgroundTask *backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; + __block OWSBackgroundTask *_Nullable backgroundTask = + [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; [self setAttachment:attachment isDownloadingInMessage:message transaction:transaction]; @@ -132,6 +133,7 @@ static const CGFloat kAttachmentDownloadProgressTheta = 0.001f; [self setAttachment:attachment didFailInMessage:message error:error]; failureHandler(error); + OWSAssert(backgroundTask); backgroundTask = nil; }); }; @@ -144,6 +146,7 @@ static const CGFloat kAttachmentDownloadProgressTheta = 0.001f; [message touch]; } + OWSAssert(backgroundTask); backgroundTask = nil; }); }; diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h index 4a3d7ceff6..87304fbab6 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h @@ -62,7 +62,10 @@ NS_ASSUME_NONNULL_BEGIN - (nullable NSString *)readOversizeText; + (void)deleteAttachments; + + (NSString *)attachmentsFolder; ++ (NSString *)legacyAttachmentsDirPath; ++ (NSString *)sharedDataAttachmentsDirPath; - (BOOL)shouldHaveImageSize; - (CGSize)imageSize; diff --git a/SignalServiceKit/src/Messages/Interactions/TSInteraction.m b/SignalServiceKit/src/Messages/Interactions/TSInteraction.m index ab41fd09d4..7f04d4cbb0 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSInteraction.m +++ b/SignalServiceKit/src/Messages/Interactions/TSInteraction.m @@ -110,10 +110,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value) #pragma mark Date operations -- (uint64_t)millisecondsTimestamp { - return self.timestamp; -} - - (NSDate *)dateForSorting { return [NSDate ows_dateWithMillisecondsSince1970:self.timestampForSorting]; diff --git a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m index fe9506f5af..3e0f5d1769 100644 --- a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m +++ b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m @@ -355,12 +355,13 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo return; } - OWSBackgroundTask *backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; + OWSBackgroundTask *_Nullable backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; NSArray *processedJobs = [self processJobs:batchJobs]; [self.finder removeJobsWithIds:processedJobs.uniqueIds]; + OWSAssert(backgroundTask); backgroundTask = nil; DDLogVerbose(@"%@ completed %lu/%lu jobs. %lu jobs left.", diff --git a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m index ef2c4767e8..5abcc2d8df 100644 --- a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m +++ b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m @@ -137,6 +137,7 @@ void AssertIsOnDisappearingMessagesQueue() DDLogDebug(@"%@ Removed %lu expired messages", self.logTag, (unsigned long)expirationCount); + OWSAssert(backgroundTask); backgroundTask = nil; return expirationCount; } @@ -223,8 +224,8 @@ void AssertIsOnDisappearingMessagesQueue() OWSAssert(timestampForSorting > 0); OWSAssert(transaction); - __block OWSBackgroundTask *_Nullable backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; - + OWSBackgroundTask *_Nullable backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; + // Become eventually consistent in the case that the remote changed their settings at the same time. // Also in case remote doesn't support expiring messages OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration = @@ -256,6 +257,7 @@ void AssertIsOnDisappearingMessagesQueue() createdInExistingGroup:createdInExistingGroup]; [infoMessage saveWithTransaction:transaction]; + OWSAssert(backgroundTask); backgroundTask = nil; } diff --git a/SignalServiceKit/src/Messages/OWSMessageReceiver.m b/SignalServiceKit/src/Messages/OWSMessageReceiver.m index 427925ac22..0c922e46f1 100644 --- a/SignalServiceKit/src/Messages/OWSMessageReceiver.m +++ b/SignalServiceKit/src/Messages/OWSMessageReceiver.m @@ -307,7 +307,8 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin return; } - __block OWSBackgroundTask *backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; + __block OWSBackgroundTask *_Nullable backgroundTask = + [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; [self processJob:job completion:^(BOOL success) { @@ -317,6 +318,7 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin success ? @"decrypted" : @"failed to decrypt", (unsigned long)[OWSMessageDecryptJob numberOfKeysInCollection]); [self drainQueueWorkStep]; + OWSAssert(backgroundTask); backgroundTask = nil; }]; } diff --git a/SignalServiceKit/src/Network/WebSockets/TSSocketManager.m b/SignalServiceKit/src/Network/WebSockets/TSSocketManager.m index 2960f725a2..2f27cccc6f 100644 --- a/SignalServiceKit/src/Network/WebSockets/TSSocketManager.m +++ b/SignalServiceKit/src/Network/WebSockets/TSSocketManager.m @@ -732,7 +732,8 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_ if ([message.path isEqualToString:@"/api/v1/message"] && [message.verb isEqualToString:@"PUT"]) { - __block OWSBackgroundTask *backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; + __block OWSBackgroundTask *_Nullable backgroundTask = + [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @try { @@ -743,6 +744,7 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_ if (!decryptedPayload) { DDLogWarn(@"%@ Failed to decrypt incoming payload or bad HMAC", self.logTag); [self sendWebSocketMessageAcknowledgement:message]; + OWSAssert(backgroundTask); backgroundTask = nil; return; } @@ -762,6 +764,7 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_ dispatch_async(dispatch_get_main_queue(), ^{ [self sendWebSocketMessageAcknowledgement:message]; + OWSAssert(backgroundTask); backgroundTask = nil; }); }); diff --git a/SignalServiceKit/src/Storage/OWSIncomingMessageFinder.m b/SignalServiceKit/src/Storage/OWSIncomingMessageFinder.m index 42b1142006..e1e522076c 100644 --- a/SignalServiceKit/src/Storage/OWSIncomingMessageFinder.m +++ b/SignalServiceKit/src/Storage/OWSIncomingMessageFinder.m @@ -52,7 +52,7 @@ NSString *const OWSIncomingMessageFinderColumnSourceDeviceId = @"OWSIncomingMess - (YapDatabaseConnection *)dbConnection { - @synchronized (self) { + @synchronized(self) { if (!_dbConnection) { _dbConnection = [self.primaryStorage newDatabaseConnection]; } diff --git a/SignalServiceKit/src/Storage/OWSOrphanedDataCleaner.h b/SignalServiceKit/src/Storage/OWSOrphanedDataCleaner.h deleted file mode 100644 index 1b4f8fb2f3..0000000000 --- a/SignalServiceKit/src/Storage/OWSOrphanedDataCleaner.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. -// - -NS_ASSUME_NONNULL_BEGIN - -// Notes: -// -// * On disk, we only bother cleaning up files, not directories. -// * For code simplicity, we don't guarantee that everything is -// cleaned up in a single pass. If an interaction is cleaned up, -// it's attachments might not be cleaned up until the next pass. -// If an attachment is cleaned up, it's file on disk might not -// be cleaned up until the next pass. -@interface OWSOrphanedDataCleaner : NSObject - -- (instancetype)init NS_UNAVAILABLE; - -+ (void)auditAsync; - -// completion, if present, will be invoked on the main thread. -+ (void)auditAndCleanupAsync:(void (^_Nullable)(void))completion; - -+ (NSSet *)filePathsInAttachmentsFolder; - -+ (long long)fileSizeOfFilePaths:(NSArray *)filePaths; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Storage/OWSOrphanedDataCleaner.m b/SignalServiceKit/src/Storage/OWSOrphanedDataCleaner.m deleted file mode 100644 index 64360c25c0..0000000000 --- a/SignalServiceKit/src/Storage/OWSOrphanedDataCleaner.m +++ /dev/null @@ -1,286 +0,0 @@ -// -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. -// - -#import "OWSOrphanedDataCleaner.h" -#import "NSDate+OWS.h" -#import "OWSContact.h" -#import "OWSPrimaryStorage.h" -#import "TSAttachmentStream.h" -#import "TSInteraction.h" -#import "TSMessage.h" -#import "TSQuotedMessage.h" -#import "TSThread.h" -#import - -NS_ASSUME_NONNULL_BEGIN - -@implementation OWSOrphanedDataCleaner - -+ (void)auditAsync -{ - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [OWSOrphanedDataCleaner auditAndCleanup:NO completion:nil]; - }); -} - -+ (void)auditAndCleanupAsync:(void (^_Nullable)(void))completion -{ - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [OWSOrphanedDataCleaner auditAndCleanup:YES completion:completion]; - }); -} - -// This method finds and optionally cleans up: -// -// * Orphan messages (with no thread). -// * Orphan attachments (with no message). -// * Orphan attachment files (with no attachment). -// * Missing attachment files (cannot be cleaned up). -// These are attachments which have no file on disk. They should be extremely rare - -// the only cases I have seen are probably due to debugging. -// They can't be cleaned up - we don't want to delete the TSAttachmentStream or -// its corresponding message. Better that the broken message shows up in the -// conversation view. -+ (void)auditAndCleanup:(BOOL)shouldCleanup completion:(void (^_Nullable)(void))completion -{ - NSSet *diskFilePaths = [self filePathsInAttachmentsFolder]; - long long totalFileSize = [self fileSizeOfFilePaths:diskFilePaths.allObjects]; - NSUInteger fileCount = diskFilePaths.count; - - OWSPrimaryStorage *primaryStorage = [OWSPrimaryStorage sharedManager]; - YapDatabaseConnection *databaseConnection = primaryStorage.newDatabaseConnection; - - __block int attachmentStreamCount = 0; - NSMutableSet *attachmentFilePaths = [NSMutableSet new]; - NSMutableSet *attachmentIds = [NSMutableSet new]; - [databaseConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { - [transaction enumerateKeysAndObjectsInCollection:TSAttachmentStream.collection - usingBlock:^(NSString *key, TSAttachment *attachment, BOOL *stop) { - [attachmentIds addObject:attachment.uniqueId]; - if (![attachment isKindOfClass:[TSAttachmentStream class]]) { - return; - } - TSAttachmentStream *attachmentStream - = (TSAttachmentStream *)attachment; - attachmentStreamCount++; - NSString *_Nullable filePath = [attachmentStream filePath]; - OWSAssert(filePath); - [attachmentFilePaths addObject:filePath]; - - NSString *_Nullable thumbnailPath = [attachmentStream thumbnailPath]; - if (thumbnailPath.length > 0) { - [attachmentFilePaths addObject:thumbnailPath]; - } - }]; - }]; - - DDLogDebug(@"%@ fileCount: %lu", self.logTag, (unsigned long)fileCount); - DDLogDebug(@"%@ totalFileSize: %lld", self.logTag, totalFileSize); - DDLogDebug(@"%@ attachmentStreams: %d", self.logTag, attachmentStreamCount); - DDLogDebug(@"%@ attachmentStreams with file paths: %lu", self.logTag, (unsigned long)attachmentFilePaths.count); - - NSMutableSet *orphanDiskFilePaths = [diskFilePaths mutableCopy]; - [orphanDiskFilePaths minusSet:attachmentFilePaths]; - NSMutableSet *missingAttachmentFilePaths = [attachmentFilePaths mutableCopy]; - [missingAttachmentFilePaths minusSet:diskFilePaths]; - - DDLogDebug(@"%@ orphan disk file paths: %lu", self.logTag, (unsigned long)orphanDiskFilePaths.count); - DDLogDebug(@"%@ missing attachment file paths: %lu", self.logTag, (unsigned long)missingAttachmentFilePaths.count); - - [self printPaths:orphanDiskFilePaths.allObjects label:@"orphan disk file paths"]; - [self printPaths:missingAttachmentFilePaths.allObjects label:@"missing attachment file paths"]; - - __block NSMutableSet *threadIds; - [databaseConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { - threadIds = [[NSMutableSet alloc] initWithArray:[transaction allKeysInCollection:TSThread.collection]]; - }]; - - NSMutableSet *orphanInteractionIds = [NSMutableSet new]; - NSMutableSet *messageAttachmentIds = [NSMutableSet new]; - NSMutableSet *quotedReplyThumbnailAttachmentIds = [NSMutableSet new]; - NSMutableSet *contactShareAvatarAttachmentIds = [NSMutableSet new]; - - [databaseConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { - [transaction enumerateKeysAndObjectsInCollection:TSMessage.collection - usingBlock:^(NSString *key, TSInteraction *interaction, BOOL *stop) { - if (![threadIds containsObject:interaction.uniqueThreadId]) { - [orphanInteractionIds addObject:interaction.uniqueId]; - } - - if (![interaction isKindOfClass:[TSMessage class]]) { - return; - } - - TSMessage *message = (TSMessage *)interaction; - if (message.attachmentIds.count > 0) { - [messageAttachmentIds addObjectsFromArray:message.attachmentIds]; - } - - TSQuotedMessage *_Nullable quotedMessage = message.quotedMessage; - if (quotedMessage) { - [quotedReplyThumbnailAttachmentIds - addObjectsFromArray:quotedMessage - .thumbnailAttachmentStreamIds]; - } - - OWSContact *_Nullable contactShare = message.contactShare; - if (contactShare && contactShare.avatarAttachmentId) { - [contactShareAvatarAttachmentIds - addObject:contactShare.avatarAttachmentId]; - } - }]; - }]; - - DDLogDebug(@"%@ attachmentIds: %lu", self.logTag, (unsigned long)attachmentIds.count); - DDLogDebug(@"%@ messageAttachmentIds: %lu", self.logTag, (unsigned long)messageAttachmentIds.count); - DDLogDebug(@"%@ quotedReplyThumbnailAttachmentIds: %lu", - self.logTag, - (unsigned long)quotedReplyThumbnailAttachmentIds.count); - DDLogDebug( - @"%@ contactShareAvatarAttachmentIds: %lu", self.logTag, (unsigned long)contactShareAvatarAttachmentIds.count); - - NSMutableSet *orphanAttachmentIds = [attachmentIds mutableCopy]; - [orphanAttachmentIds minusSet:messageAttachmentIds]; - [orphanAttachmentIds minusSet:quotedReplyThumbnailAttachmentIds]; - [orphanAttachmentIds minusSet:contactShareAvatarAttachmentIds]; - NSMutableSet *missingAttachmentIds = [messageAttachmentIds mutableCopy]; - [missingAttachmentIds minusSet:attachmentIds]; - - DDLogDebug(@"%@ orphan attachmentIds: %lu", self.logTag, (unsigned long)orphanAttachmentIds.count); - DDLogDebug(@"%@ missing attachmentIds: %lu", self.logTag, (unsigned long)missingAttachmentIds.count); - DDLogDebug(@"%@ orphan interactions: %lu", self.logTag, (unsigned long)orphanInteractionIds.count); - - // We need to avoid cleaning up new attachments and files that are still in the process of - // being created/written, so we don't clean up anything recent. - - const NSTimeInterval kMinimumOrphanAge = CurrentAppContext().isRunningTests ? 0.f : 15 * kMinuteInterval; - - if (!shouldCleanup) { - return; - } - - [databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - for (NSString *interactionId in orphanInteractionIds) { - TSInteraction *interaction = [TSInteraction fetchObjectWithUniqueID:interactionId transaction:transaction]; - if (!interaction) { - // This could just be a race condition, but it should be very unlikely. - OWSFail(@"%@ Could not load interaction: %@", self.logTag, interactionId); - continue; - } - DDLogInfo(@"%@ Removing orphan message: %@", self.logTag, interaction.uniqueId); - [interaction removeWithTransaction:transaction]; - } - for (NSString *attachmentId in orphanAttachmentIds) { - TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction]; - if (!attachment) { - // This can happen on launch since we sync contacts/groups, especially if you have a lot of attachments - // to churn through, it's likely it's been deleted since starting this job. - DDLogWarn(@"%@ Could not load attachment: %@", self.logTag, attachmentId); - continue; - } - if (![attachment isKindOfClass:[TSAttachmentStream class]]) { - continue; - } - TSAttachmentStream *attachmentStream = (TSAttachmentStream *)attachment; - // Don't delete attachments which were created in the last N minutes. - if (fabs([attachmentStream.creationTimestamp timeIntervalSinceNow]) < kMinimumOrphanAge) { - DDLogInfo(@"%@ Skipping orphan attachment due to age: %f", - self.logTag, - fabs([attachmentStream.creationTimestamp timeIntervalSinceNow])); - continue; - } - DDLogInfo(@"%@ Removing orphan attachmentStream from DB: %@", self.logTag, attachmentStream.uniqueId); - [attachmentStream removeWithTransaction:transaction]; - } - }]; - - for (NSString *filePath in orphanDiskFilePaths) { - NSError *error; - NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:&error]; - if (!attributes || error) { - OWSFail(@"%@ Could not get attributes of file at: %@", self.logTag, filePath); - continue; - } - // Don't delete files which were created in the last N minutes. - if (fabs([attributes.fileModificationDate timeIntervalSinceNow]) < kMinimumOrphanAge) { - DDLogInfo(@"%@ Skipping orphan attachment file due to age: %f", - self.logTag, - fabs([attributes.fileModificationDate timeIntervalSinceNow])); - continue; - } - - DDLogInfo(@"%@ Deleting orphan attachment file: %@", self.logTag, filePath); - [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error]; - if (error) { - OWSFail(@"%@ Could not remove orphan file at: %@", self.logTag, filePath); - } - } - - if (completion) { - dispatch_async(dispatch_get_main_queue(), ^{ - completion(); - }); - } -} - -+ (void)printPaths:(NSArray *)paths label:(NSString *)label -{ - for (NSString *path in [paths sortedArrayUsingSelector:@selector(compare:)]) { - DDLogDebug(@"%@ %@: %@", self.logTag, label, path); - } -} - -+ (NSSet *)filePathsInAttachmentsFolder -{ - NSString *attachmentsFolder = [TSAttachmentStream attachmentsFolder]; - DDLogDebug(@"%@ attachmentsFolder: %@", self.logTag, attachmentsFolder); - - return [self filePathsInDirectory:attachmentsFolder]; -} - -+ (NSSet *)filePathsInDirectory:(NSString *)dirPath -{ - NSMutableSet *filePaths = [NSMutableSet new]; - NSError *error; - NSArray *fileNames = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:dirPath error:&error]; - if (error) { - OWSFail(@"%@ contentsOfDirectoryAtPath error: %@", self.logTag, error); - return [NSSet new]; - } - for (NSString *fileName in fileNames) { - NSString *filePath = [dirPath stringByAppendingPathComponent:fileName]; - BOOL isDirectory; - [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory]; - if (isDirectory) { - [filePaths addObjectsFromArray:[self filePathsInDirectory:filePath].allObjects]; - } else { - [filePaths addObject:filePath]; - } - } - return filePaths; -} - -+ (long long)fileSizeOfFilePath:(NSString *)filePath -{ - NSError *error; - NSNumber *fileSize = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:&error][NSFileSize]; - if (error) { - OWSFail(@"%@ attributesOfItemAtPath: %@ error: %@", self.logTag, filePath, error); - return 0; - } - return fileSize.longLongValue; -} - -+ (long long)fileSizeOfFilePaths:(NSArray *)filePaths -{ - long long result = 0; - for (NSString *filePath in filePaths) { - result += [self fileSizeOfFilePath:filePath]; - } - return result; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Util/AppContext.h b/SignalServiceKit/src/Util/AppContext.h index 8b2801491c..6ec9baa26b 100755 --- a/SignalServiceKit/src/Util/AppContext.h +++ b/SignalServiceKit/src/Util/AppContext.h @@ -16,6 +16,7 @@ extern NSString *const OWSApplicationWillResignActiveNotification; extern NSString *const OWSApplicationDidBecomeActiveNotification; typedef void (^BackgroundTaskExpirationHandler)(void); +typedef void (^AppActiveBlock)(void); NSString *NSStringForUIApplicationState(UIApplicationState value); @@ -91,6 +92,8 @@ NSString *NSStringForUIApplicationState(UIApplicationState value); // Should be a NOOP if isMainApp is NO. - (void)setNetworkActivityIndicatorVisible:(BOOL)value; +- (void)runNowOrWhenMainAppIsActive:(AppActiveBlock)block; + @end id CurrentAppContext(void); diff --git a/SignalServiceKit/src/Util/AppReadiness.m b/SignalServiceKit/src/Util/AppReadiness.m index 31491893d1..61a3de3361 100755 --- a/SignalServiceKit/src/Util/AppReadiness.m +++ b/SignalServiceKit/src/Util/AppReadiness.m @@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN @property (atomic) BOOL isAppReady; -@property (nonatomic, nullable) NSMutableArray *appReadyBlocks; +@property (nonatomic) NSMutableArray *appReadyBlocks; @end @@ -39,6 +39,8 @@ NS_ASSUME_NONNULL_BEGIN OWSSingletonAssert(); + self.appReadyBlocks = [NSMutableArray new]; + return self; } @@ -64,9 +66,6 @@ NS_ASSUME_NONNULL_BEGIN return; } - if (!self.appReadyBlocks) { - self.appReadyBlocks = [NSMutableArray new]; - } [self.appReadyBlocks addObject:block]; } @@ -92,10 +91,11 @@ NS_ASSUME_NONNULL_BEGIN OWSAssertIsOnMainThread(); OWSAssert(self.isAppReady); - for (AppReadyBlock block in self.appReadyBlocks) { + NSArray *appReadyBlocks = [self.appReadyBlocks copy]; + [self.appReadyBlocks removeAllObjects]; + for (AppReadyBlock block in appReadyBlocks) { block(); } - self.appReadyBlocks = nil; } @end diff --git a/SignalServiceKit/src/Util/AppVersion.h b/SignalServiceKit/src/Util/AppVersion.h index df84b8b35a..71da4ce720 100755 --- a/SignalServiceKit/src/Util/AppVersion.h +++ b/SignalServiceKit/src/Util/AppVersion.h @@ -4,17 +4,21 @@ @interface AppVersion : NSObject -@property (nonatomic, readonly) NSString *firstAppVersion; -@property (nonatomic, readonly) NSString *lastAppVersion; -@property (nonatomic, readonly) NSString *currentAppVersion; +// The properties are updated immediately after launch. +@property (atomic, readonly) NSString *firstAppVersion; +@property (atomic, readonly) NSString *lastAppVersion; +@property (atomic, readonly) NSString *currentAppVersion; -// Unlike lastAppVersion, this property isn't updated until -// appLaunchDidComplete is called. -@property (nonatomic, readonly) NSString *lastCompletedLaunchAppVersion; -@property (nonatomic, readonly) NSString *lastCompletedLaunchMainAppVersion; -@property (nonatomic, readonly) NSString *lastCompletedLaunchSAEAppVersion; +// There properties aren't updated until appLaunchDidComplete is called. +@property (atomic, readonly) NSString *lastCompletedLaunchAppVersion; +@property (atomic, readonly) NSString *lastCompletedLaunchMainAppVersion; +@property (atomic, readonly) NSString *lastCompletedLaunchSAEAppVersion; -+ (instancetype)instance; +@property (atomic, readonly) NSDate *appLaunchTime; + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)sharedInstance; - (void)mainAppLaunchDidComplete; - (void)saeLaunchDidComplete; diff --git a/SignalServiceKit/src/Util/AppVersion.m b/SignalServiceKit/src/Util/AppVersion.m index a9bcd64a7e..ff99018254 100755 --- a/SignalServiceKit/src/Util/AppVersion.m +++ b/SignalServiceKit/src/Util/AppVersion.m @@ -15,12 +15,13 @@ NSString *const kNSUserDefaults_LastCompletedLaunchAppVersion_SAE @interface AppVersion () -@property (nonatomic) NSString *firstAppVersion; -@property (nonatomic) NSString *lastAppVersion; -@property (nonatomic) NSString *currentAppVersion; -@property (nonatomic) NSString *lastCompletedLaunchAppVersion; -@property (nonatomic) NSString *lastCompletedLaunchMainAppVersion; -@property (nonatomic) NSString *lastCompletedLaunchSAEAppVersion; +@property (atomic) NSString *firstAppVersion; +@property (atomic) NSString *lastAppVersion; +@property (atomic) NSString *currentAppVersion; + +@property (atomic) NSString *lastCompletedLaunchAppVersion; +@property (atomic) NSString *lastCompletedLaunchMainAppVersion; +@property (atomic) NSString *lastCompletedLaunchSAEAppVersion; @end @@ -28,7 +29,8 @@ NSString *const kNSUserDefaults_LastCompletedLaunchAppVersion_SAE @implementation AppVersion -+ (instancetype)instance { ++ (instancetype)sharedInstance +{ static AppVersion *instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -39,6 +41,10 @@ NSString *const kNSUserDefaults_LastCompletedLaunchAppVersion_SAE } - (void)configure { + OWSAssertIsOnMainThread(); + + _appLaunchTime = [NSDate new]; + self.currentAppVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; // The version of the app when it was first launched. @@ -78,6 +84,8 @@ NSString *const kNSUserDefaults_LastCompletedLaunchAppVersion_SAE - (void)appLaunchDidComplete { + OWSAssertIsOnMainThread(); + DDLogInfo(@"%@ appLaunchDidComplete", self.logTag); self.lastCompletedLaunchAppVersion = self.currentAppVersion; @@ -90,6 +98,8 @@ NSString *const kNSUserDefaults_LastCompletedLaunchAppVersion_SAE - (void)mainAppLaunchDidComplete { + OWSAssertIsOnMainThread(); + self.lastCompletedLaunchMainAppVersion = self.currentAppVersion; [[NSUserDefaults appUserDefaults] setObject:self.currentAppVersion forKey:kNSUserDefaults_LastCompletedLaunchAppVersion_MainApp]; @@ -99,6 +109,8 @@ NSString *const kNSUserDefaults_LastCompletedLaunchAppVersion_SAE - (void)saeLaunchDidComplete { + OWSAssertIsOnMainThread(); + self.lastCompletedLaunchSAEAppVersion = self.currentAppVersion; [[NSUserDefaults appUserDefaults] setObject:self.currentAppVersion forKey:kNSUserDefaults_LastCompletedLaunchAppVersion_SAE]; diff --git a/SignalShareExtension/ShareViewController.swift b/SignalShareExtension/ShareViewController.swift index 07ba68ad68..9421932144 100644 --- a/SignalShareExtension/ShareViewController.swift +++ b/SignalShareExtension/ShareViewController.swift @@ -44,7 +44,7 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed Logger.info("\(self.logTag) \(#function)") - _ = AppVersion() + _ = AppVersion.sharedInstance() startupLogging() @@ -265,7 +265,7 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed // We don't need to use DeviceSleepManager in the SAE. - AppVersion.instance().saeLaunchDidComplete() + AppVersion.sharedInstance().saeLaunchDidComplete() Environment.current().contactsManager.loadSignalAccountsFromCache() Environment.current().contactsManager.startObserving() @@ -277,7 +277,7 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed OWSProfileManager.shared().ensureLocalProfileCached() - // We don't need to use OWSOrphanedDataCleaner in the SAE. + // We don't need to use OWSOrphanDataCleaner in the SAE. // We don't need to fetch the local profile in the SAE diff --git a/SignalShareExtension/utils/ShareAppExtensionContext.m b/SignalShareExtension/utils/ShareAppExtensionContext.m index 99d2862047..0fcf69175d 100644 --- a/SignalShareExtension/utils/ShareAppExtensionContext.m +++ b/SignalShareExtension/utils/ShareAppExtensionContext.m @@ -205,6 +205,11 @@ NS_ASSUME_NONNULL_BEGIN OWSFail(@"%@ called %s.", self.logTag, __PRETTY_FUNCTION__); } +- (void)runNowOrWhenMainAppIsActive:(AppActiveBlock)block +{ + OWSProdLogAndFail(@"%@ cannot run main app active blocks in share extension.", self.logTag); +} + @end NS_ASSUME_NONNULL_END From 06d84860ae6667096fdc8853cb175235e9e7a50b Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 2 Aug 2018 15:21:59 -0400 Subject: [PATCH 2/6] Fix rebase breakage. --- Signal.xcodeproj/project.pbxproj | 287 +++++++++++----------- SignalMessaging/profiles/OWSUserProfile.h | 2 + 2 files changed, 149 insertions(+), 140 deletions(-) diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 299b140fc0..247f5be564 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -35,7 +35,12 @@ 340FC8BB204DAC8D007AEB0F /* OWSAddToContactViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8A1204DAC8D007AEB0F /* OWSAddToContactViewController.m */; }; 340FC8BC204DAC8D007AEB0F /* FingerprintViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8A2204DAC8D007AEB0F /* FingerprintViewController.m */; }; 340FC8BD204DAC8D007AEB0F /* ShowGroupMembersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8A6204DAC8D007AEB0F /* ShowGroupMembersViewController.m */; }; + 340FC8C0204DB7D2007AEB0F /* OWSBackupExportJob.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8BF204DB7D2007AEB0F /* OWSBackupExportJob.m */; }; 340FC8C5204DE223007AEB0F /* DebugUIBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8C4204DE223007AEB0F /* DebugUIBackup.m */; }; + 340FC8C7204DE64D007AEB0F /* OWSBackupAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8C6204DE64D007AEB0F /* OWSBackupAPI.swift */; }; + 340FC8CA20517B84007AEB0F /* OWSBackupImportJob.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8C820517B84007AEB0F /* OWSBackupImportJob.m */; }; + 340FC8CD20518C77007AEB0F /* OWSBackupJob.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8CC20518C76007AEB0F /* OWSBackupJob.m */; }; + 340FC8D0205BF2FA007AEB0F /* OWSBackupIO.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8CE205BF2FA007AEB0F /* OWSBackupIO.m */; }; 341F2C0F1F2B8AE700D07D6B /* DebugUIMisc.m in Sources */ = {isa = PBXBuildFile; fileRef = 341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */; }; 34219801210612F600C57195 /* iRate.m in Sources */ = {isa = PBXBuildFile; fileRef = 342197FF210612F600C57195 /* iRate.m */; }; 3421980F21061A0700C57195 /* UIColor+JSQMessages.m in Sources */ = {isa = PBXBuildFile; fileRef = 3421980521061A0600C57195 /* UIColor+JSQMessages.m */; }; @@ -76,29 +81,7 @@ 34480B641FD0A98800BC14EF /* UIView+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 34480B601FD0A98800BC14EF /* UIView+OWS.m */; }; 34480B671FD0AA9400BC14EF /* UIFont+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 34480B651FD0AA9400BC14EF /* UIFont+OWS.m */; }; 34480B681FD0AA9400BC14EF /* UIFont+OWS.h in Headers */ = {isa = PBXBuildFile; fileRef = 34480B661FD0AA9400BC14EF /* UIFont+OWS.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3448259D21138BAF00DB4BD8 /* AppUpdateNag.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448255321138BAE00DB4BD8 /* AppUpdateNag.m */; }; - 3448259E21138BAF00DB4BD8 /* RegistrationUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448255521138BAE00DB4BD8 /* RegistrationUtils.m */; }; - 3448259F21138BAF00DB4BD8 /* OWSBackupExportJob.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448255621138BAE00DB4BD8 /* OWSBackupExportJob.m */; }; - 344825A021138BAF00DB4BD8 /* OWSBackupLazyRestoreJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448255921138BAE00DB4BD8 /* OWSBackupLazyRestoreJob.swift */; }; - 344825A121138BAF00DB4BD8 /* Pastelog.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448255A21138BAE00DB4BD8 /* Pastelog.m */; }; - 344825A221138BAF00DB4BD8 /* OWSScreenLockUI.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448255B21138BAE00DB4BD8 /* OWSScreenLockUI.m */; }; - 344825A921138BAF00DB4BD8 /* UIResponder+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448256B21138BAE00DB4BD8 /* UIResponder+OWS.swift */; }; - 344825AB21138BAF00DB4BD8 /* FunctionalUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448256D21138BAE00DB4BD8 /* FunctionalUtil.m */; }; - 344825AD21138BAF00DB4BD8 /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448256F21138BAE00DB4BD8 /* DateUtil.m */; }; - 344825B121138BAF00DB4BD8 /* TextFieldHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448257421138BAE00DB4BD8 /* TextFieldHelper.swift */; }; - 344825B321138BAF00DB4BD8 /* OWSBackupIO.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448257721138BAE00DB4BD8 /* OWSBackupIO.m */; }; - 344825B421138BAF00DB4BD8 /* OWSBackupImportJob.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448257821138BAE00DB4BD8 /* OWSBackupImportJob.m */; }; - 344825B621138BAF00DB4BD8 /* UIViewController+Permissions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448258021138BAE00DB4BD8 /* UIViewController+Permissions.m */; }; - 344825B721138BAF00DB4BD8 /* OWSBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448258321138BAE00DB4BD8 /* OWSBackup.m */; }; - 344825B821138BAF00DB4BD8 /* MainAppContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448258521138BAE00DB4BD8 /* MainAppContext.m */; }; - 344825B921138BAF00DB4BD8 /* NSString+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448258721138BAE00DB4BD8 /* NSString+OWS.m */; }; - 344825BA21138BAF00DB4BD8 /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448258A21138BAE00DB4BD8 /* Platform.swift */; }; - 344825BB21138BAF00DB4BD8 /* OWSOrphanDataCleaner.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448258B21138BAE00DB4BD8 /* OWSOrphanDataCleaner.m */; }; - 344825BC21138BAF00DB4BD8 /* AppStoreRating.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448258C21138BAE00DB4BD8 /* AppStoreRating.m */; }; - 344825BD21138BAF00DB4BD8 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3448258D21138BAE00DB4BD8 /* Launch Screen.storyboard */; }; - 344825C021138BAF00DB4BD8 /* OWSAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448259421138BAE00DB4BD8 /* OWSAnalytics.swift */; }; - 344825C221138BAF00DB4BD8 /* OWSBackupJob.m in Sources */ = {isa = PBXBuildFile; fileRef = 3448259821138BAE00DB4BD8 /* OWSBackupJob.m */; }; - 344825C321138BAF00DB4BD8 /* OWSBackupAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448259921138BAE00DB4BD8 /* OWSBackupAPI.swift */; }; + 344825C6211390C800DB4BD8 /* OWSOrphanDataCleaner.m in Sources */ = {isa = PBXBuildFile; fileRef = 344825C5211390C800DB4BD8 /* OWSOrphanDataCleaner.m */; }; 344D6CEA20069E070042AF96 /* SelectRecipientViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 344D6CE620069E060042AF96 /* SelectRecipientViewController.h */; }; 344D6CEB20069E070042AF96 /* SelectRecipientViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 344D6CE720069E060042AF96 /* SelectRecipientViewController.m */; }; 344D6CEC20069E070042AF96 /* NewNonContactConversationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 344D6CE820069E070042AF96 /* NewNonContactConversationViewController.m */; }; @@ -198,8 +181,10 @@ 3496744D2076768700080B5F /* OWSMessageBubbleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3496744C2076768700080B5F /* OWSMessageBubbleView.m */; }; 3496744F2076ACD000080B5F /* LongTextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3496744E2076ACCE00080B5F /* LongTextViewController.swift */; }; 34A55F3720485465002CC6DE /* OWS2FARegistrationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */; }; + 34A910601FFEB114000C4745 /* OWSBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A9105F1FFEB114000C4745 /* OWSBackup.m */; }; 34ABB2C42090C59700C727A6 /* OWSResaveCollectionDBMigration.m in Sources */ = {isa = PBXBuildFile; fileRef = 34ABB2C22090C59600C727A6 /* OWSResaveCollectionDBMigration.m */; }; 34ABB2C52090C59700C727A6 /* OWSResaveCollectionDBMigration.h in Headers */ = {isa = PBXBuildFile; fileRef = 34ABB2C32090C59700C727A6 /* OWSResaveCollectionDBMigration.h */; }; + 34B0796D1FCF46B100E248C2 /* MainAppContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B0796B1FCF46B000E248C2 /* MainAppContext.m */; }; 34B3F8751E8DF1700035BE1A /* CallViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F83B1E8DF1700035BE1A /* CallViewController.swift */; }; 34B3F8771E8DF1700035BE1A /* ContactsPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F83E1E8DF1700035BE1A /* ContactsPicker.swift */; }; 34B3F87B1E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8441E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift */; }; @@ -223,6 +208,7 @@ 34C82E5120F8E1F300E9688D /* Theme.h in Headers */ = {isa = PBXBuildFile; fileRef = 34C82E4F20F8E1F000E9688D /* Theme.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34C82E5220F8E1F300E9688D /* Theme.m in Sources */ = {isa = PBXBuildFile; fileRef = 34C82E5020F8E1F100E9688D /* Theme.m */; }; 34CA631B2097806F00E526A0 /* OWSContactShareView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CA631A2097806E00E526A0 /* OWSContactShareView.m */; }; + 34CCAF381F0C0599004084F4 /* AppUpdateNag.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CCAF371F0C0599004084F4 /* AppUpdateNag.m */; }; 34CE88E71F2FB9A10098030F /* ProfileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CE88E61F2FB9A10098030F /* ProfileViewController.m */; }; 34CF0787203E6B78005C4D61 /* busy_tone_ansi.caf in Resources */ = {isa = PBXBuildFile; fileRef = 34CF0783203E6B77005C4D61 /* busy_tone_ansi.caf */; }; 34CF0788203E6B78005C4D61 /* ringback_tone_ansi.caf in Resources */ = {isa = PBXBuildFile; fileRef = 34CF0784203E6B77005C4D61 /* ringback_tone_ansi.caf */; }; @@ -245,6 +231,8 @@ 34D1F0C01F8EC1760066283D /* MessageRecipientStatusUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D1F0BF1F8EC1760066283D /* MessageRecipientStatusUtils.swift */; }; 34D2015120DC160E00A6FD3A /* ContactCellView.h in Headers */ = {isa = PBXBuildFile; fileRef = 34D2014F20DC160D00A6FD3A /* ContactCellView.h */; }; 34D2015220DC160E00A6FD3A /* ContactCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D2015020DC160D00A6FD3A /* ContactCellView.m */; }; + 34D2CCD220618B3000CB1A14 /* OWSBackupLazyRestoreJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D2CCD120618B2F00CB1A14 /* OWSBackupLazyRestoreJob.swift */; }; + 34D2CCDA2062E7D000CB1A14 /* OWSScreenLockUI.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D2CCD92062E7D000CB1A14 /* OWSScreenLockUI.m */; }; 34D2CCDF206939B400CB1A14 /* DebugUIMessagesAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D2CCDB206939B100CB1A14 /* DebugUIMessagesAction.m */; }; 34D2CCE0206939B400CB1A14 /* DebugUIMessagesAssetLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D2CCDC206939B200CB1A14 /* DebugUIMessagesAssetLoader.m */; }; 34D5872F208E2C4200D2255A /* OWS109OutgoingMessageState.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D5872D208E2C4100D2255A /* OWS109OutgoingMessageState.m */; }; @@ -254,6 +242,7 @@ 34D8C0281ED3673300188D7C /* DebugUITableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D8C0261ED3673300188D7C /* DebugUITableViewController.m */; }; 34D8C02B1ED3685800188D7C /* DebugUIContacts.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D8C02A1ED3685800188D7C /* DebugUIContacts.m */; }; 34D920E720E179C200D51158 /* OWSMessageFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D920E620E179C200D51158 /* OWSMessageFooterView.m */; }; + 34D99C931F2937CC00D284D6 /* OWSAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */; }; 34DB0BED2011548B007B313F /* OWSDatabaseConverterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DB0BEC2011548B007B313F /* OWSDatabaseConverterTest.m */; }; 34DBF003206BD5A500025978 /* OWSMessageTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DBEFFF206BD5A400025978 /* OWSMessageTextView.m */; }; 34DBF004206BD5A500025978 /* OWSBubbleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DBF001206BD5A500025978 /* OWSBubbleView.m */; }; @@ -261,6 +250,7 @@ 34E3E5681EC4B19400495BAC /* AudioProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E3E5671EC4B19400495BAC /* AudioProgressView.swift */; }; 34E3EF0D1EFC235B007F6822 /* DebugUIDiskUsage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */; }; 34E3EF101EFC2684007F6822 /* DebugUIPage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E3EF0F1EFC2684007F6822 /* DebugUIPage.m */; }; + 34E5DC8220D8050D00C08145 /* RegistrationUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E5DC8120D8050D00C08145 /* RegistrationUtils.m */; }; 34E88D262098C5AE00A608F4 /* ContactViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E88D252098C5AE00A608F4 /* ContactViewController.swift */; }; 34E8A8D12085238A00B272B1 /* ProtoParsingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E8A8D02085238900B272B1 /* ProtoParsingTest.m */; }; 34F308A21ECB469700BB7697 /* OWSBezierPathView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F308A11ECB469700BB7697 /* OWSBezierPathView.m */; }; @@ -282,6 +272,7 @@ 450C801120AD1CDB00F3A091 /* ReturnToCallViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A60E7220AC674100FB1ABF /* ReturnToCallViewController.swift */; }; 450C801220AD1D5B00F3A091 /* UIDevice+featureSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45BB93371E688E14001E3939 /* UIDevice+featureSupport.swift */; }; 450D19131F85236600970622 /* RemoteVideoView.m in Sources */ = {isa = PBXBuildFile; fileRef = 450D19121F85236600970622 /* RemoteVideoView.m */; }; + 450DF2051E0D74AC003D14BE /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 450DF2041E0D74AC003D14BE /* Platform.swift */; }; 450DF2091E0DD2C6003D14BE /* UserNotificationsAdaptee.swift in Sources */ = {isa = PBXBuildFile; fileRef = 450DF2081E0DD2C6003D14BE /* UserNotificationsAdaptee.swift */; }; 451166C01FD86B98000739BA /* AccountManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 451166BF1FD86B98000739BA /* AccountManager.swift */; }; 451573962061B49500803601 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 451573952061B49500803601 /* GradientView.swift */; }; @@ -321,6 +312,7 @@ 451F8A4B1FD715E1005CB9DA /* OWSGroupAvatarBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 45666EC71D994C0D008FE134 /* OWSGroupAvatarBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 452037D11EE84975004E4CDF /* DebugUISessionState.m in Sources */ = {isa = PBXBuildFile; fileRef = 452037D01EE84975004E4CDF /* DebugUISessionState.m */; }; 4520D8D51D417D8E00123472 /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4520D8D41D417D8E00123472 /* Photos.framework */; }; + 4521C3C01F59F3BA00B4C582 /* TextFieldHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4521C3BF1F59F3BA00B4C582 /* TextFieldHelper.swift */; }; 452314A01F7E9E18003A428C /* DirectionalPanGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4523149F1F7E9E18003A428C /* DirectionalPanGestureRecognizer.swift */; }; 4523D016206EDC2B00A2AB51 /* LRUCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4523D015206EDC2B00A2AB51 /* LRUCache.swift */; }; 452B999020A34B6B006F2F9E /* AddContactShareToExistingContactViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 452B998F20A34B6B006F2F9E /* AddContactShareToExistingContactViewController.swift */; }; @@ -349,17 +341,20 @@ 454A965A1FD6017E008D2A0E /* SignalAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D913491F62D4A500722898 /* SignalAttachment.swift */; }; 454A965B1FD601BF008D2A0E /* MediaMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34CA1C281F7164F700E51C51 /* MediaMessageView.swift */; }; 454A965F1FD60EA3008D2A0E /* OWSFlatButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 454A965E1FD60EA2008D2A0E /* OWSFlatButton.swift */; }; + 454EBAB41F2BE14C00ACE0BB /* OWSAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */; }; 4551DB5A205C562300C8AE75 /* Collection+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4551DB59205C562300C8AE75 /* Collection+OWS.swift */; }; 4556FA681F54AA9500AF40DD /* DebugUIProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4556FA671F54AA9500AF40DD /* DebugUIProfile.swift */; }; 455A16DD1F1FEA0000F86704 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 455A16DB1F1FEA0000F86704 /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 455A16DE1F1FEA0000F86704 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 455A16DC1F1FEA0000F86704 /* MetalKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 455AC69E1F4F8B0300134004 /* ImageCacheTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 455AC69D1F4F8B0300134004 /* ImageCacheTest.swift */; }; 45638BDC1F3DD0D400128435 /* DebugUICalling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45638BDB1F3DD0D400128435 /* DebugUICalling.swift */; }; + 45638BDF1F3DDB2200128435 /* MessageSender+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45638BDE1F3DDB2200128435 /* MessageSender+Promise.swift */; }; 4565ED06200EA29900C46DBB /* VideoPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453034AA200289F50018945D /* VideoPlayerView.swift */; }; 45666F581D9B2880008FE134 /* OWSScrubbingLogFormatterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 45666F571D9B2880008FE134 /* OWSScrubbingLogFormatterTest.m */; }; 456C38961DC7B882007536A7 /* PromiseKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 451DE9F11DC1585F00810E42 /* PromiseKit.framework */; }; 456F6E2F1E261D1000FD2210 /* PeerConnectionClientTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 456F6E2E1E261D1000FD2210 /* PeerConnectionClientTest.swift */; }; 4574A5D61DD6704700C6B692 /* CallService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4574A5D51DD6704700C6B692 /* CallService.swift */; }; + 4579431E1E7C8CE9008ED0C0 /* Pastelog.m in Sources */ = {isa = PBXBuildFile; fileRef = 4579431D1E7C8CE9008ED0C0 /* Pastelog.m */; }; 45794E861E00620000066731 /* CallUIAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45794E851E00620000066731 /* CallUIAdapter.swift */; }; 457C87B82032645C008D52D6 /* DebugUINotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 457C87B72032645C008D52D6 /* DebugUINotifications.swift */; }; 457F671B20746193000EABCD /* QuotedReplyPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 457F671A20746193000EABCD /* QuotedReplyPreview.swift */; }; @@ -380,6 +375,7 @@ 45A6DAD61EBBF85500893231 /* ReminderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A6DAD51EBBF85500893231 /* ReminderView.swift */; }; 45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */; }; 45B27B862037FFB400A539DF /* DebugUIFileBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B27B852037FFB400A539DF /* DebugUIFileBrowser.swift */; }; + 45B5360E206DD8BB00D61655 /* UIResponder+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B5360D206DD8BB00D61655 /* UIResponder+OWS.swift */; }; 45B74A742044AAB600CD42F8 /* aurora-quiet.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 45B74A5B2044AAB300CD42F8 /* aurora-quiet.aifc */; }; 45B74A752044AAB600CD42F8 /* synth-quiet.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 45B74A5C2044AAB300CD42F8 /* synth-quiet.aifc */; }; 45B74A762044AAB600CD42F8 /* keys-quiet.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 45B74A5D2044AAB400CD42F8 /* keys-quiet.aifc */; }; @@ -407,6 +403,8 @@ 45BC829D1FD9C4B400011CF3 /* ShareViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45BC829C1FD9C4B400011CF3 /* ShareViewDelegate.swift */; }; 45BD60821DE9547E00A8F436 /* Contacts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45BD60811DE9547E00A8F436 /* Contacts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 45BE4EA22012AD2000935E59 /* DisappearingTimerConfigurationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45BE4EA12012AD2000935E59 /* DisappearingTimerConfigurationView.swift */; }; + 45C0DC1B1E68FE9000E04C47 /* UIApplication+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C0DC1A1E68FE9000E04C47 /* UIApplication+OWS.swift */; }; + 45C0DC1E1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */; }; 45C9DEB81DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C9DEB71DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift */; }; 45CB2FA81CB7146C00E1B343 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 45CB2FA71CB7146C00E1B343 /* Launch Screen.storyboard */; }; 45CD81EF1DC030E7004C9430 /* SyncPushTokensJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45CD81EE1DC030E7004C9430 /* SyncPushTokensJob.swift */; }; @@ -446,6 +444,7 @@ 768A1A2B17FC9CD300E00ED8 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 768A1A2A17FC9CD300E00ED8 /* libz.dylib */; }; 76C87F19181EFCE600C4ACAB /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */; }; 76EB054018170B33006006FC /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB03C318170B33006006FC /* AppDelegate.m */; }; + 76EB063A18170B33006006FC /* FunctionalUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04EB18170B33006006FC /* FunctionalUtil.m */; }; 954AEE6A1DF33E01002E5410 /* ContactsPickerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954AEE681DF33D32002E5410 /* ContactsPickerTest.swift */; }; A10FDF79184FB4BB007FF963 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */; }; A11CD70D17FA230600A2D1B1 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A11CD70C17FA230600A2D1B1 /* QuartzCore.framework */; }; @@ -485,13 +484,16 @@ B660F6DB1C29868000687D6E /* FunctionalUtilTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6AD1C29868000687D6E /* FunctionalUtilTest.m */; }; B660F6E01C29868000687D6E /* UtilTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6B41C29868000687D6E /* UtilTest.m */; }; B660F7561C29988E00687D6E /* PushManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B9ECFB198B31BA00C620D3 /* PushManager.m */; }; + B660F7721C29988E00687D6E /* AppStoreRating.m in Sources */ = {isa = PBXBuildFile; fileRef = B6DA6B061B8A2F9A00CA6F98 /* AppStoreRating.m */; }; B66DBF4A19D5BBC8006EA940 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B66DBF4919D5BBC8006EA940 /* Images.xcassets */; }; B67EBF5D19194AC60084CCFD /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B67EBF5C19194AC60084CCFD /* Settings.bundle */; }; B69CD25119773E79005CE69A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B69CD25019773E79005CE69A /* XCTest.framework */; }; B6B226971BE4B7D200860F4D /* ContactsUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6B226961BE4B7D200860F4D /* ContactsUI.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; B6B9ECFC198B31BA00C620D3 /* PushManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B9ECFB198B31BA00C620D3 /* PushManager.m */; }; + B6DA6B071B8A2F9A00CA6F98 /* AppStoreRating.m in Sources */ = {isa = PBXBuildFile; fileRef = B6DA6B061B8A2F9A00CA6F98 /* AppStoreRating.m */; }; B6F509971AA53F760068F56A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B6F509951AA53F760068F56A /* Localizable.strings */; }; B6FE7EB71ADD62FA00A6D22F /* PushKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6FE7EB61ADD62FA00A6D22F /* PushKit.framework */; }; + B90418E6183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; }; B9EB5ABD1884C002007CBB57 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9EB5ABC1884C002007CBB57 /* MessageUI.framework */; }; BFF3FB9730634F37D25903F4 /* Pods_Signal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D17BB5C25D615AB49813100C /* Pods_Signal.framework */; }; CC875800737563D6891B741D /* Pods_SignalTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 748A5CAEDD7C919FC64C6807 /* Pods_SignalTests.framework */; }; @@ -510,6 +512,7 @@ D24B5BD5169F568C00681372 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D24B5BD4169F568C00681372 /* AudioToolbox.framework */; }; D2AEACDC16C426DA00C364C0 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2AEACDB16C426DA00C364C0 /* CFNetwork.framework */; }; E1368CBE18A1C36B00109378 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9EB5ABC1884C002007CBB57 /* MessageUI.framework */; }; + EF764C351DB67CC5000D9A87 /* UIViewController+Permissions.m in Sources */ = {isa = PBXBuildFile; fileRef = EF764C341DB67CC5000D9A87 /* UIViewController+Permissions.m */; }; FC3BD9881A30A790005B96BB /* Social.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC3BD9871A30A790005B96BB /* Social.framework */; }; FC5CDF391A3393DD00B47253 /* error_white@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC5CDF371A3393DD00B47253 /* error_white@2x.png */; }; FC5CDF3A1A3393DD00B47253 /* warning_white@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC5CDF381A3393DD00B47253 /* warning_white@2x.png */; }; @@ -644,8 +647,17 @@ 340FC8A4204DAC8D007AEB0F /* AddToGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddToGroupViewController.h; sourceTree = ""; }; 340FC8A5204DAC8D007AEB0F /* FingerprintViewScanController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FingerprintViewScanController.h; sourceTree = ""; }; 340FC8A6204DAC8D007AEB0F /* ShowGroupMembersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShowGroupMembersViewController.m; sourceTree = ""; }; + 340FC8BE204DB7D1007AEB0F /* OWSBackupExportJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupExportJob.h; sourceTree = ""; }; + 340FC8BF204DB7D2007AEB0F /* OWSBackupExportJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupExportJob.m; sourceTree = ""; }; 340FC8C3204DE223007AEB0F /* DebugUIBackup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIBackup.h; sourceTree = ""; }; 340FC8C4204DE223007AEB0F /* DebugUIBackup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIBackup.m; sourceTree = ""; }; + 340FC8C6204DE64D007AEB0F /* OWSBackupAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSBackupAPI.swift; sourceTree = ""; }; + 340FC8C820517B84007AEB0F /* OWSBackupImportJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupImportJob.m; sourceTree = ""; }; + 340FC8C920517B84007AEB0F /* OWSBackupImportJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupImportJob.h; sourceTree = ""; }; + 340FC8CB20518C76007AEB0F /* OWSBackupJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupJob.h; sourceTree = ""; }; + 340FC8CC20518C76007AEB0F /* OWSBackupJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupJob.m; sourceTree = ""; }; + 340FC8CE205BF2FA007AEB0F /* OWSBackupIO.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupIO.m; sourceTree = ""; }; + 340FC8CF205BF2FA007AEB0F /* OWSBackupIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupIO.h; sourceTree = ""; }; 341458471FBE11C4005ABCF9 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = translations/fa.lproj/Localizable.strings; sourceTree = ""; }; 341F2C0D1F2B8AE700D07D6B /* DebugUIMisc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIMisc.h; sourceTree = ""; }; 341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIMisc.m; sourceTree = ""; }; @@ -701,45 +713,8 @@ 34480B601FD0A98800BC14EF /* UIView+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+OWS.m"; sourceTree = ""; }; 34480B651FD0AA9400BC14EF /* UIFont+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+OWS.m"; sourceTree = ""; }; 34480B661FD0AA9400BC14EF /* UIFont+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+OWS.h"; sourceTree = ""; }; - 3448255321138BAE00DB4BD8 /* AppUpdateNag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppUpdateNag.m; sourceTree = ""; }; - 3448255421138BAE00DB4BD8 /* UIViewController+Permissions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+Permissions.h"; sourceTree = ""; }; - 3448255521138BAE00DB4BD8 /* RegistrationUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegistrationUtils.m; sourceTree = ""; }; - 3448255621138BAE00DB4BD8 /* OWSBackupExportJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupExportJob.m; sourceTree = ""; }; - 3448255721138BAE00DB4BD8 /* AppStoreRating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppStoreRating.h; sourceTree = ""; }; - 3448255821138BAE00DB4BD8 /* OWSOrphanDataCleaner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSOrphanDataCleaner.h; sourceTree = ""; }; - 3448255921138BAE00DB4BD8 /* OWSBackupLazyRestoreJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSBackupLazyRestoreJob.swift; sourceTree = ""; }; - 3448255A21138BAE00DB4BD8 /* Pastelog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Pastelog.m; sourceTree = ""; }; - 3448255B21138BAE00DB4BD8 /* OWSScreenLockUI.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSScreenLockUI.m; sourceTree = ""; }; - 3448256821138BAE00DB4BD8 /* MainAppContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainAppContext.h; sourceTree = ""; }; - 3448256921138BAE00DB4BD8 /* OWSBackup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackup.h; sourceTree = ""; }; - 3448256B21138BAE00DB4BD8 /* UIResponder+OWS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIResponder+OWS.swift"; sourceTree = ""; }; - 3448256D21138BAE00DB4BD8 /* FunctionalUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FunctionalUtil.m; sourceTree = ""; }; - 3448256F21138BAE00DB4BD8 /* DateUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DateUtil.m; sourceTree = ""; }; - 3448257421138BAE00DB4BD8 /* TextFieldHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldHelper.swift; sourceTree = ""; }; - 3448257721138BAE00DB4BD8 /* OWSBackupIO.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupIO.m; sourceTree = ""; }; - 3448257821138BAE00DB4BD8 /* OWSBackupImportJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupImportJob.m; sourceTree = ""; }; - 3448257921138BAE00DB4BD8 /* UIViewController+CameraPermissions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+CameraPermissions.h"; sourceTree = ""; }; - 3448257A21138BAE00DB4BD8 /* OWSBackupJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupJob.h; sourceTree = ""; }; - 3448257E21138BAE00DB4BD8 /* OWSBackupExportJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupExportJob.h; sourceTree = ""; }; - 3448257F21138BAE00DB4BD8 /* RegistrationUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegistrationUtils.h; sourceTree = ""; }; - 3448258021138BAE00DB4BD8 /* UIViewController+Permissions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+Permissions.m"; sourceTree = ""; }; - 3448258121138BAE00DB4BD8 /* AppUpdateNag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppUpdateNag.h; sourceTree = ""; }; - 3448258321138BAE00DB4BD8 /* OWSBackup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackup.m; sourceTree = ""; }; - 3448258521138BAE00DB4BD8 /* MainAppContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainAppContext.m; sourceTree = ""; }; - 3448258721138BAE00DB4BD8 /* NSString+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+OWS.m"; sourceTree = ""; }; - 3448258821138BAE00DB4BD8 /* OWSScreenLockUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSScreenLockUI.h; sourceTree = ""; }; - 3448258921138BAE00DB4BD8 /* Pastelog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pastelog.h; sourceTree = ""; }; - 3448258A21138BAE00DB4BD8 /* Platform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Platform.swift; sourceTree = ""; }; - 3448258B21138BAE00DB4BD8 /* OWSOrphanDataCleaner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSOrphanDataCleaner.m; sourceTree = ""; }; - 3448258C21138BAE00DB4BD8 /* AppStoreRating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppStoreRating.m; sourceTree = ""; }; - 3448258D21138BAE00DB4BD8 /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = ""; }; - 3448259221138BAE00DB4BD8 /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = ""; }; - 3448259421138BAE00DB4BD8 /* OWSAnalytics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSAnalytics.swift; sourceTree = ""; }; - 3448259521138BAE00DB4BD8 /* FunctionalUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionalUtil.h; sourceTree = ""; }; - 3448259821138BAE00DB4BD8 /* OWSBackupJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupJob.m; sourceTree = ""; }; - 3448259921138BAE00DB4BD8 /* OWSBackupAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSBackupAPI.swift; sourceTree = ""; }; - 3448259A21138BAE00DB4BD8 /* OWSBackupImportJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupImportJob.h; sourceTree = ""; }; - 3448259B21138BAE00DB4BD8 /* OWSBackupIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupIO.h; sourceTree = ""; }; + 344825C4211390C700DB4BD8 /* OWSOrphanDataCleaner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSOrphanDataCleaner.h; sourceTree = ""; }; + 344825C5211390C800DB4BD8 /* OWSOrphanDataCleaner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSOrphanDataCleaner.m; sourceTree = ""; }; 34491FC11FB0F78500B3E5A3 /* my */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = my; path = translations/my.lproj/Localizable.strings; sourceTree = ""; }; 344D6CE620069E060042AF96 /* SelectRecipientViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SelectRecipientViewController.h; path = SignalMessaging/contacts/SelectRecipientViewController.h; sourceTree = SOURCE_ROOT; }; 344D6CE720069E060042AF96 /* SelectRecipientViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SelectRecipientViewController.m; path = SignalMessaging/contacts/SelectRecipientViewController.m; sourceTree = SOURCE_ROOT; }; @@ -848,8 +823,12 @@ 3496744E2076ACCE00080B5F /* LongTextViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LongTextViewController.swift; sourceTree = ""; }; 34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWS2FARegistrationViewController.m; sourceTree = ""; }; 34A55F3620485464002CC6DE /* OWS2FARegistrationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWS2FARegistrationViewController.h; sourceTree = ""; }; + 34A9105E1FFEB113000C4745 /* OWSBackup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackup.h; sourceTree = ""; }; + 34A9105F1FFEB114000C4745 /* OWSBackup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackup.m; sourceTree = ""; }; 34ABB2C22090C59600C727A6 /* OWSResaveCollectionDBMigration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSResaveCollectionDBMigration.m; sourceTree = ""; }; 34ABB2C32090C59700C727A6 /* OWSResaveCollectionDBMigration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSResaveCollectionDBMigration.h; sourceTree = ""; }; + 34B0796B1FCF46B000E248C2 /* MainAppContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainAppContext.m; sourceTree = ""; }; + 34B0796C1FCF46B000E248C2 /* MainAppContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainAppContext.h; sourceTree = ""; }; 34B0796E1FD07B1E00E248C2 /* SignalShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SignalShareExtension.entitlements; sourceTree = ""; }; 34B3F8391E8DF1700035BE1A /* AttachmentSharing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AttachmentSharing.h; sourceTree = ""; }; 34B3F83A1E8DF1700035BE1A /* AttachmentSharing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AttachmentSharing.m; sourceTree = ""; }; @@ -891,6 +870,8 @@ 34CA1C281F7164F700E51C51 /* MediaMessageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaMessageView.swift; sourceTree = ""; }; 34CA63192097806E00E526A0 /* OWSContactShareView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSContactShareView.h; sourceTree = ""; }; 34CA631A2097806E00E526A0 /* OWSContactShareView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactShareView.m; sourceTree = ""; }; + 34CCAF361F0C0599004084F4 /* AppUpdateNag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppUpdateNag.h; sourceTree = ""; }; + 34CCAF371F0C0599004084F4 /* AppUpdateNag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppUpdateNag.m; sourceTree = ""; }; 34CE88E51F2FB9A10098030F /* ProfileViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProfileViewController.h; sourceTree = ""; }; 34CE88E61F2FB9A10098030F /* ProfileViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProfileViewController.m; sourceTree = ""; }; 34CF0783203E6B77005C4D61 /* busy_tone_ansi.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = busy_tone_ansi.caf; path = Signal/AudioFiles/busy_tone_ansi.caf; sourceTree = SOURCE_ROOT; }; @@ -927,6 +908,9 @@ 34D1F0BF1F8EC1760066283D /* MessageRecipientStatusUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageRecipientStatusUtils.swift; sourceTree = ""; }; 34D2014F20DC160D00A6FD3A /* ContactCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContactCellView.h; path = SignalMessaging/Views/ContactCellView.h; sourceTree = SOURCE_ROOT; }; 34D2015020DC160D00A6FD3A /* ContactCellView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ContactCellView.m; path = SignalMessaging/Views/ContactCellView.m; sourceTree = SOURCE_ROOT; }; + 34D2CCD120618B2F00CB1A14 /* OWSBackupLazyRestoreJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSBackupLazyRestoreJob.swift; sourceTree = ""; }; + 34D2CCD82062E7D000CB1A14 /* OWSScreenLockUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSScreenLockUI.h; sourceTree = ""; }; + 34D2CCD92062E7D000CB1A14 /* OWSScreenLockUI.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSScreenLockUI.m; sourceTree = ""; }; 34D2CCDB206939B100CB1A14 /* DebugUIMessagesAction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIMessagesAction.m; sourceTree = ""; }; 34D2CCDC206939B200CB1A14 /* DebugUIMessagesAssetLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIMessagesAssetLoader.m; sourceTree = ""; }; 34D2CCDD206939B200CB1A14 /* DebugUIMessagesAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIMessagesAction.h; sourceTree = ""; }; @@ -947,6 +931,7 @@ 34D920E620E179C200D51158 /* OWSMessageFooterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSMessageFooterView.m; sourceTree = ""; }; 34D99C8A1F27B13B00D284D6 /* OWSViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSViewController.h; sourceTree = ""; }; 34D99C8B1F27B13B00D284D6 /* OWSViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSViewController.m; sourceTree = ""; }; + 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSAnalytics.swift; sourceTree = ""; }; 34DB0BEB2011548A007B313F /* OWSDatabaseConverterTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSDatabaseConverterTest.h; sourceTree = ""; }; 34DB0BEC2011548B007B313F /* OWSDatabaseConverterTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDatabaseConverterTest.m; sourceTree = ""; }; 34DBEFFF206BD5A400025978 /* OWSMessageTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSMessageTextView.m; sourceTree = ""; }; @@ -960,6 +945,8 @@ 34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIDiskUsage.m; sourceTree = ""; }; 34E3EF0E1EFC2684007F6822 /* DebugUIPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIPage.h; sourceTree = ""; }; 34E3EF0F1EFC2684007F6822 /* DebugUIPage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIPage.m; sourceTree = ""; }; + 34E5DC8020D8050D00C08145 /* RegistrationUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegistrationUtils.h; sourceTree = ""; }; + 34E5DC8120D8050D00C08145 /* RegistrationUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegistrationUtils.m; sourceTree = ""; }; 34E88D252098C5AE00A608F4 /* ContactViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactViewController.swift; sourceTree = ""; }; 34E8A8D02085238900B272B1 /* ProtoParsingTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProtoParsingTest.m; sourceTree = ""; }; 34F308A01ECB469700BB7697 /* OWSBezierPathView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBezierPathView.h; sourceTree = ""; }; @@ -975,6 +962,7 @@ 4509E7991DD653700025A59F /* WebRTC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebRTC.framework; path = Carthage/Build/iOS/WebRTC.framework; sourceTree = ""; }; 450D19111F85236600970622 /* RemoteVideoView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RemoteVideoView.h; sourceTree = ""; }; 450D19121F85236600970622 /* RemoteVideoView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RemoteVideoView.m; sourceTree = ""; }; + 450DF2041E0D74AC003D14BE /* Platform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Platform.swift; sourceTree = ""; }; 450DF2081E0DD2C6003D14BE /* UserNotificationsAdaptee.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = UserNotificationsAdaptee.swift; path = UserInterface/Notifications/UserNotificationsAdaptee.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; 451166BF1FD86B98000739BA /* AccountManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountManager.swift; sourceTree = ""; }; 451573952061B49500803601 /* GradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = GradientView.swift; path = SignalMessaging/Views/GradientView.swift; sourceTree = SOURCE_ROOT; }; @@ -986,6 +974,7 @@ 452037CF1EE84975004E4CDF /* DebugUISessionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUISessionState.h; sourceTree = ""; }; 452037D01EE84975004E4CDF /* DebugUISessionState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUISessionState.m; sourceTree = ""; }; 4520D8D41D417D8E00123472 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = System/Library/Frameworks/Photos.framework; sourceTree = SDKROOT; }; + 4521C3BF1F59F3BA00B4C582 /* TextFieldHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldHelper.swift; sourceTree = ""; }; 4523149F1F7E9E18003A428C /* DirectionalPanGestureRecognizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DirectionalPanGestureRecognizer.swift; sourceTree = ""; }; 4523D015206EDC2B00A2AB51 /* LRUCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LRUCache.swift; sourceTree = ""; }; 452B998F20A34B6B006F2F9E /* AddContactShareToExistingContactViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddContactShareToExistingContactViewController.swift; sourceTree = ""; }; @@ -1021,6 +1010,7 @@ 455A16DC1F1FEA0000F86704 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; }; 455AC69D1F4F8B0300134004 /* ImageCacheTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageCacheTest.swift; sourceTree = ""; }; 45638BDB1F3DD0D400128435 /* DebugUICalling.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugUICalling.swift; sourceTree = ""; }; + 45638BDE1F3DDB2200128435 /* MessageSender+Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MessageSender+Promise.swift"; sourceTree = ""; }; 45666EC41D99483D008FE134 /* OWSAvatarBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSAvatarBuilder.h; sourceTree = ""; }; 45666EC51D99483D008FE134 /* OWSAvatarBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSAvatarBuilder.m; sourceTree = ""; }; 45666EC71D994C0D008FE134 /* OWSGroupAvatarBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSGroupAvatarBuilder.h; sourceTree = ""; }; @@ -1030,6 +1020,8 @@ 456D0FD81F631F4E008499CD /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lt; path = translations/lt.lproj/Localizable.strings; sourceTree = ""; }; 456F6E2E1E261D1000FD2210 /* PeerConnectionClientTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerConnectionClientTest.swift; sourceTree = ""; }; 4574A5D51DD6704700C6B692 /* CallService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = CallService.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 4579431C1E7C8CE9008ED0C0 /* Pastelog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pastelog.h; sourceTree = ""; }; + 4579431D1E7C8CE9008ED0C0 /* Pastelog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Pastelog.m; sourceTree = ""; }; 45794E851E00620000066731 /* CallUIAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CallUIAdapter.swift; path = UserInterface/CallUIAdapter.swift; sourceTree = ""; }; 457C87B72032645C008D52D6 /* DebugUINotifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugUINotifications.swift; sourceTree = ""; }; 457F671A20746193000EABCD /* QuotedReplyPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuotedReplyPreview.swift; sourceTree = ""; }; @@ -1060,6 +1052,7 @@ 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TurnServerInfo.swift; sourceTree = ""; }; 45B201741DAECBFD00C461E0 /* Signal-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Signal-Bridging-Header.h"; sourceTree = ""; }; 45B27B852037FFB400A539DF /* DebugUIFileBrowser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugUIFileBrowser.swift; sourceTree = ""; }; + 45B5360D206DD8BB00D61655 /* UIResponder+OWS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "UIResponder+OWS.swift"; path = "util/UI Categories/UIResponder+OWS.swift"; sourceTree = ""; }; 45B74A5B2044AAB300CD42F8 /* aurora-quiet.aifc */ = {isa = PBXFileReference; lastKnownFileType = file; path = "aurora-quiet.aifc"; sourceTree = ""; }; 45B74A5C2044AAB300CD42F8 /* synth-quiet.aifc */ = {isa = PBXFileReference; lastKnownFileType = file; path = "synth-quiet.aifc"; sourceTree = ""; }; 45B74A5D2044AAB400CD42F8 /* keys-quiet.aifc */ = {isa = PBXFileReference; lastKnownFileType = file; path = "keys-quiet.aifc"; sourceTree = ""; }; @@ -1090,6 +1083,8 @@ 45BC829C1FD9C4B400011CF3 /* ShareViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewDelegate.swift; sourceTree = ""; }; 45BD60811DE9547E00A8F436 /* Contacts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Contacts.framework; path = System/Library/Frameworks/Contacts.framework; sourceTree = SDKROOT; }; 45BE4EA12012AD2000935E59 /* DisappearingTimerConfigurationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisappearingTimerConfigurationView.swift; sourceTree = ""; }; + 45C0DC1A1E68FE9000E04C47 /* UIApplication+OWS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIApplication+OWS.swift"; sourceTree = ""; }; + 45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIStoryboard+OWS.swift"; sourceTree = ""; }; 45C9DEB71DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebRTCCallMessageHandler.swift; sourceTree = ""; }; 45CB2FA71CB7146C00E1B343 /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = "Launch Screen.storyboard"; path = "Signal/src/util/Launch Screen.storyboard"; sourceTree = SOURCE_ROOT; }; 45CD81EE1DC030E7004C9430 /* SyncPushTokensJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyncPushTokensJob.swift; sourceTree = ""; }; @@ -1135,6 +1130,8 @@ 76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; }; 76EB03C218170B33006006FC /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 76EB03C318170B33006006FC /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 76EB04EA18170B33006006FC /* FunctionalUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionalUtil.h; sourceTree = ""; }; + 76EB04EB18170B33006006FC /* FunctionalUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FunctionalUtil.m; sourceTree = ""; }; 76EB052E18170B33006006FC /* ContactTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactTableViewCell.h; sourceTree = ""; }; 76EB052F18170B33006006FC /* ContactTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactTableViewCell.m; sourceTree = ""; }; 8981C8F64D94D3C52EB67A2C /* Pods-SignalTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignalTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-SignalTests/Pods-SignalTests.test.xcconfig"; sourceTree = ""; }; @@ -1216,8 +1213,12 @@ B6B9ECFA198B31BA00C620D3 /* PushManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = PushManager.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; B6B9ECFB198B31BA00C620D3 /* PushManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = PushManager.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; B6BC3D0C1AA544B100C2907F /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = translations/da.lproj/Localizable.strings; sourceTree = ""; }; + B6DA6B051B8A2F9A00CA6F98 /* AppStoreRating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppStoreRating.h; sourceTree = ""; }; + B6DA6B061B8A2F9A00CA6F98 /* AppStoreRating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppStoreRating.m; sourceTree = ""; }; B6F509961AA53F760068F56A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = translations/en.lproj/Localizable.strings; sourceTree = ""; }; B6FE7EB61ADD62FA00A6D22F /* PushKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PushKit.framework; path = System/Library/Frameworks/PushKit.framework; sourceTree = SDKROOT; }; + B90418E4183E9DD40038554A /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = ""; }; + B90418E5183E9DD40038554A /* DateUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DateUtil.m; sourceTree = ""; }; B97940251832BD2400BD66CB /* UIUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIUtil.h; sourceTree = ""; }; B97940261832BD2400BD66CB /* UIUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIUtil.m; sourceTree = ""; }; B9EB5ABC1884C002007CBB57 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; @@ -1239,6 +1240,8 @@ DF728B4B438716EAF95CEC18 /* Pods-Signal.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Signal.app store release.xcconfig"; path = "Pods/Target Support Files/Pods-Signal/Pods-Signal.app store release.xcconfig"; sourceTree = ""; }; E1A0AD8B16E13FDD0071E604 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; E85DB184824BA9DC302EC8B3 /* Pods-SignalTests.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignalTests.app store release.xcconfig"; path = "Pods/Target Support Files/Pods-SignalTests/Pods-SignalTests.app store release.xcconfig"; sourceTree = ""; }; + EF764C331DB67CC5000D9A87 /* UIViewController+Permissions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIViewController+Permissions.h"; path = "util/UIViewController+Permissions.h"; sourceTree = ""; }; + EF764C341DB67CC5000D9A87 /* UIViewController+Permissions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIViewController+Permissions.m"; path = "util/UIViewController+Permissions.m"; sourceTree = ""; }; FC3BD9871A30A790005B96BB /* Social.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Social.framework; path = System/Library/Frameworks/Social.framework; sourceTree = SDKROOT; }; FC5CDF371A3393DD00B47253 /* error_white@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "error_white@2x.png"; sourceTree = ""; }; FC5CDF381A3393DD00B47253 /* warning_white@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "warning_white@2x.png"; sourceTree = ""; }; @@ -1588,60 +1591,6 @@ path = categories; sourceTree = ""; }; - 3448255121138BAE00DB4BD8 /* util */ = { - isa = PBXGroup; - children = ( - 3448255721138BAE00DB4BD8 /* AppStoreRating.h */, - 3448258C21138BAE00DB4BD8 /* AppStoreRating.m */, - 3448258121138BAE00DB4BD8 /* AppUpdateNag.h */, - 3448255321138BAE00DB4BD8 /* AppUpdateNag.m */, - 3448259221138BAE00DB4BD8 /* DateUtil.h */, - 3448256F21138BAE00DB4BD8 /* DateUtil.m */, - 3448259521138BAE00DB4BD8 /* FunctionalUtil.h */, - 3448256D21138BAE00DB4BD8 /* FunctionalUtil.m */, - 3448258D21138BAE00DB4BD8 /* Launch Screen.storyboard */, - 3448256821138BAE00DB4BD8 /* MainAppContext.h */, - 3448258521138BAE00DB4BD8 /* MainAppContext.m */, - 3448258721138BAE00DB4BD8 /* NSString+OWS.m */, - 3448259421138BAE00DB4BD8 /* OWSAnalytics.swift */, - 3448256921138BAE00DB4BD8 /* OWSBackup.h */, - 3448258321138BAE00DB4BD8 /* OWSBackup.m */, - 3448259921138BAE00DB4BD8 /* OWSBackupAPI.swift */, - 3448257E21138BAE00DB4BD8 /* OWSBackupExportJob.h */, - 3448255621138BAE00DB4BD8 /* OWSBackupExportJob.m */, - 3448259A21138BAE00DB4BD8 /* OWSBackupImportJob.h */, - 3448257821138BAE00DB4BD8 /* OWSBackupImportJob.m */, - 3448259B21138BAE00DB4BD8 /* OWSBackupIO.h */, - 3448257721138BAE00DB4BD8 /* OWSBackupIO.m */, - 3448257A21138BAE00DB4BD8 /* OWSBackupJob.h */, - 3448259821138BAE00DB4BD8 /* OWSBackupJob.m */, - 3448255921138BAE00DB4BD8 /* OWSBackupLazyRestoreJob.swift */, - 3448255821138BAE00DB4BD8 /* OWSOrphanDataCleaner.h */, - 3448258B21138BAE00DB4BD8 /* OWSOrphanDataCleaner.m */, - 3448258821138BAE00DB4BD8 /* OWSScreenLockUI.h */, - 3448255B21138BAE00DB4BD8 /* OWSScreenLockUI.m */, - 3448258921138BAE00DB4BD8 /* Pastelog.h */, - 3448255A21138BAE00DB4BD8 /* Pastelog.m */, - 3448258A21138BAE00DB4BD8 /* Platform.swift */, - 3448257F21138BAE00DB4BD8 /* RegistrationUtils.h */, - 3448255521138BAE00DB4BD8 /* RegistrationUtils.m */, - 3448257421138BAE00DB4BD8 /* TextFieldHelper.swift */, - 3448256A21138BAE00DB4BD8 /* UI Categories */, - 3448257921138BAE00DB4BD8 /* UIViewController+CameraPermissions.h */, - 3448255421138BAE00DB4BD8 /* UIViewController+Permissions.h */, - 3448258021138BAE00DB4BD8 /* UIViewController+Permissions.m */, - ); - path = util; - sourceTree = ""; - }; - 3448256A21138BAE00DB4BD8 /* UI Categories */ = { - isa = PBXGroup; - children = ( - 3448256B21138BAE00DB4BD8 /* UIResponder+OWS.swift */, - ); - path = "UI Categories"; - sourceTree = ""; - }; 3448BFC01EDF0EA7005B2D69 /* ConversationView */ = { isa = PBXGroup; children = ( @@ -2188,7 +2137,7 @@ 45B201741DAECBFD00C461E0 /* Signal-Bridging-Header.h */, 45CD81A41DBFF8CF004C9430 /* Storyboards */, 450DF2061E0DD28D003D14BE /* UserInterface */, - 3448255121138BAE00DB4BD8 /* util */, + 76EB04C818170B33006006FC /* util */, ); path = src; sourceTree = ""; @@ -2231,6 +2180,47 @@ path = network; sourceTree = ""; }; + 76EB04C818170B33006006FC /* util */ = { + isa = PBXGroup; + children = ( + B6DA6B051B8A2F9A00CA6F98 /* AppStoreRating.h */, + B6DA6B061B8A2F9A00CA6F98 /* AppStoreRating.m */, + 34CCAF361F0C0599004084F4 /* AppUpdateNag.h */, + 34CCAF371F0C0599004084F4 /* AppUpdateNag.m */, + B90418E4183E9DD40038554A /* DateUtil.h */, + B90418E5183E9DD40038554A /* DateUtil.m */, + 76EB04EA18170B33006006FC /* FunctionalUtil.h */, + 76EB04EB18170B33006006FC /* FunctionalUtil.m */, + 34B0796C1FCF46B000E248C2 /* MainAppContext.h */, + 34B0796B1FCF46B000E248C2 /* MainAppContext.m */, + 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */, + 34A9105E1FFEB113000C4745 /* OWSBackup.h */, + 34A9105F1FFEB114000C4745 /* OWSBackup.m */, + 340FC8C6204DE64D007AEB0F /* OWSBackupAPI.swift */, + 340FC8BE204DB7D1007AEB0F /* OWSBackupExportJob.h */, + 340FC8BF204DB7D2007AEB0F /* OWSBackupExportJob.m */, + 340FC8C920517B84007AEB0F /* OWSBackupImportJob.h */, + 340FC8C820517B84007AEB0F /* OWSBackupImportJob.m */, + 340FC8CF205BF2FA007AEB0F /* OWSBackupIO.h */, + 340FC8CE205BF2FA007AEB0F /* OWSBackupIO.m */, + 340FC8CB20518C76007AEB0F /* OWSBackupJob.h */, + 340FC8CC20518C76007AEB0F /* OWSBackupJob.m */, + 34D2CCD120618B2F00CB1A14 /* OWSBackupLazyRestoreJob.swift */, + 344825C4211390C700DB4BD8 /* OWSOrphanDataCleaner.h */, + 344825C5211390C800DB4BD8 /* OWSOrphanDataCleaner.m */, + 34D2CCD82062E7D000CB1A14 /* OWSScreenLockUI.h */, + 34D2CCD92062E7D000CB1A14 /* OWSScreenLockUI.m */, + 4579431C1E7C8CE9008ED0C0 /* Pastelog.h */, + 4579431D1E7C8CE9008ED0C0 /* Pastelog.m */, + 450DF2041E0D74AC003D14BE /* Platform.swift */, + 34E5DC8020D8050D00C08145 /* RegistrationUtils.h */, + 34E5DC8120D8050D00C08145 /* RegistrationUtils.m */, + 4521C3BF1F59F3BA00B4C582 /* TextFieldHelper.swift */, + FCFA64B11A24F29E0007FB87 /* UI Categories */, + ); + path = util; + sourceTree = ""; + }; 76EB052B18170B33006006FC /* Views */ = { isa = PBXGroup; children = ( @@ -2486,6 +2476,20 @@ name = "Supporting Files"; sourceTree = ""; }; + FCFA64B11A24F29E0007FB87 /* UI Categories */ = { + isa = PBXGroup; + children = ( + 45638BDE1F3DDB2200128435 /* MessageSender+Promise.swift */, + 45C0DC1A1E68FE9000E04C47 /* UIApplication+OWS.swift */, + 45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */, + EF764C331DB67CC5000D9A87 /* UIViewController+Permissions.h */, + EF764C341DB67CC5000D9A87 /* UIViewController+Permissions.m */, + 45B5360D206DD8BB00D61655 /* UIResponder+OWS.swift */, + ); + name = "UI Categories"; + path = ..; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -2878,7 +2882,6 @@ 45B74A772044AAB600CD42F8 /* hello.aifc in Resources */, 45B74A7C2044AAB600CD42F8 /* hello-quiet.aifc in Resources */, 45B74A792044AAB600CD42F8 /* input.aifc in Resources */, - 344825BD21138BAF00DB4BD8 /* Launch Screen.storyboard in Resources */, 45B74A8C2044AAB600CD42F8 /* input-quiet.aifc in Resources */, 45B74A7A2044AAB600CD42F8 /* keys.aifc in Resources */, 45B74A762044AAB600CD42F8 /* keys-quiet.aifc in Resources */, @@ -3272,9 +3275,7 @@ buildActionMask = 2147483647; files = ( 4CC0B59C20EC5F2E00CF6EE0 /* ConversationConfigurationSyncOperation.swift in Sources */, - 344825B121138BAF00DB4BD8 /* TextFieldHelper.swift in Sources */, 3461293E1FD1D72B00532771 /* ExperienceUpgradeFinder.swift in Sources */, - 344825BA21138BAF00DB4BD8 /* Platform.swift in Sources */, 34D1F0BD1F8D108C0066283D /* AttachmentUploadView.m in Sources */, 452EC6DF205E9E30000E787C /* MediaGalleryViewController.swift in Sources */, 34386A52207D0C01009F5D9C /* HomeViewCell.m in Sources */, @@ -3283,31 +3284,31 @@ 34D8C02B1ED3685800188D7C /* DebugUIContacts.m in Sources */, 45C9DEB81DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift in Sources */, 34D1F0501F7D45A60066283D /* GifPickerCell.swift in Sources */, + 34D99C931F2937CC00D284D6 /* OWSAnalytics.swift in Sources */, 340FC8B8204DAC8D007AEB0F /* AddToGroupViewController.m in Sources */, 341F2C0F1F2B8AE700D07D6B /* DebugUIMisc.m in Sources */, 340FC8AF204DAC8D007AEB0F /* OWSLinkDeviceViewController.m in Sources */, 34E3EF0D1EFC235B007F6822 /* DebugUIDiskUsage.m in Sources */, - 344825B921138BAF00DB4BD8 /* NSString+OWS.m in Sources */, 454A84042059C787008B8C75 /* MediaTileViewController.swift in Sources */, 340FC8B4204DAC8D007AEB0F /* OWSBackupSettingsViewController.m in Sources */, 34D1F0871F8678AA0066283D /* ConversationViewItem.m in Sources */, + B6DA6B071B8A2F9A00CA6F98 /* AppStoreRating.m in Sources */, 451A13B11E13DED2000A50FD /* CallNotificationsAdapter.swift in Sources */, 348570A820F67575004FF32B /* OWSMessageHeaderView.m in Sources */, 450DF2091E0DD2C6003D14BE /* UserNotificationsAdaptee.swift in Sources */, - 344825A121138BAF00DB4BD8 /* Pastelog.m in Sources */, 34D1F0AB1F867BFC0066283D /* OWSContactOffersCell.m in Sources */, + 340FC8C7204DE64D007AEB0F /* OWSBackupAPI.swift in Sources */, 343A65981FC4CFE7000477A1 /* ConversationScrollButton.m in Sources */, 34386A51207D0C01009F5D9C /* HomeViewController.m in Sources */, - 344825A021138BAF00DB4BD8 /* OWSBackupLazyRestoreJob.swift in Sources */, 34D1F0A91F867BFC0066283D /* ConversationViewCell.m in Sources */, 4505C2BF1E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */, + 34CCAF381F0C0599004084F4 /* AppUpdateNag.m in Sources */, + EF764C351DB67CC5000D9A87 /* UIViewController+Permissions.m in Sources */, 45CD81EF1DC030E7004C9430 /* SyncPushTokensJob.swift in Sources */, 34D2CCE0206939B400CB1A14 /* DebugUIMessagesAssetLoader.m in Sources */, 45794E861E00620000066731 /* CallUIAdapter.swift in Sources */, 340FC8BA204DAC8D007AEB0F /* FingerprintViewScanController.m in Sources */, - 344825B721138BAF00DB4BD8 /* OWSBackup.m in Sources */, 4585C4681ED8F8D200896AEA /* SafetyNumberConfirmationAlert.swift in Sources */, - 344825BC21138BAF00DB4BD8 /* AppStoreRating.m in Sources */, 4C20B2B920CA10DE001BAC90 /* ConversationSearchViewController.swift in Sources */, 450D19131F85236600970622 /* RemoteVideoView.m in Sources */, B6B9ECFC198B31BA00C620D3 /* PushManager.m in Sources */, @@ -3315,6 +3316,7 @@ 45DF5DF21DDB843F00C936C7 /* CompareSafetyNumbersActivity.swift in Sources */, 458DE9D91DEE7B360071BB03 /* OWSWebRTCDataProtos.pb.m in Sources */, 451166C01FD86B98000739BA /* AccountManager.swift in Sources */, + 34D2CCD220618B3000CB1A14 /* OWSBackupLazyRestoreJob.swift in Sources */, 3430FE181F7751D4000EC51B /* GiphyAPI.swift in Sources */, 34A55F3720485465002CC6DE /* OWS2FARegistrationViewController.m in Sources */, 340FC8AD204DAC8D007AEB0F /* OWSLinkedDevicesTableViewController.m in Sources */, @@ -3323,12 +3325,14 @@ 3496744F2076ACD000080B5F /* LongTextViewController.swift in Sources */, 34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */, 34B3F8931E8DF1710035BE1A /* SignalsNavigationController.m in Sources */, - 3448259E21138BAF00DB4BD8 /* RegistrationUtils.m in Sources */, + 76EB063A18170B33006006FC /* FunctionalUtil.m in Sources */, 34F308A21ECB469700BB7697 /* OWSBezierPathView.m in Sources */, 45B27B862037FFB400A539DF /* DebugUIFileBrowser.swift in Sources */, 34CE88E71F2FB9A10098030F /* ProfileViewController.m in Sources */, 3403B95D20EA9527001A1F44 /* OWSContactShareButtonsView.m in Sources */, + 34B0796D1FCF46B100E248C2 /* MainAppContext.m in Sources */, 34E3EF101EFC2684007F6822 /* DebugUIPage.m in Sources */, + 340FC8CD20518C77007AEB0F /* OWSBackupJob.m in Sources */, 34D1F0AE1F867BFC0066283D /* OWSMessageCell.m in Sources */, 4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */, 4CB5F26720F6E1E2004D1B42 /* MenuActionsViewController.swift in Sources */, @@ -3338,27 +3342,28 @@ 452037D11EE84975004E4CDF /* DebugUISessionState.m in Sources */, D221A09A169C9E5E00537ABF /* main.m in Sources */, 34B3F87B1E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift in Sources */, + 34E5DC8220D8050D00C08145 /* RegistrationUtils.m in Sources */, 452EA09E1EA7ABE00078744B /* AttachmentPointerView.swift in Sources */, 45638BDC1F3DD0D400128435 /* DebugUICalling.swift in Sources */, 45464DBC1DFA041F001D3FD6 /* DataChannelMessage.swift in Sources */, 34E3E5681EC4B19400495BAC /* AudioProgressView.swift in Sources */, 34D1F0521F7E8EA30066283D /* GiphyDownloader.swift in Sources */, 340FC8BC204DAC8D007AEB0F /* FingerprintViewController.m in Sources */, + 450DF2051E0D74AC003D14BE /* Platform.swift in Sources */, 340FC8B2204DAC8D007AEB0F /* AdvancedSettingsTableViewController.m in Sources */, 452B999020A34B6B006F2F9E /* AddContactShareToExistingContactViewController.swift in Sources */, - 344825B421138BAF00DB4BD8 /* OWSBackupImportJob.m in Sources */, 346129991FD1E4DA00532771 /* SignalApp.m in Sources */, 34BECE301F7ABCF800D7438D /* GifPickerLayout.swift in Sources */, 343A65951FC47D5E000477A1 /* DebugUISyncMessages.m in Sources */, + 45C0DC1E1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */, 452ECA4D1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */, 4556FA681F54AA9500AF40DD /* DebugUIProfile.swift in Sources */, 45A6DAD61EBBF85500893231 /* ReminderView.swift in Sources */, - 344825BB21138BAF00DB4BD8 /* OWSOrphanDataCleaner.m in Sources */, 34D1F0881F8678AA0066283D /* ConversationViewLayout.m in Sources */, 452314A01F7E9E18003A428C /* DirectionalPanGestureRecognizer.swift in Sources */, 34330AA31E79686200DF2FB9 /* OWSProgressView.m in Sources */, + 344825C6211390C800DB4BD8 /* OWSOrphanDataCleaner.m in Sources */, 45D2AC02204885170033C692 /* OWS2FAReminderViewController.swift in Sources */, - 344825A921138BAF00DB4BD8 /* UIResponder+OWS.swift in Sources */, 4542DF54208D40AC007B4E76 /* LoadingViewController.swift in Sources */, 34D5CCA91EAE3D30005515DB /* AvatarViewHelper.m in Sources */, 34D1F0B71F87F8850066283D /* OWSGenericAttachmentView.m in Sources */, @@ -3367,16 +3372,15 @@ 34B3F8801E8DF1700035BE1A /* InviteFlow.swift in Sources */, 457C87B82032645C008D52D6 /* DebugUINotifications.swift in Sources */, 4C13C9F620E57BA30089A98B /* ColorPickerViewController.swift in Sources */, + 340FC8D0205BF2FA007AEB0F /* OWSBackupIO.m in Sources */, 458E38371D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m in Sources */, 4517642B1DE939FD00EDB8B9 /* ContactCell.swift in Sources */, - 344825B621138BAF00DB4BD8 /* UIViewController+Permissions.m in Sources */, 340FC8AB204DAC8D007AEB0F /* DomainFrontingCountryViewController.m in Sources */, 3496744D2076768700080B5F /* OWSMessageBubbleView.m in Sources */, 34B3F8751E8DF1700035BE1A /* CallViewController.swift in Sources */, 34D8C0281ED3673300188D7C /* DebugUITableViewController.m in Sources */, 34219801210612F600C57195 /* iRate.m in Sources */, 45F32C222057297A00A300D5 /* MediaDetailViewController.m in Sources */, - 344825C021138BAF00DB4BD8 /* OWSAnalytics.swift in Sources */, 34B3F8851E8DF1700035BE1A /* NewGroupViewController.m in Sources */, 34D8C0271ED3673300188D7C /* DebugUIMessages.m in Sources */, 34DBF003206BD5A500025978 /* OWSMessageTextView.m in Sources */, @@ -3384,30 +3388,29 @@ 34B3F8821E8DF1700035BE1A /* NewContactThreadViewController.m in Sources */, 45D308AD2049A439000189E4 /* PinEntryView.m in Sources */, 340FC8B1204DAC8D007AEB0F /* BlockListViewController.m in Sources */, - 344825A221138BAF00DB4BD8 /* OWSScreenLockUI.m in Sources */, - 3448259F21138BAF00DB4BD8 /* OWSBackupExportJob.m in Sources */, + 45B5360E206DD8BB00D61655 /* UIResponder+OWS.swift in Sources */, 45F659821E1BE77000444429 /* NonCallKitCallUIAdaptee.swift in Sources */, - 344825C321138BAF00DB4BD8 /* OWSBackupAPI.swift in Sources */, 45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */, 34B3F8771E8DF1700035BE1A /* ContactsPicker.swift in Sources */, + 45C0DC1B1E68FE9000E04C47 /* UIApplication+OWS.swift in Sources */, + 45638BDF1F3DDB2200128435 /* MessageSender+Promise.swift in Sources */, 45FBC5C81DF8575700E9B410 /* CallKitCallManager.swift in Sources */, 4539B5861F79348F007141FF /* PushRegistrationManager.swift in Sources */, 45FBC5D11DF8592E00E9B410 /* SignalCall.swift in Sources */, 340FC8BB204DAC8D007AEB0F /* OWSAddToContactViewController.m in Sources */, - 3448259D21138BAF00DB4BD8 /* AppUpdateNag.m in Sources */, + 340FC8C0204DB7D2007AEB0F /* OWSBackupExportJob.m in Sources */, 45F32C232057297A00A300D5 /* MediaPageViewController.swift in Sources */, 3466087420E5649700AFFE73 /* OWSLayerView.swift in Sources */, 340FC8A7204DAC8D007AEB0F /* RegistrationViewController.m in Sources */, 452C468F1E427E200087B011 /* OutboundCallInitiator.swift in Sources */, + 34D2CCDA2062E7D000CB1A14 /* OWSScreenLockUI.m in Sources */, 45F170BB1E2FC5D3003FC1F2 /* CallAudioService.swift in Sources */, 345BC30C2047030700257B7C /* OWS2FASettingsViewController.m in Sources */, + 340FC8CA20517B84007AEB0F /* OWSBackupImportJob.m in Sources */, 340FC8B7204DAC8D007AEB0F /* OWSConversationSettingsViewController.m in Sources */, - 344825AD21138BAF00DB4BD8 /* DateUtil.m in Sources */, 34BECE2E1F7ABCE000D7438D /* GifPickerViewController.swift in Sources */, 34D1F0C01F8EC1760066283D /* MessageRecipientStatusUtils.swift in Sources */, - 344825AB21138BAF00DB4BD8 /* FunctionalUtil.m in Sources */, 45F659731E1BD99C00444429 /* CallKitCallUIAdaptee.swift in Sources */, - 344825B321138BAF00DB4BD8 /* OWSBackupIO.m in Sources */, 34277A5E20751BDC006049F2 /* OWSQuotedMessageView.m in Sources */, 458DE9D61DEE3FD00071BB03 /* PeerConnectionClient.swift in Sources */, 45DDA6242090CEB500DE97F8 /* ConversationHeaderView.swift in Sources */, @@ -3415,7 +3418,6 @@ 34D1F0841F8678AA0066283D /* ConversationInputToolbar.m in Sources */, 457F671B20746193000EABCD /* QuotedReplyPreview.swift in Sources */, 34DBF004206BD5A500025978 /* OWSBubbleView.m in Sources */, - 344825B821138BAF00DB4BD8 /* MainAppContext.m in Sources */, 34E88D262098C5AE00A608F4 /* ContactViewController.swift in Sources */, 76EB054018170B33006006FC /* AppDelegate.m in Sources */, 34D1F0831F8678AA0066283D /* ConversationInputTextView.m in Sources */, @@ -3427,21 +3429,24 @@ 4574A5D61DD6704700C6B692 /* CallService.swift in Sources */, 340FC8A8204DAC8D007AEB0F /* CodeVerificationViewController.m in Sources */, 3461299C1FD1EA9E00532771 /* NotificationsManager.m in Sources */, + 4521C3C01F59F3BA00B4C582 /* TextFieldHelper.swift in Sources */, 34D2CCDF206939B400CB1A14 /* DebugUIMessagesAction.m in Sources */, - 344825C221138BAF00DB4BD8 /* OWSBackupJob.m in Sources */, 340FC8AC204DAC8D007AEB0F /* PrivacySettingsTableViewController.m in Sources */, 340FC8C5204DE223007AEB0F /* DebugUIBackup.m in Sources */, 4C11AA5020FD59C700351FBD /* MessageStatusView.swift in Sources */, 340FC8AE204DAC8D007AEB0F /* OWSSoundSettingsViewController.m in Sources */, + 4579431E1E7C8CE9008ED0C0 /* Pastelog.m in Sources */, 340FC8B0204DAC8D007AEB0F /* AddToBlockListViewController.m in Sources */, 340FC8B3204DAC8D007AEB0F /* AppSettingsViewController.m in Sources */, 346B66311F4E29B200E5122F /* CropScaleImageViewController.swift in Sources */, 45E5A6991F61E6DE001E4A8A /* MarqueeLabel.swift in Sources */, + 34A910601FFEB114000C4745 /* OWSBackup.m in Sources */, 34D1F0B01F867BFC0066283D /* OWSSystemMessageCell.m in Sources */, 45A663C51F92EC760027B59E /* GroupTableViewCell.swift in Sources */, 34CA631B2097806F00E526A0 /* OWSContactShareView.m in Sources */, 34D1F0861F8678AA0066283D /* ConversationViewController.m in Sources */, 3427C64320F500E000EEC730 /* OWSMessageTimerView.m in Sources */, + B90418E6183E9DD40038554A /* DateUtil.m in Sources */, 340FC8BD204DAC8D007AEB0F /* ShowGroupMembersViewController.m in Sources */, 459311FC1D75C948008DD4F0 /* OWSDeviceTableViewCell.m in Sources */, ); @@ -3461,6 +3466,8 @@ B660F7561C29988E00687D6E /* PushManager.m in Sources */, 34DB0BED2011548B007B313F /* OWSDatabaseConverterTest.m in Sources */, 45360B911F952AA900FA666C /* MarqueeLabel.swift in Sources */, + 454EBAB41F2BE14C00ACE0BB /* OWSAnalytics.swift in Sources */, + B660F7721C29988E00687D6E /* AppStoreRating.m in Sources */, 954AEE6A1DF33E01002E5410 /* ContactsPickerTest.swift in Sources */, 45666F581D9B2880008FE134 /* OWSScrubbingLogFormatterTest.m in Sources */, B660F6E01C29868000687D6E /* UtilTest.m in Sources */, diff --git a/SignalMessaging/profiles/OWSUserProfile.h b/SignalMessaging/profiles/OWSUserProfile.h index d63ccd39ae..4453a5dd0a 100644 --- a/SignalMessaging/profiles/OWSUserProfile.h +++ b/SignalMessaging/profiles/OWSUserProfile.h @@ -69,6 +69,8 @@ extern NSString *const kLocalProfileUniqueId; + (NSString *)profileAvatarFilepathWithFilename:(NSString *)filename; + (nullable NSError *)migrateToSharedData; ++ (NSString *)legacyProfileAvatarsDirPath; ++ (NSString *)sharedDataProfileAvatarsDirPath; + (NSString *)profileAvatarsDirPath; + (void)resetProfileStorage; + (NSSet *)allProfileAvatarFilePaths; From 815ccbdcd161b711df628b752bd26167e3190c8e Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 2 Aug 2018 15:31:21 -0400 Subject: [PATCH 3/6] Respond to CR. --- Signal/src/util/OWSOrphanDataCleaner.m | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Signal/src/util/OWSOrphanDataCleaner.m b/Signal/src/util/OWSOrphanDataCleaner.m index 128f902b31..9fb8389732 100644 --- a/Signal/src/util/OWSOrphanDataCleaner.m +++ b/Signal/src/util/OWSOrphanDataCleaner.m @@ -264,12 +264,12 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); return nil; } - NSMutableSet *allFilePaths = [NSMutableSet new]; - [allFilePaths unionSet:legacyAttachmentFilePaths]; - [allFilePaths unionSet:sharedDataAttachmentFilePaths]; - [allFilePaths unionSet:legacyProfileAvatarsFilePaths]; - [allFilePaths unionSet:sharedDataProfileAvatarFilePaths]; - [allFilePaths addObjectsFromArray:tempFilePaths]; + NSMutableSet *allOnDiskFilePaths = [NSMutableSet new]; + [allOnDiskFilePaths unionSet:legacyAttachmentFilePaths]; + [allOnDiskFilePaths unionSet:sharedDataAttachmentFilePaths]; + [allOnDiskFilePaths unionSet:legacyProfileAvatarsFilePaths]; + [allOnDiskFilePaths unionSet:sharedDataProfileAvatarFilePaths]; + [allOnDiskFilePaths addObjectsFromArray:tempFilePaths]; NSSet *profileAvatarFilePaths = [OWSUserProfile allProfileAvatarFilePaths]; @@ -277,13 +277,13 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); return nil; } - NSNumber *_Nullable totalFileSize = [self fileSizeOfFilePathsSafe:allFilePaths.allObjects]; + NSNumber *_Nullable totalFileSize = [self fileSizeOfFilePathsSafe:allOnDiskFilePaths.allObjects]; if (!totalFileSize || !self.isMainAppAndActive) { return nil; } - NSUInteger fileCount = allFilePaths.count; + NSUInteger fileCount = allOnDiskFilePaths.count; // Attachments __block int attachmentStreamCount = 0; @@ -375,11 +375,11 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); DDLogDebug(@"%@ attachmentStreams: %d", self.logTag, attachmentStreamCount); DDLogDebug(@"%@ attachmentStreams with file paths: %zu", self.logTag, allAttachmentFilePaths.count); - NSMutableSet *orphanFilePaths = [allFilePaths mutableCopy]; + NSMutableSet *orphanFilePaths = [allOnDiskFilePaths mutableCopy]; [orphanFilePaths minusSet:allAttachmentFilePaths]; [orphanFilePaths minusSet:profileAvatarFilePaths]; NSMutableSet *missingAttachmentFilePaths = [allAttachmentFilePaths mutableCopy]; - [missingAttachmentFilePaths minusSet:allFilePaths]; + [missingAttachmentFilePaths minusSet:allOnDiskFilePaths]; DDLogDebug(@"%@ orphan file paths: %zu", self.logTag, orphanFilePaths.count); DDLogDebug(@"%@ missing attachment file paths: %zu", self.logTag, missingAttachmentFilePaths.count); @@ -415,7 +415,7 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); OWSAssertIsOnMainThread(); OWSPrimaryStorage *primaryStorage = [OWSPrimaryStorage sharedManager]; - YapDatabaseConnection *databaseConnection = primaryStorage.newDatabaseConnection; + YapDatabaseConnection *databaseConnection = primaryStorage.dbReadWriteConnection; // In production, only clean up once per app version. #ifndef DEBUG @@ -438,7 +438,7 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); + (void)auditAndCleanup:(BOOL)shouldRemoveOrphans { OWSPrimaryStorage *primaryStorage = [OWSPrimaryStorage sharedManager]; - YapDatabaseConnection *databaseConnection = primaryStorage.newDatabaseConnection; + YapDatabaseConnection *databaseConnection = primaryStorage.dbReadWriteConnection; [self auditAndCleanup:shouldRemoveOrphans databaseConnection:databaseConnection]; } From 4bb0122c07cc8c9d85ea949ca151d286e830a0c2 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Mon, 6 Aug 2018 08:52:32 -0400 Subject: [PATCH 4/6] Respond to CR. --- Signal/src/util/OWSOrphanDataCleaner.m | 34 ++++++++++++++++++++------ 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/Signal/src/util/OWSOrphanDataCleaner.m b/Signal/src/util/OWSOrphanDataCleaner.m index 9fb8389732..41c582d3d2 100644 --- a/Signal/src/util/OWSOrphanDataCleaner.m +++ b/Signal/src/util/OWSOrphanDataCleaner.m @@ -3,6 +3,7 @@ // #import "OWSOrphanDataCleaner.h" +#import "DateUtil.h" #import #import #import @@ -23,6 +24,7 @@ NS_ASSUME_NONNULL_BEGIN NSString *const OWSOrphanDataCleaner_Collection = @"OWSOrphanDataCleaner_Collection"; NSString *const OWSOrphanDataCleaner_LastCleaningVersionKey = @"OWSOrphanDataCleaner_LastCleaningVersionKey"; +NSString *const OWSOrphanDataCleaner_LastCleaningDateKey = @"OWSOrphanDataCleaner_LastCleaningDateKey"; @interface OWSOrphanData : NSObject @@ -414,24 +416,39 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); { OWSAssertIsOnMainThread(); + // In production, do not audit or clean up. +#ifndef DEBUG + return; +#endif + OWSPrimaryStorage *primaryStorage = [OWSPrimaryStorage sharedManager]; YapDatabaseConnection *databaseConnection = primaryStorage.dbReadWriteConnection; - // In production, only clean up once per app version. -#ifndef DEBUG - NSString *_Nullable lastCleaningVersion = - [databaseConnection stringForKey:OWSOrphanDataCleaner_LastCleaningVersionKey - inCollection:OWSOrphanDataCleaner_Collection]; + __block NSString *_Nullable lastCleaningVersion; + __block NSDate *_Nullable lastCleaningDate; + [databaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + lastCleaningVersion = [databaseConnection stringForKey:OWSOrphanDataCleaner_LastCleaningVersionKey + inCollection:OWSOrphanDataCleaner_Collection]; + lastCleaningDate = [databaseConnection dateForKey:OWSOrphanDataCleaner_LastCleaningDateKey + inCollection:OWSOrphanDataCleaner_Collection]; + }]; + + // Only clean up once per app version. NSString *currentAppVersion = AppVersion.sharedInstance.currentAppVersion; if (lastCleaningVersion && [lastCleaningVersion isEqualToString:currentAppVersion]) { DDLogVerbose(@"%@ skipping orphan data cleanup; already done on %@.", self.logTag, currentAppVersion); return; } -#endif + + // Only clean up once per day. + if (lastCleaningDate && [DateUtil dateIsToday:lastCleaningDate]) { + DDLogVerbose(@"%@ skipping orphan data cleanup; already done today.", self.logTag); + return; + } // If we want to be cautious, we can disable orphan deletion using // flag - the cleanup will just be a dry run with logging. - BOOL shouldRemoveOrphans = YES; + BOOL shouldRemoveOrphans = NO; [self auditAndCleanup:shouldRemoveOrphans databaseConnection:databaseConnection]; } @@ -501,6 +518,9 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); [databaseConnection setObject:AppVersion.sharedInstance.currentAppVersion forKey:OWSOrphanDataCleaner_LastCleaningVersionKey inCollection:OWSOrphanDataCleaner_Collection]; + [databaseConnection setDate:[NSDate new] + forKey:OWSOrphanDataCleaner_LastCleaningDateKey + inCollection:OWSOrphanDataCleaner_Collection]; } failure:^{ DDLogInfo(@"%@ Aborting orphan data cleanup.", self.logTag); From 2fd77fcc29232f996254770e548acb8051a6fb22 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 7 Aug 2018 13:16:30 -0400 Subject: [PATCH 5/6] Fix typo. --- Pods | 2 +- Signal/src/util/OWSOrphanDataCleaner.m | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Pods b/Pods index d5ef8e9a1a..716524e3d0 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit d5ef8e9a1a7dce57232dd534af17eddbca938427 +Subproject commit 716524e3d03351f6a26a3883650e40991c9efdbe diff --git a/Signal/src/util/OWSOrphanDataCleaner.m b/Signal/src/util/OWSOrphanDataCleaner.m index 41c582d3d2..b2e58e8e5b 100644 --- a/Signal/src/util/OWSOrphanDataCleaner.m +++ b/Signal/src/util/OWSOrphanDataCleaner.m @@ -17,7 +17,7 @@ #import #import #import -#import +#import #import NS_ASSUME_NONNULL_BEGIN @@ -427,10 +427,10 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); __block NSString *_Nullable lastCleaningVersion; __block NSDate *_Nullable lastCleaningDate; [databaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { - lastCleaningVersion = [databaseConnection stringForKey:OWSOrphanDataCleaner_LastCleaningVersionKey - inCollection:OWSOrphanDataCleaner_Collection]; - lastCleaningDate = [databaseConnection dateForKey:OWSOrphanDataCleaner_LastCleaningDateKey - inCollection:OWSOrphanDataCleaner_Collection]; + lastCleaningVersion = [transaction stringForKey:OWSOrphanDataCleaner_LastCleaningVersionKey + inCollection:OWSOrphanDataCleaner_Collection]; + lastCleaningDate = [transaction dateForKey:OWSOrphanDataCleaner_LastCleaningDateKey + inCollection:OWSOrphanDataCleaner_Collection]; }]; // Only clean up once per app version. @@ -515,12 +515,14 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); success:^{ DDLogInfo(@"%@ Completed orphan data cleanup.", self.logTag); - [databaseConnection setObject:AppVersion.sharedInstance.currentAppVersion - forKey:OWSOrphanDataCleaner_LastCleaningVersionKey - inCollection:OWSOrphanDataCleaner_Collection]; - [databaseConnection setDate:[NSDate new] - forKey:OWSOrphanDataCleaner_LastCleaningDateKey - inCollection:OWSOrphanDataCleaner_Collection]; + [databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [transaction setObject:AppVersion.sharedInstance.currentAppVersion + forKey:OWSOrphanDataCleaner_LastCleaningVersionKey + inCollection:OWSOrphanDataCleaner_Collection]; + [transaction setDate:[NSDate new] + forKey:OWSOrphanDataCleaner_LastCleaningDateKey + inCollection:OWSOrphanDataCleaner_Collection]; + }]; } failure:^{ DDLogInfo(@"%@ Aborting orphan data cleanup.", self.logTag); From aeb539502d7d3a465e1d15006038f24ef35e6e32 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 7 Aug 2018 13:18:04 -0400 Subject: [PATCH 6/6] Update Cocoapods. --- Pods | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pods b/Pods index 716524e3d0..e680d157ee 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit 716524e3d03351f6a26a3883650e40991c9efdbe +Subproject commit e680d157ee32f4079cc2e126068773cd8280f118