mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Merge branch 'charlesmchen/incrementalBackup'
This commit is contained in:
commit
bdb35c566c
2
Pods
2
Pods
|
@ -1 +1 @@
|
|||
Subproject commit 9d3b5ade1d08c45119aff9cc3c27452cf6b89f35
|
||||
Subproject commit 93e79025cf285042cb397f3f4d1e0d52c68b9ecc
|
|
@ -8,11 +8,36 @@
|
|||
|
||||
/* Begin PBXBuildFile section */
|
||||
2AE2882E4C2B96BFFF9EE27C /* Pods_SignalShareExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0F94C85CB0B235DA37F68ED0 /* Pods_SignalShareExtension.framework */; };
|
||||
34074F5B203D093B004596AE /* OWSSoundSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34074F59203D093A004596AE /* OWSSoundSettingsViewController.m */; };
|
||||
34074F61203D0CBE004596AE /* OWSSounds.m in Sources */ = {isa = PBXBuildFile; fileRef = 34074F5F203D0CBD004596AE /* OWSSounds.m */; };
|
||||
34074F62203D0CBE004596AE /* OWSSounds.h in Headers */ = {isa = PBXBuildFile; fileRef = 34074F60203D0CBE004596AE /* OWSSounds.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
340B02BA1FA0D6C700F9CFEC /* ConversationViewItemTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 340B02B91FA0D6C700F9CFEC /* ConversationViewItemTest.m */; };
|
||||
340CB2271EAC25820001CAA1 /* UpdateGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340CB2261EAC25820001CAA1 /* UpdateGroupViewController.m */; };
|
||||
340FC8A7204DAC8D007AEB0F /* RegistrationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC876204DAC8C007AEB0F /* RegistrationViewController.m */; };
|
||||
340FC8A8204DAC8D007AEB0F /* CodeVerificationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC877204DAC8C007AEB0F /* CodeVerificationViewController.m */; };
|
||||
340FC8A9204DAC8D007AEB0F /* NotificationSettingsOptionsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC87B204DAC8C007AEB0F /* NotificationSettingsOptionsViewController.m */; };
|
||||
340FC8AA204DAC8D007AEB0F /* NotificationSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC87C204DAC8C007AEB0F /* NotificationSettingsViewController.m */; };
|
||||
340FC8AB204DAC8D007AEB0F /* DomainFrontingCountryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC87D204DAC8C007AEB0F /* DomainFrontingCountryViewController.m */; };
|
||||
340FC8AC204DAC8D007AEB0F /* PrivacySettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC87E204DAC8C007AEB0F /* PrivacySettingsTableViewController.m */; };
|
||||
340FC8AD204DAC8D007AEB0F /* OWSLinkedDevicesTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC882204DAC8C007AEB0F /* OWSLinkedDevicesTableViewController.m */; };
|
||||
340FC8AE204DAC8D007AEB0F /* OWSSoundSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC883204DAC8C007AEB0F /* OWSSoundSettingsViewController.m */; };
|
||||
340FC8AF204DAC8D007AEB0F /* OWSLinkDeviceViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC885204DAC8C007AEB0F /* OWSLinkDeviceViewController.m */; };
|
||||
340FC8B0204DAC8D007AEB0F /* AddToBlockListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC886204DAC8C007AEB0F /* AddToBlockListViewController.m */; };
|
||||
340FC8B1204DAC8D007AEB0F /* BlockListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC887204DAC8C007AEB0F /* BlockListViewController.m */; };
|
||||
340FC8B2204DAC8D007AEB0F /* AdvancedSettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC88C204DAC8C007AEB0F /* AdvancedSettingsTableViewController.m */; };
|
||||
340FC8B3204DAC8D007AEB0F /* AppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC88D204DAC8C007AEB0F /* AppSettingsViewController.m */; };
|
||||
340FC8B4204DAC8D007AEB0F /* OWSBackupSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC88E204DAC8C007AEB0F /* OWSBackupSettingsViewController.m */; };
|
||||
340FC8B5204DAC8D007AEB0F /* AboutTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC893204DAC8C007AEB0F /* AboutTableViewController.m */; };
|
||||
340FC8B6204DAC8D007AEB0F /* OWSQRCodeScanningViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC896204DAC8C007AEB0F /* OWSQRCodeScanningViewController.m */; };
|
||||
340FC8B7204DAC8D007AEB0F /* OWSConversationSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC89A204DAC8D007AEB0F /* OWSConversationSettingsViewController.m */; };
|
||||
340FC8B8204DAC8D007AEB0F /* AddToGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC89B204DAC8D007AEB0F /* AddToGroupViewController.m */; };
|
||||
340FC8B9204DAC8D007AEB0F /* UpdateGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC89C204DAC8D007AEB0F /* UpdateGroupViewController.m */; };
|
||||
340FC8BA204DAC8D007AEB0F /* FingerprintViewScanController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC89F204DAC8D007AEB0F /* FingerprintViewScanController.m */; };
|
||||
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 /* OWSBackupExport.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8BF204DB7D2007AEB0F /* OWSBackupExport.m */; };
|
||||
340FC8C2204DDF67007AEB0F /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 340FC8C1204DDF66007AEB0F /* CloudKit.framework */; };
|
||||
340FC8C5204DE223007AEB0F /* DebugUIBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8C4204DE223007AEB0F /* DebugUIBackup.m */; };
|
||||
340FC8C7204DE64D007AEB0F /* OWSBackupAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8C6204DE64D007AEB0F /* OWSBackupAPI.swift */; };
|
||||
341F2C0F1F2B8AE700D07D6B /* DebugUIMisc.m in Sources */ = {isa = PBXBuildFile; fileRef = 341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */; };
|
||||
3430FE181F7751D4000EC51B /* GiphyAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3430FE171F7751D4000EC51B /* GiphyAPI.swift */; };
|
||||
34330A5A1E7875FB00DF2FB9 /* fontawesome-webfont.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 34330A591E7875FB00DF2FB9 /* fontawesome-webfont.ttf */; };
|
||||
|
@ -113,7 +138,6 @@
|
|||
34612A061FD7238600532771 /* OWSContactsSyncing.h in Headers */ = {isa = PBXBuildFile; fileRef = 34612A041FD7238500532771 /* OWSContactsSyncing.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
34612A071FD7238600532771 /* OWSContactsSyncing.m in Sources */ = {isa = PBXBuildFile; fileRef = 34612A051FD7238500532771 /* OWSContactsSyncing.m */; };
|
||||
346B66311F4E29B200E5122F /* CropScaleImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346B66301F4E29B200E5122F /* CropScaleImageViewController.swift */; };
|
||||
3472229F1EB22FFE00E53955 /* AddToGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3472229E1EB22FFE00E53955 /* AddToGroupViewController.m */; };
|
||||
347850311FD7494A007B8332 /* dripicons-v2.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 34330A5B1E787A9800DF2FB9 /* dripicons-v2.ttf */; };
|
||||
347850321FD7494A007B8332 /* ElegantIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 34330A5D1E787BD800DF2FB9 /* ElegantIcons.ttf */; };
|
||||
347850331FD7494A007B8332 /* fontawesome-webfont.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 34330A591E7875FB00DF2FB9 /* fontawesome-webfont.ttf */; };
|
||||
|
@ -127,38 +151,20 @@
|
|||
3478506C1FD9B78A007B8332 /* NoopNotificationsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347850681FD9B78A007B8332 /* NoopNotificationsManager.swift */; };
|
||||
347850711FDAEB17007B8332 /* OWSUserProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 3478506F1FDAEB16007B8332 /* OWSUserProfile.m */; };
|
||||
347850721FDAEB17007B8332 /* OWSUserProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 347850701FDAEB16007B8332 /* OWSUserProfile.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
347E0B7A2003CD7500BC2F76 /* OWSBackupExportViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 347E0B762003CD7400BC2F76 /* OWSBackupExportViewController.m */; };
|
||||
347E0B7B2003CD7500BC2F76 /* OWSBackupImportViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 347E0B782003CD7400BC2F76 /* OWSBackupImportViewController.m */; };
|
||||
3497DBEC1ECE257500DB2605 /* OWSCountryMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 3497DBEB1ECE257500DB2605 /* OWSCountryMetadata.m */; };
|
||||
3497DBEF1ECE2E4700DB2605 /* DomainFrontingCountryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3497DBEE1ECE2E4700DB2605 /* DomainFrontingCountryViewController.m */; };
|
||||
34A55F3720485465002CC6DE /* OWS2FARegistrationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */; };
|
||||
34A910601FFEB114000C4745 /* OWSBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A9105F1FFEB114000C4745 /* OWSBackup.m */; };
|
||||
34B0796D1FCF46B100E248C2 /* MainAppContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B0796B1FCF46B000E248C2 /* MainAppContext.m */; };
|
||||
34B3F8711E8DF1700035BE1A /* AboutTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8351E8DF1700035BE1A /* AboutTableViewController.m */; };
|
||||
34B3F8721E8DF1700035BE1A /* AdvancedSettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8371E8DF1700035BE1A /* AdvancedSettingsTableViewController.m */; };
|
||||
34B3F8751E8DF1700035BE1A /* CallViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F83B1E8DF1700035BE1A /* CallViewController.swift */; };
|
||||
34B3F8761E8DF1700035BE1A /* CodeVerificationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F83D1E8DF1700035BE1A /* CodeVerificationViewController.m */; };
|
||||
34B3F8771E8DF1700035BE1A /* ContactsPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F83E1E8DF1700035BE1A /* ContactsPicker.swift */; };
|
||||
34B3F8781E8DF1700035BE1A /* ContactsPicker.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34B3F83F1E8DF1700035BE1A /* ContactsPicker.xib */; };
|
||||
34B3F87B1E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8441E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift */; };
|
||||
34B3F87C1E8DF1700035BE1A /* FingerprintViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8461E8DF1700035BE1A /* FingerprintViewController.m */; };
|
||||
34B3F87E1E8DF1700035BE1A /* InboxTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F84A1E8DF1700035BE1A /* InboxTableViewCell.m */; };
|
||||
34B3F8801E8DF1700035BE1A /* InviteFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F84C1E8DF1700035BE1A /* InviteFlow.swift */; };
|
||||
34B3F8821E8DF1700035BE1A /* NewContactThreadViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8501E8DF1700035BE1A /* NewContactThreadViewController.m */; };
|
||||
34B3F8851E8DF1700035BE1A /* NewGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8551E8DF1700035BE1A /* NewGroupViewController.m */; };
|
||||
34B3F8861E8DF1700035BE1A /* NotificationSettingsOptionsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8571E8DF1700035BE1A /* NotificationSettingsOptionsViewController.m */; };
|
||||
34B3F8871E8DF1700035BE1A /* NotificationSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8591E8DF1700035BE1A /* NotificationSettingsViewController.m */; };
|
||||
34B3F8891E8DF1700035BE1A /* OWSConversationSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F85C1E8DF1700035BE1A /* OWSConversationSettingsViewController.m */; };
|
||||
34B3F88A1E8DF1700035BE1A /* OWSLinkDeviceViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F85E1E8DF1700035BE1A /* OWSLinkDeviceViewController.m */; };
|
||||
34B3F88B1E8DF1700035BE1A /* OWSLinkedDevicesTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8601E8DF1700035BE1A /* OWSLinkedDevicesTableViewController.m */; };
|
||||
34B3F88D1E8DF1700035BE1A /* OWSQRCodeScanningViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8631E8DF1700035BE1A /* OWSQRCodeScanningViewController.m */; };
|
||||
34B3F88E1E8DF1700035BE1A /* PrivacySettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8651E8DF1700035BE1A /* PrivacySettingsTableViewController.m */; };
|
||||
34B3F88F1E8DF1710035BE1A /* RegistrationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8671E8DF1700035BE1A /* RegistrationViewController.m */; };
|
||||
34B3F8901E8DF1710035BE1A /* AppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8691E8DF1700035BE1A /* AppSettingsViewController.m */; };
|
||||
34B3F8911E8DF1710035BE1A /* ShowGroupMembersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F86B1E8DF1700035BE1A /* ShowGroupMembersViewController.m */; };
|
||||
34B3F8931E8DF1710035BE1A /* SignalsNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F86E1E8DF1700035BE1A /* SignalsNavigationController.m */; };
|
||||
34B3F8941E8DF1710035BE1A /* HomeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8701E8DF1700035BE1A /* HomeViewController.m */; };
|
||||
34B3F89C1E8DF3270035BE1A /* BlockListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F89B1E8DF3270035BE1A /* BlockListViewController.m */; };
|
||||
34BECE2B1F74C12700D7438D /* DebugUIStress.m in Sources */ = {isa = PBXBuildFile; fileRef = 34BECE2A1F74C12700D7438D /* DebugUIStress.m */; };
|
||||
34BECE2E1F7ABCE000D7438D /* GifPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34BECE2D1F7ABCE000D7438D /* GifPickerViewController.swift */; };
|
||||
34BECE301F7ABCF800D7438D /* GifPickerLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34BECE2F1F7ABCF800D7438D /* GifPickerLayout.swift */; };
|
||||
|
@ -173,7 +179,6 @@
|
|||
34C6B0AE1FA0E4AA00D35993 /* test-jpg.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 34C6B0AD1FA0E4AA00D35993 /* test-jpg.jpg */; };
|
||||
34CA1C271F7156F300E51C51 /* MessageDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34CA1C261F7156F300E51C51 /* MessageDetailViewController.swift */; };
|
||||
34CCAF381F0C0599004084F4 /* AppUpdateNag.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CCAF371F0C0599004084F4 /* AppUpdateNag.m */; };
|
||||
34CCAF3B1F0C2748004084F4 /* OWSAddToContactViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CCAF3A1F0C2748004084F4 /* OWSAddToContactViewController.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 */; };
|
||||
|
@ -203,11 +208,9 @@
|
|||
34D8C02B1ED3685800188D7C /* DebugUIContacts.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D8C02A1ED3685800188D7C /* DebugUIContacts.m */; };
|
||||
34D99C931F2937CC00D284D6 /* OWSAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */; };
|
||||
34DB0BED2011548B007B313F /* OWSDatabaseConverterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DB0BEC2011548B007B313F /* OWSDatabaseConverterTest.m */; };
|
||||
34DFCB851E8E04B500053165 /* AddToBlockListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DFCB841E8E04B500053165 /* AddToBlockListViewController.m */; };
|
||||
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 */; };
|
||||
34E8BF381EE9E2FD00F5F4CA /* FingerprintViewScanController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E8BF371EE9E2FD00F5F4CA /* FingerprintViewScanController.m */; };
|
||||
34F308A21ECB469700BB7697 /* OWSBezierPathView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F308A11ECB469700BB7697 /* OWSBezierPathView.m */; };
|
||||
34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 34FD936F1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m */; };
|
||||
4503F1BE20470A5B00CEE724 /* classic-quiet.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 4503F1BB20470A5B00CEE724 /* classic-quiet.aifc */; };
|
||||
|
@ -515,16 +518,65 @@
|
|||
3400C7951EAF99F4008A8584 /* SelectThreadViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SelectThreadViewController.m; sourceTree = "<group>"; };
|
||||
3400C7971EAFB772008A8584 /* ThreadViewHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadViewHelper.h; sourceTree = "<group>"; };
|
||||
3400C7981EAFB772008A8584 /* ThreadViewHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThreadViewHelper.m; sourceTree = "<group>"; };
|
||||
34074F59203D093A004596AE /* OWSSoundSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSSoundSettingsViewController.m; sourceTree = "<group>"; };
|
||||
34074F5A203D093B004596AE /* OWSSoundSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSSoundSettingsViewController.h; sourceTree = "<group>"; };
|
||||
34074F5F203D0CBD004596AE /* OWSSounds.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSSounds.m; sourceTree = "<group>"; };
|
||||
34074F60203D0CBE004596AE /* OWSSounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSSounds.h; sourceTree = "<group>"; };
|
||||
340B02B61F9FD31800F9CFEC /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = translations/he.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
340B02B91FA0D6C700F9CFEC /* ConversationViewItemTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConversationViewItemTest.m; sourceTree = "<group>"; };
|
||||
340CB2221EAC155C0001CAA1 /* ContactsViewHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsViewHelper.h; sourceTree = "<group>"; };
|
||||
340CB2231EAC155C0001CAA1 /* ContactsViewHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactsViewHelper.m; sourceTree = "<group>"; };
|
||||
340CB2251EAC25820001CAA1 /* UpdateGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UpdateGroupViewController.h; sourceTree = "<group>"; };
|
||||
340CB2261EAC25820001CAA1 /* UpdateGroupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UpdateGroupViewController.m; sourceTree = "<group>"; };
|
||||
340FC876204DAC8C007AEB0F /* RegistrationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegistrationViewController.m; sourceTree = "<group>"; };
|
||||
340FC877204DAC8C007AEB0F /* CodeVerificationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodeVerificationViewController.m; sourceTree = "<group>"; };
|
||||
340FC878204DAC8C007AEB0F /* RegistrationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegistrationViewController.h; sourceTree = "<group>"; };
|
||||
340FC879204DAC8C007AEB0F /* CodeVerificationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeVerificationViewController.h; sourceTree = "<group>"; };
|
||||
340FC87B204DAC8C007AEB0F /* NotificationSettingsOptionsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationSettingsOptionsViewController.m; sourceTree = "<group>"; };
|
||||
340FC87C204DAC8C007AEB0F /* NotificationSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationSettingsViewController.m; sourceTree = "<group>"; };
|
||||
340FC87D204DAC8C007AEB0F /* DomainFrontingCountryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DomainFrontingCountryViewController.m; sourceTree = "<group>"; };
|
||||
340FC87E204DAC8C007AEB0F /* PrivacySettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PrivacySettingsTableViewController.m; sourceTree = "<group>"; };
|
||||
340FC87F204DAC8C007AEB0F /* OWSBackupSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupSettingsViewController.h; sourceTree = "<group>"; };
|
||||
340FC880204DAC8C007AEB0F /* AppSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppSettingsViewController.h; sourceTree = "<group>"; };
|
||||
340FC881204DAC8C007AEB0F /* AdvancedSettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdvancedSettingsTableViewController.h; sourceTree = "<group>"; };
|
||||
340FC882204DAC8C007AEB0F /* OWSLinkedDevicesTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSLinkedDevicesTableViewController.m; sourceTree = "<group>"; };
|
||||
340FC883204DAC8C007AEB0F /* OWSSoundSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSSoundSettingsViewController.m; sourceTree = "<group>"; };
|
||||
340FC884204DAC8C007AEB0F /* AboutTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutTableViewController.h; sourceTree = "<group>"; };
|
||||
340FC885204DAC8C007AEB0F /* OWSLinkDeviceViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSLinkDeviceViewController.m; sourceTree = "<group>"; };
|
||||
340FC886204DAC8C007AEB0F /* AddToBlockListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddToBlockListViewController.m; sourceTree = "<group>"; };
|
||||
340FC887204DAC8C007AEB0F /* BlockListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BlockListViewController.m; sourceTree = "<group>"; };
|
||||
340FC888204DAC8C007AEB0F /* OWSQRCodeScanningViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSQRCodeScanningViewController.h; sourceTree = "<group>"; };
|
||||
340FC889204DAC8C007AEB0F /* DomainFrontingCountryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DomainFrontingCountryViewController.h; sourceTree = "<group>"; };
|
||||
340FC88A204DAC8C007AEB0F /* NotificationSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotificationSettingsViewController.h; sourceTree = "<group>"; };
|
||||
340FC88B204DAC8C007AEB0F /* NotificationSettingsOptionsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotificationSettingsOptionsViewController.h; sourceTree = "<group>"; };
|
||||
340FC88C204DAC8C007AEB0F /* AdvancedSettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AdvancedSettingsTableViewController.m; sourceTree = "<group>"; };
|
||||
340FC88D204DAC8C007AEB0F /* AppSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppSettingsViewController.m; sourceTree = "<group>"; };
|
||||
340FC88E204DAC8C007AEB0F /* OWSBackupSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupSettingsViewController.m; sourceTree = "<group>"; };
|
||||
340FC88F204DAC8C007AEB0F /* PrivacySettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivacySettingsTableViewController.h; sourceTree = "<group>"; };
|
||||
340FC890204DAC8C007AEB0F /* BlockListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockListViewController.h; sourceTree = "<group>"; };
|
||||
340FC891204DAC8C007AEB0F /* OWSLinkDeviceViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSLinkDeviceViewController.h; sourceTree = "<group>"; };
|
||||
340FC892204DAC8C007AEB0F /* AddToBlockListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddToBlockListViewController.h; sourceTree = "<group>"; };
|
||||
340FC893204DAC8C007AEB0F /* AboutTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutTableViewController.m; sourceTree = "<group>"; };
|
||||
340FC894204DAC8C007AEB0F /* OWSSoundSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSSoundSettingsViewController.h; sourceTree = "<group>"; };
|
||||
340FC895204DAC8C007AEB0F /* OWSLinkedDevicesTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSLinkedDevicesTableViewController.h; sourceTree = "<group>"; };
|
||||
340FC896204DAC8C007AEB0F /* OWSQRCodeScanningViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSQRCodeScanningViewController.m; sourceTree = "<group>"; };
|
||||
340FC898204DAC8D007AEB0F /* OWSAddToContactViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSAddToContactViewController.h; sourceTree = "<group>"; };
|
||||
340FC899204DAC8D007AEB0F /* OWSConversationSettingsViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSConversationSettingsViewDelegate.h; sourceTree = "<group>"; };
|
||||
340FC89A204DAC8D007AEB0F /* OWSConversationSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSConversationSettingsViewController.m; sourceTree = "<group>"; };
|
||||
340FC89B204DAC8D007AEB0F /* AddToGroupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddToGroupViewController.m; sourceTree = "<group>"; };
|
||||
340FC89C204DAC8D007AEB0F /* UpdateGroupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UpdateGroupViewController.m; sourceTree = "<group>"; };
|
||||
340FC89D204DAC8D007AEB0F /* FingerprintViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FingerprintViewController.h; sourceTree = "<group>"; };
|
||||
340FC89E204DAC8D007AEB0F /* ShowGroupMembersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShowGroupMembersViewController.h; sourceTree = "<group>"; };
|
||||
340FC89F204DAC8D007AEB0F /* FingerprintViewScanController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FingerprintViewScanController.m; sourceTree = "<group>"; };
|
||||
340FC8A0204DAC8D007AEB0F /* OWSConversationSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSConversationSettingsViewController.h; sourceTree = "<group>"; };
|
||||
340FC8A1204DAC8D007AEB0F /* OWSAddToContactViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSAddToContactViewController.m; sourceTree = "<group>"; };
|
||||
340FC8A2204DAC8D007AEB0F /* FingerprintViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FingerprintViewController.m; sourceTree = "<group>"; };
|
||||
340FC8A3204DAC8D007AEB0F /* UpdateGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UpdateGroupViewController.h; sourceTree = "<group>"; };
|
||||
340FC8A4204DAC8D007AEB0F /* AddToGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddToGroupViewController.h; sourceTree = "<group>"; };
|
||||
340FC8A5204DAC8D007AEB0F /* FingerprintViewScanController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FingerprintViewScanController.h; sourceTree = "<group>"; };
|
||||
340FC8A6204DAC8D007AEB0F /* ShowGroupMembersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShowGroupMembersViewController.m; sourceTree = "<group>"; };
|
||||
340FC8BE204DB7D1007AEB0F /* OWSBackupExport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupExport.h; sourceTree = "<group>"; };
|
||||
340FC8BF204DB7D2007AEB0F /* OWSBackupExport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupExport.m; sourceTree = "<group>"; };
|
||||
340FC8C1204DDF66007AEB0F /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; };
|
||||
340FC8C3204DE223007AEB0F /* DebugUIBackup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIBackup.h; sourceTree = "<group>"; };
|
||||
340FC8C4204DE223007AEB0F /* DebugUIBackup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIBackup.m; sourceTree = "<group>"; };
|
||||
340FC8C6204DE64D007AEB0F /* OWSBackupAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSBackupAPI.swift; sourceTree = "<group>"; };
|
||||
341458471FBE11C4005ABCF9 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = translations/fa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
341F2C0D1F2B8AE700D07D6B /* DebugUIMisc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIMisc.h; sourceTree = "<group>"; };
|
||||
341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIMisc.m; sourceTree = "<group>"; };
|
||||
|
@ -639,8 +691,6 @@
|
|||
34612A041FD7238500532771 /* OWSContactsSyncing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSContactsSyncing.h; sourceTree = "<group>"; };
|
||||
34612A051FD7238500532771 /* OWSContactsSyncing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactsSyncing.m; sourceTree = "<group>"; };
|
||||
346B66301F4E29B200E5122F /* CropScaleImageViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CropScaleImageViewController.swift; sourceTree = "<group>"; };
|
||||
3472229D1EB22FFE00E53955 /* AddToGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddToGroupViewController.h; sourceTree = "<group>"; };
|
||||
3472229E1EB22FFE00E53955 /* AddToGroupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddToGroupViewController.m; sourceTree = "<group>"; };
|
||||
347850561FD86544007B8332 /* SAEFailedViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SAEFailedViewController.swift; sourceTree = "<group>"; };
|
||||
347850581FD9972E007B8332 /* SwiftSingletons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftSingletons.swift; sourceTree = "<group>"; };
|
||||
3478505A1FD999D5007B8332 /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = translations/et.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
|
@ -651,16 +701,10 @@
|
|||
347850681FD9B78A007B8332 /* NoopNotificationsManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NoopNotificationsManager.swift; sourceTree = "<group>"; };
|
||||
3478506F1FDAEB16007B8332 /* OWSUserProfile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSUserProfile.m; sourceTree = "<group>"; };
|
||||
347850701FDAEB16007B8332 /* OWSUserProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSUserProfile.h; sourceTree = "<group>"; };
|
||||
347E0B762003CD7400BC2F76 /* OWSBackupExportViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupExportViewController.m; sourceTree = "<group>"; };
|
||||
347E0B772003CD7400BC2F76 /* OWSBackupExportViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupExportViewController.h; sourceTree = "<group>"; };
|
||||
347E0B782003CD7400BC2F76 /* OWSBackupImportViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupImportViewController.m; sourceTree = "<group>"; };
|
||||
347E0B792003CD7500BC2F76 /* OWSBackupImportViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupImportViewController.h; sourceTree = "<group>"; };
|
||||
348F2EAD1F0D21BC00D4ECE0 /* DeviceSleepManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceSleepManager.swift; sourceTree = "<group>"; };
|
||||
3495BC911F1426B800B478F5 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = translations/ar.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
3497DBEA1ECE257500DB2605 /* OWSCountryMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSCountryMetadata.h; sourceTree = "<group>"; };
|
||||
3497DBEB1ECE257500DB2605 /* OWSCountryMetadata.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSCountryMetadata.m; sourceTree = "<group>"; };
|
||||
3497DBED1ECE2E4700DB2605 /* DomainFrontingCountryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DomainFrontingCountryViewController.h; sourceTree = "<group>"; };
|
||||
3497DBEE1ECE2E4700DB2605 /* DomainFrontingCountryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DomainFrontingCountryViewController.m; sourceTree = "<group>"; };
|
||||
34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWS2FARegistrationViewController.m; sourceTree = "<group>"; };
|
||||
34A55F3620485464002CC6DE /* OWS2FARegistrationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWS2FARegistrationViewController.h; sourceTree = "<group>"; };
|
||||
34A9105E1FFEB113000C4745 /* OWSBackup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackup.h; sourceTree = "<group>"; };
|
||||
|
@ -668,20 +712,12 @@
|
|||
34B0796B1FCF46B000E248C2 /* MainAppContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainAppContext.m; sourceTree = "<group>"; };
|
||||
34B0796C1FCF46B000E248C2 /* MainAppContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainAppContext.h; sourceTree = "<group>"; };
|
||||
34B0796E1FD07B1E00E248C2 /* SignalShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SignalShareExtension.entitlements; sourceTree = "<group>"; };
|
||||
34B3F8341E8DF1700035BE1A /* AboutTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutTableViewController.h; sourceTree = "<group>"; };
|
||||
34B3F8351E8DF1700035BE1A /* AboutTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutTableViewController.m; sourceTree = "<group>"; };
|
||||
34B3F8361E8DF1700035BE1A /* AdvancedSettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdvancedSettingsTableViewController.h; sourceTree = "<group>"; };
|
||||
34B3F8371E8DF1700035BE1A /* AdvancedSettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AdvancedSettingsTableViewController.m; sourceTree = "<group>"; };
|
||||
34B3F8391E8DF1700035BE1A /* AttachmentSharing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AttachmentSharing.h; sourceTree = "<group>"; };
|
||||
34B3F83A1E8DF1700035BE1A /* AttachmentSharing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AttachmentSharing.m; sourceTree = "<group>"; };
|
||||
34B3F83B1E8DF1700035BE1A /* CallViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallViewController.swift; sourceTree = "<group>"; };
|
||||
34B3F83C1E8DF1700035BE1A /* CodeVerificationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeVerificationViewController.h; sourceTree = "<group>"; };
|
||||
34B3F83D1E8DF1700035BE1A /* CodeVerificationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodeVerificationViewController.m; sourceTree = "<group>"; };
|
||||
34B3F83E1E8DF1700035BE1A /* ContactsPicker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactsPicker.swift; sourceTree = "<group>"; };
|
||||
34B3F83F1E8DF1700035BE1A /* ContactsPicker.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ContactsPicker.xib; sourceTree = "<group>"; };
|
||||
34B3F8441E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExperienceUpgradesPageViewController.swift; sourceTree = "<group>"; };
|
||||
34B3F8451E8DF1700035BE1A /* FingerprintViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FingerprintViewController.h; sourceTree = "<group>"; };
|
||||
34B3F8461E8DF1700035BE1A /* FingerprintViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FingerprintViewController.m; sourceTree = "<group>"; };
|
||||
34B3F8491E8DF1700035BE1A /* InboxTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InboxTableViewCell.h; sourceTree = "<group>"; };
|
||||
34B3F84A1E8DF1700035BE1A /* InboxTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InboxTableViewCell.m; sourceTree = "<group>"; };
|
||||
34B3F84C1E8DF1700035BE1A /* InviteFlow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InviteFlow.swift; sourceTree = "<group>"; };
|
||||
|
@ -689,32 +725,10 @@
|
|||
34B3F8501E8DF1700035BE1A /* NewContactThreadViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NewContactThreadViewController.m; sourceTree = "<group>"; };
|
||||
34B3F8541E8DF1700035BE1A /* NewGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NewGroupViewController.h; sourceTree = "<group>"; };
|
||||
34B3F8551E8DF1700035BE1A /* NewGroupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NewGroupViewController.m; sourceTree = "<group>"; };
|
||||
34B3F8561E8DF1700035BE1A /* NotificationSettingsOptionsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotificationSettingsOptionsViewController.h; sourceTree = "<group>"; };
|
||||
34B3F8571E8DF1700035BE1A /* NotificationSettingsOptionsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationSettingsOptionsViewController.m; sourceTree = "<group>"; };
|
||||
34B3F8581E8DF1700035BE1A /* NotificationSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotificationSettingsViewController.h; sourceTree = "<group>"; };
|
||||
34B3F8591E8DF1700035BE1A /* NotificationSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationSettingsViewController.m; sourceTree = "<group>"; };
|
||||
34B3F85B1E8DF1700035BE1A /* OWSConversationSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSConversationSettingsViewController.h; sourceTree = "<group>"; };
|
||||
34B3F85C1E8DF1700035BE1A /* OWSConversationSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSConversationSettingsViewController.m; sourceTree = "<group>"; };
|
||||
34B3F85D1E8DF1700035BE1A /* OWSLinkDeviceViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSLinkDeviceViewController.h; sourceTree = "<group>"; };
|
||||
34B3F85E1E8DF1700035BE1A /* OWSLinkDeviceViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSLinkDeviceViewController.m; sourceTree = "<group>"; };
|
||||
34B3F85F1E8DF1700035BE1A /* OWSLinkedDevicesTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSLinkedDevicesTableViewController.h; sourceTree = "<group>"; };
|
||||
34B3F8601E8DF1700035BE1A /* OWSLinkedDevicesTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSLinkedDevicesTableViewController.m; sourceTree = "<group>"; };
|
||||
34B3F8621E8DF1700035BE1A /* OWSQRCodeScanningViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSQRCodeScanningViewController.h; sourceTree = "<group>"; };
|
||||
34B3F8631E8DF1700035BE1A /* OWSQRCodeScanningViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSQRCodeScanningViewController.m; sourceTree = "<group>"; };
|
||||
34B3F8641E8DF1700035BE1A /* PrivacySettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivacySettingsTableViewController.h; sourceTree = "<group>"; };
|
||||
34B3F8651E8DF1700035BE1A /* PrivacySettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PrivacySettingsTableViewController.m; sourceTree = "<group>"; };
|
||||
34B3F8661E8DF1700035BE1A /* RegistrationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegistrationViewController.h; sourceTree = "<group>"; };
|
||||
34B3F8671E8DF1700035BE1A /* RegistrationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegistrationViewController.m; sourceTree = "<group>"; };
|
||||
34B3F8681E8DF1700035BE1A /* AppSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppSettingsViewController.h; sourceTree = "<group>"; };
|
||||
34B3F8691E8DF1700035BE1A /* AppSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppSettingsViewController.m; sourceTree = "<group>"; };
|
||||
34B3F86A1E8DF1700035BE1A /* ShowGroupMembersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShowGroupMembersViewController.h; sourceTree = "<group>"; };
|
||||
34B3F86B1E8DF1700035BE1A /* ShowGroupMembersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShowGroupMembersViewController.m; sourceTree = "<group>"; };
|
||||
34B3F86D1E8DF1700035BE1A /* SignalsNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SignalsNavigationController.h; sourceTree = "<group>"; };
|
||||
34B3F86E1E8DF1700035BE1A /* SignalsNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignalsNavigationController.m; sourceTree = "<group>"; };
|
||||
34B3F86F1E8DF1700035BE1A /* HomeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomeViewController.h; sourceTree = "<group>"; };
|
||||
34B3F8701E8DF1700035BE1A /* HomeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomeViewController.m; sourceTree = "<group>"; };
|
||||
34B3F89A1E8DF3270035BE1A /* BlockListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockListViewController.h; sourceTree = "<group>"; };
|
||||
34B3F89B1E8DF3270035BE1A /* BlockListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BlockListViewController.m; sourceTree = "<group>"; };
|
||||
34B3F89D1E8DF5490035BE1A /* OWSTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSTableViewController.h; sourceTree = "<group>"; };
|
||||
34B3F89E1E8DF5490035BE1A /* OWSTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSTableViewController.m; sourceTree = "<group>"; };
|
||||
34BECE291F74C12700D7438D /* DebugUIStress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIStress.h; sourceTree = "<group>"; };
|
||||
|
@ -739,8 +753,6 @@
|
|||
34CA1C281F7164F700E51C51 /* MediaMessageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaMessageView.swift; sourceTree = "<group>"; };
|
||||
34CCAF361F0C0599004084F4 /* AppUpdateNag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppUpdateNag.h; sourceTree = "<group>"; };
|
||||
34CCAF371F0C0599004084F4 /* AppUpdateNag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppUpdateNag.m; sourceTree = "<group>"; };
|
||||
34CCAF391F0C2748004084F4 /* OWSAddToContactViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSAddToContactViewController.h; sourceTree = "<group>"; };
|
||||
34CCAF3A1F0C2748004084F4 /* OWSAddToContactViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSAddToContactViewController.m; sourceTree = "<group>"; };
|
||||
34CE88E51F2FB9A10098030F /* ProfileViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProfileViewController.h; sourceTree = "<group>"; };
|
||||
34CE88E61F2FB9A10098030F /* ProfileViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProfileViewController.m; sourceTree = "<group>"; };
|
||||
34CF0783203E6B77005C4D61 /* busy_tone_ansi.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = busy_tone_ansi.caf; path = Signal/AudioFiles/busy_tone_ansi.caf; sourceTree = SOURCE_ROOT; };
|
||||
|
@ -784,7 +796,6 @@
|
|||
34D1F0BF1F8EC1760066283D /* MessageRecipientStatusUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageRecipientStatusUtils.swift; sourceTree = "<group>"; };
|
||||
34D5CCA71EAE3D30005515DB /* AvatarViewHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AvatarViewHelper.h; sourceTree = "<group>"; };
|
||||
34D5CCA81EAE3D30005515DB /* AvatarViewHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AvatarViewHelper.m; sourceTree = "<group>"; };
|
||||
34D5CCAB1EAE7136005515DB /* OWSConversationSettingsViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSConversationSettingsViewDelegate.h; sourceTree = "<group>"; };
|
||||
34D8C0231ED3673300188D7C /* DebugUIMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIMessages.h; sourceTree = "<group>"; };
|
||||
34D8C0241ED3673300188D7C /* DebugUIMessages.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIMessages.m; sourceTree = "<group>"; };
|
||||
34D8C0251ED3673300188D7C /* DebugUITableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUITableViewController.h; sourceTree = "<group>"; };
|
||||
|
@ -797,15 +808,11 @@
|
|||
34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSAnalytics.swift; sourceTree = "<group>"; };
|
||||
34DB0BEB2011548A007B313F /* OWSDatabaseConverterTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSDatabaseConverterTest.h; sourceTree = "<group>"; };
|
||||
34DB0BEC2011548B007B313F /* OWSDatabaseConverterTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDatabaseConverterTest.m; sourceTree = "<group>"; };
|
||||
34DFCB831E8E04B400053165 /* AddToBlockListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddToBlockListViewController.h; sourceTree = "<group>"; };
|
||||
34DFCB841E8E04B500053165 /* AddToBlockListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddToBlockListViewController.m; sourceTree = "<group>"; };
|
||||
34E3E5671EC4B19400495BAC /* AudioProgressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AudioProgressView.swift; sourceTree = "<group>"; };
|
||||
34E3EF0B1EFC235B007F6822 /* DebugUIDiskUsage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIDiskUsage.h; sourceTree = "<group>"; };
|
||||
34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIDiskUsage.m; sourceTree = "<group>"; };
|
||||
34E3EF0E1EFC2684007F6822 /* DebugUIPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIPage.h; sourceTree = "<group>"; };
|
||||
34E3EF0F1EFC2684007F6822 /* DebugUIPage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIPage.m; sourceTree = "<group>"; };
|
||||
34E8BF361EE9E2FD00F5F4CA /* FingerprintViewScanController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FingerprintViewScanController.h; sourceTree = "<group>"; };
|
||||
34E8BF371EE9E2FD00F5F4CA /* FingerprintViewScanController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FingerprintViewScanController.m; sourceTree = "<group>"; };
|
||||
34F308A01ECB469700BB7697 /* OWSBezierPathView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBezierPathView.h; sourceTree = "<group>"; };
|
||||
34F308A11ECB469700BB7697 /* OWSBezierPathView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBezierPathView.m; sourceTree = "<group>"; };
|
||||
34FD936E1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWSAnyTouchGestureRecognizer.h; path = views/OWSAnyTouchGestureRecognizer.h; sourceTree = "<group>"; };
|
||||
|
@ -1121,6 +1128,7 @@
|
|||
70377AAB1918450100CAF501 /* MobileCoreServices.framework in Frameworks */,
|
||||
B9EB5ABD1884C002007CBB57 /* MessageUI.framework in Frameworks */,
|
||||
453518991FC63DBF00210559 /* SignalMessaging.framework in Frameworks */,
|
||||
340FC8C2204DDF67007AEB0F /* CloudKit.framework in Frameworks */,
|
||||
76C87F19181EFCE600C4ACAB /* MediaPlayer.framework in Frameworks */,
|
||||
768A1A2B17FC9CD300E00ED8 /* libz.dylib in Frameworks */,
|
||||
A11CD70D17FA230600A2D1B1 /* QuartzCore.framework in Frameworks */,
|
||||
|
@ -1212,6 +1220,74 @@
|
|||
path = Signal/AudioFiles/messageReceivedSounds;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
340FC875204DAC8C007AEB0F /* Registration */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
340FC879204DAC8C007AEB0F /* CodeVerificationViewController.h */,
|
||||
340FC877204DAC8C007AEB0F /* CodeVerificationViewController.m */,
|
||||
340FC878204DAC8C007AEB0F /* RegistrationViewController.h */,
|
||||
340FC876204DAC8C007AEB0F /* RegistrationViewController.m */,
|
||||
);
|
||||
path = Registration;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
340FC87A204DAC8C007AEB0F /* AppSettings */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
340FC884204DAC8C007AEB0F /* AboutTableViewController.h */,
|
||||
340FC893204DAC8C007AEB0F /* AboutTableViewController.m */,
|
||||
340FC892204DAC8C007AEB0F /* AddToBlockListViewController.h */,
|
||||
340FC886204DAC8C007AEB0F /* AddToBlockListViewController.m */,
|
||||
340FC881204DAC8C007AEB0F /* AdvancedSettingsTableViewController.h */,
|
||||
340FC88C204DAC8C007AEB0F /* AdvancedSettingsTableViewController.m */,
|
||||
340FC880204DAC8C007AEB0F /* AppSettingsViewController.h */,
|
||||
340FC88D204DAC8C007AEB0F /* AppSettingsViewController.m */,
|
||||
340FC890204DAC8C007AEB0F /* BlockListViewController.h */,
|
||||
340FC887204DAC8C007AEB0F /* BlockListViewController.m */,
|
||||
340FC889204DAC8C007AEB0F /* DomainFrontingCountryViewController.h */,
|
||||
340FC87D204DAC8C007AEB0F /* DomainFrontingCountryViewController.m */,
|
||||
340FC88B204DAC8C007AEB0F /* NotificationSettingsOptionsViewController.h */,
|
||||
340FC87B204DAC8C007AEB0F /* NotificationSettingsOptionsViewController.m */,
|
||||
340FC88A204DAC8C007AEB0F /* NotificationSettingsViewController.h */,
|
||||
340FC87C204DAC8C007AEB0F /* NotificationSettingsViewController.m */,
|
||||
340FC87F204DAC8C007AEB0F /* OWSBackupSettingsViewController.h */,
|
||||
340FC88E204DAC8C007AEB0F /* OWSBackupSettingsViewController.m */,
|
||||
340FC891204DAC8C007AEB0F /* OWSLinkDeviceViewController.h */,
|
||||
340FC885204DAC8C007AEB0F /* OWSLinkDeviceViewController.m */,
|
||||
340FC895204DAC8C007AEB0F /* OWSLinkedDevicesTableViewController.h */,
|
||||
340FC882204DAC8C007AEB0F /* OWSLinkedDevicesTableViewController.m */,
|
||||
340FC888204DAC8C007AEB0F /* OWSQRCodeScanningViewController.h */,
|
||||
340FC896204DAC8C007AEB0F /* OWSQRCodeScanningViewController.m */,
|
||||
340FC894204DAC8C007AEB0F /* OWSSoundSettingsViewController.h */,
|
||||
340FC883204DAC8C007AEB0F /* OWSSoundSettingsViewController.m */,
|
||||
340FC88F204DAC8C007AEB0F /* PrivacySettingsTableViewController.h */,
|
||||
340FC87E204DAC8C007AEB0F /* PrivacySettingsTableViewController.m */,
|
||||
);
|
||||
path = AppSettings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
340FC897204DAC8D007AEB0F /* ThreadSettings */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
340FC8A4204DAC8D007AEB0F /* AddToGroupViewController.h */,
|
||||
340FC89B204DAC8D007AEB0F /* AddToGroupViewController.m */,
|
||||
340FC89D204DAC8D007AEB0F /* FingerprintViewController.h */,
|
||||
340FC8A2204DAC8D007AEB0F /* FingerprintViewController.m */,
|
||||
340FC8A5204DAC8D007AEB0F /* FingerprintViewScanController.h */,
|
||||
340FC89F204DAC8D007AEB0F /* FingerprintViewScanController.m */,
|
||||
340FC898204DAC8D007AEB0F /* OWSAddToContactViewController.h */,
|
||||
340FC8A1204DAC8D007AEB0F /* OWSAddToContactViewController.m */,
|
||||
340FC8A0204DAC8D007AEB0F /* OWSConversationSettingsViewController.h */,
|
||||
340FC89A204DAC8D007AEB0F /* OWSConversationSettingsViewController.m */,
|
||||
340FC899204DAC8D007AEB0F /* OWSConversationSettingsViewDelegate.h */,
|
||||
340FC89E204DAC8D007AEB0F /* ShowGroupMembersViewController.h */,
|
||||
340FC8A6204DAC8D007AEB0F /* ShowGroupMembersViewController.m */,
|
||||
340FC8A3204DAC8D007AEB0F /* UpdateGroupViewController.h */,
|
||||
340FC89C204DAC8D007AEB0F /* UpdateGroupViewController.m */,
|
||||
);
|
||||
path = ThreadSettings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
34330A581E7875FB00DF2FB9 /* Fonts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1440,35 +1516,16 @@
|
|||
34B3F8331E8DF1700035BE1A /* ViewControllers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
34B3F8341E8DF1700035BE1A /* AboutTableViewController.h */,
|
||||
34B3F8351E8DF1700035BE1A /* AboutTableViewController.m */,
|
||||
34DFCB831E8E04B400053165 /* AddToBlockListViewController.h */,
|
||||
34DFCB841E8E04B500053165 /* AddToBlockListViewController.m */,
|
||||
3472229D1EB22FFE00E53955 /* AddToGroupViewController.h */,
|
||||
3472229E1EB22FFE00E53955 /* AddToGroupViewController.m */,
|
||||
34B3F8361E8DF1700035BE1A /* AdvancedSettingsTableViewController.h */,
|
||||
34B3F8371E8DF1700035BE1A /* AdvancedSettingsTableViewController.m */,
|
||||
34B3F8681E8DF1700035BE1A /* AppSettingsViewController.h */,
|
||||
34B3F8691E8DF1700035BE1A /* AppSettingsViewController.m */,
|
||||
340FC87A204DAC8C007AEB0F /* AppSettings */,
|
||||
34D5CCA71EAE3D30005515DB /* AvatarViewHelper.h */,
|
||||
34D5CCA81EAE3D30005515DB /* AvatarViewHelper.m */,
|
||||
34B3F89A1E8DF3270035BE1A /* BlockListViewController.h */,
|
||||
34B3F89B1E8DF3270035BE1A /* BlockListViewController.m */,
|
||||
34B3F83B1E8DF1700035BE1A /* CallViewController.swift */,
|
||||
34B3F83C1E8DF1700035BE1A /* CodeVerificationViewController.h */,
|
||||
34B3F83D1E8DF1700035BE1A /* CodeVerificationViewController.m */,
|
||||
34B3F83E1E8DF1700035BE1A /* ContactsPicker.swift */,
|
||||
34B3F83F1E8DF1700035BE1A /* ContactsPicker.xib */,
|
||||
3448BFC01EDF0EA7005B2D69 /* ConversationView */,
|
||||
346B66301F4E29B200E5122F /* CropScaleImageViewController.swift */,
|
||||
34D8C0221ED3673300188D7C /* DebugUI */,
|
||||
3497DBED1ECE2E4700DB2605 /* DomainFrontingCountryViewController.h */,
|
||||
3497DBEE1ECE2E4700DB2605 /* DomainFrontingCountryViewController.m */,
|
||||
34B3F8441E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift */,
|
||||
34B3F8451E8DF1700035BE1A /* FingerprintViewController.h */,
|
||||
34B3F8461E8DF1700035BE1A /* FingerprintViewController.m */,
|
||||
34E8BF361EE9E2FD00F5F4CA /* FingerprintViewScanController.h */,
|
||||
34E8BF371EE9E2FD00F5F4CA /* FingerprintViewScanController.m */,
|
||||
34BECE2C1F7ABCE000D7438D /* GifPicker */,
|
||||
34B3F86F1E8DF1700035BE1A /* HomeViewController.h */,
|
||||
34B3F8701E8DF1700035BE1A /* HomeViewController.m */,
|
||||
|
@ -1482,48 +1539,21 @@
|
|||
34B3F8501E8DF1700035BE1A /* NewContactThreadViewController.m */,
|
||||
34B3F8541E8DF1700035BE1A /* NewGroupViewController.h */,
|
||||
34B3F8551E8DF1700035BE1A /* NewGroupViewController.m */,
|
||||
34B3F8561E8DF1700035BE1A /* NotificationSettingsOptionsViewController.h */,
|
||||
34B3F8571E8DF1700035BE1A /* NotificationSettingsOptionsViewController.m */,
|
||||
34B3F8581E8DF1700035BE1A /* NotificationSettingsViewController.h */,
|
||||
34B3F8591E8DF1700035BE1A /* NotificationSettingsViewController.m */,
|
||||
34A55F3620485464002CC6DE /* OWS2FARegistrationViewController.h */,
|
||||
34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */,
|
||||
345BC30A2047030600257B7C /* OWS2FASettingsViewController.h */,
|
||||
345BC30B2047030600257B7C /* OWS2FASettingsViewController.m */,
|
||||
34CCAF391F0C2748004084F4 /* OWSAddToContactViewController.h */,
|
||||
34CCAF3A1F0C2748004084F4 /* OWSAddToContactViewController.m */,
|
||||
347E0B772003CD7400BC2F76 /* OWSBackupExportViewController.h */,
|
||||
347E0B762003CD7400BC2F76 /* OWSBackupExportViewController.m */,
|
||||
347E0B792003CD7500BC2F76 /* OWSBackupImportViewController.h */,
|
||||
347E0B782003CD7400BC2F76 /* OWSBackupImportViewController.m */,
|
||||
34B3F85B1E8DF1700035BE1A /* OWSConversationSettingsViewController.h */,
|
||||
34B3F85C1E8DF1700035BE1A /* OWSConversationSettingsViewController.m */,
|
||||
34D5CCAB1EAE7136005515DB /* OWSConversationSettingsViewDelegate.h */,
|
||||
3497DBEA1ECE257500DB2605 /* OWSCountryMetadata.h */,
|
||||
3497DBEB1ECE257500DB2605 /* OWSCountryMetadata.m */,
|
||||
34B3F85D1E8DF1700035BE1A /* OWSLinkDeviceViewController.h */,
|
||||
34B3F85E1E8DF1700035BE1A /* OWSLinkDeviceViewController.m */,
|
||||
34B3F85F1E8DF1700035BE1A /* OWSLinkedDevicesTableViewController.h */,
|
||||
34B3F8601E8DF1700035BE1A /* OWSLinkedDevicesTableViewController.m */,
|
||||
34C42D591F45F7A80072EC04 /* OWSNavigationController.h */,
|
||||
34C42D5A1F45F7A80072EC04 /* OWSNavigationController.m */,
|
||||
34B3F8621E8DF1700035BE1A /* OWSQRCodeScanningViewController.h */,
|
||||
34B3F8631E8DF1700035BE1A /* OWSQRCodeScanningViewController.m */,
|
||||
34074F5A203D093B004596AE /* OWSSoundSettingsViewController.h */,
|
||||
34074F59203D093A004596AE /* OWSSoundSettingsViewController.m */,
|
||||
34B3F8641E8DF1700035BE1A /* PrivacySettingsTableViewController.h */,
|
||||
34B3F8651E8DF1700035BE1A /* PrivacySettingsTableViewController.m */,
|
||||
34CE88E51F2FB9A10098030F /* ProfileViewController.h */,
|
||||
34CE88E61F2FB9A10098030F /* ProfileViewController.m */,
|
||||
34B3F8661E8DF1700035BE1A /* RegistrationViewController.h */,
|
||||
34B3F8671E8DF1700035BE1A /* RegistrationViewController.m */,
|
||||
340FC875204DAC8C007AEB0F /* Registration */,
|
||||
4585C4671ED8F8D200896AEA /* SafetyNumberConfirmationAlert.swift */,
|
||||
34B3F86A1E8DF1700035BE1A /* ShowGroupMembersViewController.h */,
|
||||
34B3F86B1E8DF1700035BE1A /* ShowGroupMembersViewController.m */,
|
||||
34B3F86D1E8DF1700035BE1A /* SignalsNavigationController.h */,
|
||||
34B3F86E1E8DF1700035BE1A /* SignalsNavigationController.m */,
|
||||
340CB2251EAC25820001CAA1 /* UpdateGroupViewController.h */,
|
||||
340CB2261EAC25820001CAA1 /* UpdateGroupViewController.m */,
|
||||
340FC897204DAC8D007AEB0F /* ThreadSettings */,
|
||||
34D1F0BE1F8EC1760066283D /* Utils */,
|
||||
45D2AC01204885170033C692 /* OWS2FAReminderViewController.swift */,
|
||||
);
|
||||
|
@ -1605,11 +1635,14 @@
|
|||
34D8C0221ED3673300188D7C /* DebugUI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
340FC8C3204DE223007AEB0F /* DebugUIBackup.h */,
|
||||
340FC8C4204DE223007AEB0F /* DebugUIBackup.m */,
|
||||
45638BDB1F3DD0D400128435 /* DebugUICalling.swift */,
|
||||
34D8C0291ED3685800188D7C /* DebugUIContacts.h */,
|
||||
34D8C02A1ED3685800188D7C /* DebugUIContacts.m */,
|
||||
34E3EF0B1EFC235B007F6822 /* DebugUIDiskUsage.h */,
|
||||
34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */,
|
||||
45B27B852037FFB400A539DF /* DebugUIFileBrowser.swift */,
|
||||
34D8C0231ED3673300188D7C /* DebugUIMessages.h */,
|
||||
34D8C0241ED3673300188D7C /* DebugUIMessages.m */,
|
||||
341F2C0D1F2B8AE700D07D6B /* DebugUIMisc.h */,
|
||||
|
@ -1626,7 +1659,6 @@
|
|||
343A65941FC47D5E000477A1 /* DebugUISyncMessages.m */,
|
||||
34D8C0251ED3673300188D7C /* DebugUITableViewController.h */,
|
||||
34D8C0261ED3673300188D7C /* DebugUITableViewController.m */,
|
||||
45B27B852037FFB400A539DF /* DebugUIFileBrowser.swift */,
|
||||
);
|
||||
path = DebugUI;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1646,9 +1678,9 @@
|
|||
450DF2071E0DD29E003D14BE /* Notifications */,
|
||||
34FD936E1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.h */,
|
||||
34FD936F1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m */,
|
||||
4523149D1F7E916B003A428C /* SlideOffAnimatedTransition.swift */,
|
||||
34B3F8331E8DF1700035BE1A /* ViewControllers */,
|
||||
76EB052B18170B33006006FC /* Views */,
|
||||
4523149D1F7E916B003A428C /* SlideOffAnimatedTransition.swift */,
|
||||
);
|
||||
name = UserInterface;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1901,6 +1933,9 @@
|
|||
34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */,
|
||||
34A9105E1FFEB113000C4745 /* OWSBackup.h */,
|
||||
34A9105F1FFEB114000C4745 /* OWSBackup.m */,
|
||||
340FC8C6204DE64D007AEB0F /* OWSBackupAPI.swift */,
|
||||
340FC8BE204DB7D1007AEB0F /* OWSBackupExport.h */,
|
||||
340FC8BF204DB7D2007AEB0F /* OWSBackupExport.m */,
|
||||
4579431C1E7C8CE9008ED0C0 /* Pastelog.h */,
|
||||
4579431D1E7C8CE9008ED0C0 /* Pastelog.m */,
|
||||
450DF2041E0D74AC003D14BE /* Platform.swift */,
|
||||
|
@ -2100,6 +2135,7 @@
|
|||
D221A08C169C9E5E00537ABF /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
340FC8C1204DDF66007AEB0F /* CloudKit.framework */,
|
||||
455A16DB1F1FEA0000F86704 /* Metal.framework */,
|
||||
455A16DC1F1FEA0000F86704 /* MetalKit.framework */,
|
||||
45847E861E4283C30080EAB3 /* Intents.framework */,
|
||||
|
@ -3029,7 +3065,6 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
34B3F8761E8DF1700035BE1A /* CodeVerificationViewController.m in Sources */,
|
||||
3461293E1FD1D72B00532771 /* ExperienceUpgradeFinder.swift in Sources */,
|
||||
34D1F0BD1F8D108C0066283D /* AttachmentUploadView.m in Sources */,
|
||||
34D1F0BA1F8800D90066283D /* OWSAudioMessageView.m in Sources */,
|
||||
|
@ -3037,15 +3072,18 @@
|
|||
45C9DEB81DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift in Sources */,
|
||||
34D1F0501F7D45A60066283D /* GifPickerCell.swift in Sources */,
|
||||
34D99C931F2937CC00D284D6 /* OWSAnalytics.swift in Sources */,
|
||||
34B3F88E1E8DF1700035BE1A /* PrivacySettingsTableViewController.m in Sources */,
|
||||
340FC8B8204DAC8D007AEB0F /* AddToGroupViewController.m in Sources */,
|
||||
341F2C0F1F2B8AE700D07D6B /* DebugUIMisc.m in Sources */,
|
||||
340FC8AF204DAC8D007AEB0F /* OWSLinkDeviceViewController.m in Sources */,
|
||||
34E3EF0D1EFC235B007F6822 /* DebugUIDiskUsage.m in Sources */,
|
||||
340FC8B4204DAC8D007AEB0F /* OWSBackupSettingsViewController.m in Sources */,
|
||||
34D1F0871F8678AA0066283D /* ConversationViewItem.m in Sources */,
|
||||
B6DA6B071B8A2F9A00CA6F98 /* AppStoreRating.m in Sources */,
|
||||
451A13B11E13DED2000A50FD /* CallNotificationsAdapter.swift in Sources */,
|
||||
450DF2091E0DD2C6003D14BE /* UserNotificationsAdaptee.swift in Sources */,
|
||||
34D1F0821F8678AA0066283D /* ConversationHeaderView.m in Sources */,
|
||||
34D1F0AB1F867BFC0066283D /* OWSContactOffersCell.m in Sources */,
|
||||
340FC8C7204DE64D007AEB0F /* OWSBackupAPI.swift in Sources */,
|
||||
343A65981FC4CFE7000477A1 /* ConversationScrollButton.m in Sources */,
|
||||
34D1F0A91F867BFC0066283D /* ConversationViewCell.m in Sources */,
|
||||
4505C2BF1E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */,
|
||||
|
@ -3053,17 +3091,18 @@
|
|||
EF764C351DB67CC5000D9A87 /* UIViewController+Permissions.m in Sources */,
|
||||
45CD81EF1DC030E7004C9430 /* SyncPushTokensJob.swift in Sources */,
|
||||
45794E861E00620000066731 /* CallUIAdapter.swift in Sources */,
|
||||
340FC8BA204DAC8D007AEB0F /* FingerprintViewScanController.m in Sources */,
|
||||
4585C4681ED8F8D200896AEA /* SafetyNumberConfirmationAlert.swift in Sources */,
|
||||
450D19131F85236600970622 /* RemoteVideoView.m in Sources */,
|
||||
B6B9ECFC198B31BA00C620D3 /* PushManager.m in Sources */,
|
||||
45DF5DF21DDB843F00C936C7 /* CompareSafetyNumbersActivity.swift in Sources */,
|
||||
458DE9D91DEE7B360071BB03 /* OWSWebRTCDataProtos.pb.m in Sources */,
|
||||
76EB063C18170B33006006FC /* NumberUtil.m in Sources */,
|
||||
34B3F88F1E8DF1710035BE1A /* RegistrationViewController.m in Sources */,
|
||||
451166C01FD86B98000739BA /* AccountManager.swift in Sources */,
|
||||
3430FE181F7751D4000EC51B /* GiphyAPI.swift in Sources */,
|
||||
34A55F3720485465002CC6DE /* OWS2FARegistrationViewController.m in Sources */,
|
||||
34B3F8901E8DF1710035BE1A /* AppSettingsViewController.m in Sources */,
|
||||
340FC8AD204DAC8D007AEB0F /* OWSLinkedDevicesTableViewController.m in Sources */,
|
||||
340FC8AA204DAC8D007AEB0F /* NotificationSettingsViewController.m in Sources */,
|
||||
34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */,
|
||||
34B3F8931E8DF1710035BE1A /* SignalsNavigationController.m in Sources */,
|
||||
34D1F0AC1F867BFC0066283D /* OWSExpirationTimerView.m in Sources */,
|
||||
|
@ -3076,29 +3115,26 @@
|
|||
34D1F0AE1F867BFC0066283D /* OWSMessageCell.m in Sources */,
|
||||
451686AB1F520CDA00AC3D4B /* MultiDeviceProfileKeyUpdateJob.swift in Sources */,
|
||||
45D231771DC7E8F10034FA89 /* SessionResetJob.swift in Sources */,
|
||||
340FC8A9204DAC8D007AEB0F /* NotificationSettingsOptionsViewController.m in Sources */,
|
||||
452037D11EE84975004E4CDF /* DebugUISessionState.m in Sources */,
|
||||
D221A09A169C9E5E00537ABF /* main.m in Sources */,
|
||||
34B3F87B1E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift in Sources */,
|
||||
452EA09E1EA7ABE00078744B /* AttachmentPointerView.swift in Sources */,
|
||||
34B3F87C1E8DF1700035BE1A /* FingerprintViewController.m 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 */,
|
||||
346129991FD1E4DA00532771 /* SignalApp.m in Sources */,
|
||||
34BECE301F7ABCF800D7438D /* GifPickerLayout.swift in Sources */,
|
||||
3472229F1EB22FFE00E53955 /* AddToGroupViewController.m in Sources */,
|
||||
343A65951FC47D5E000477A1 /* DebugUISyncMessages.m in Sources */,
|
||||
45C0DC1E1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */,
|
||||
34B3F8861E8DF1700035BE1A /* NotificationSettingsOptionsViewController.m in Sources */,
|
||||
452ECA4D1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */,
|
||||
4556FA681F54AA9500AF40DD /* DebugUIProfile.swift in Sources */,
|
||||
34DFCB851E8E04B500053165 /* AddToBlockListViewController.m in Sources */,
|
||||
45A6DAD61EBBF85500893231 /* ReminderView.swift in Sources */,
|
||||
34B3F88A1E8DF1700035BE1A /* OWSLinkDeviceViewController.m in Sources */,
|
||||
34D1F0881F8678AA0066283D /* ConversationViewLayout.m in Sources */,
|
||||
3497DBEF1ECE2E4700DB2605 /* DomainFrontingCountryViewController.m in Sources */,
|
||||
452314A01F7E9E18003A428C /* DirectionalPanGestureRecognizer.swift in Sources */,
|
||||
34330AA31E79686200DF2FB9 /* OWSProgressView.m in Sources */,
|
||||
34CA1C271F7156F300E51C51 /* MessageDetailViewController.swift in Sources */,
|
||||
|
@ -3107,10 +3143,9 @@
|
|||
34D1F0B71F87F8850066283D /* OWSGenericAttachmentView.m in Sources */,
|
||||
34B3F8801E8DF1700035BE1A /* InviteFlow.swift in Sources */,
|
||||
457C87B82032645C008D52D6 /* DebugUINotifications.swift in Sources */,
|
||||
34B3F8871E8DF1700035BE1A /* NotificationSettingsViewController.m in Sources */,
|
||||
347E0B7B2003CD7500BC2F76 /* OWSBackupImportViewController.m in Sources */,
|
||||
458E38371D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m in Sources */,
|
||||
4517642B1DE939FD00EDB8B9 /* ContactCell.swift in Sources */,
|
||||
340FC8AB204DAC8D007AEB0F /* DomainFrontingCountryViewController.m in Sources */,
|
||||
34B3F8751E8DF1700035BE1A /* CallViewController.swift in Sources */,
|
||||
34D8C0281ED3673300188D7C /* DebugUITableViewController.m in Sources */,
|
||||
3497DBEC1ECE257500DB2605 /* OWSCountryMetadata.m in Sources */,
|
||||
|
@ -3119,50 +3154,52 @@
|
|||
34D1F0B41F86D31D0066283D /* ConversationCollectionView.m in Sources */,
|
||||
34B3F8821E8DF1700035BE1A /* NewContactThreadViewController.m in Sources */,
|
||||
45D308AD2049A439000189E4 /* PinEntryView.m in Sources */,
|
||||
340FC8B1204DAC8D007AEB0F /* BlockListViewController.m in Sources */,
|
||||
45F659821E1BE77000444429 /* NonCallKitCallUIAdaptee.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 */,
|
||||
34B3F8911E8DF1710035BE1A /* ShowGroupMembersViewController.m in Sources */,
|
||||
4539B5861F79348F007141FF /* PushRegistrationManager.swift in Sources */,
|
||||
45FBC5D11DF8592E00E9B410 /* SignalCall.swift in Sources */,
|
||||
340FC8BB204DAC8D007AEB0F /* OWSAddToContactViewController.m in Sources */,
|
||||
4523149E1F7E916B003A428C /* SlideOffAnimatedTransition.swift in Sources */,
|
||||
340FC8C0204DB7D2007AEB0F /* OWSBackupExport.m in Sources */,
|
||||
340FC8A7204DAC8D007AEB0F /* RegistrationViewController.m in Sources */,
|
||||
452C468F1E427E200087B011 /* OutboundCallInitiator.swift in Sources */,
|
||||
45F170BB1E2FC5D3003FC1F2 /* CallAudioService.swift in Sources */,
|
||||
345BC30C2047030700257B7C /* OWS2FASettingsViewController.m in Sources */,
|
||||
34B3F8711E8DF1700035BE1A /* AboutTableViewController.m in Sources */,
|
||||
34B3F88D1E8DF1700035BE1A /* OWSQRCodeScanningViewController.m in Sources */,
|
||||
340FC8B7204DAC8D007AEB0F /* OWSConversationSettingsViewController.m in Sources */,
|
||||
34BECE2E1F7ABCE000D7438D /* GifPickerViewController.swift in Sources */,
|
||||
34CCAF3B1F0C2748004084F4 /* OWSAddToContactViewController.m in Sources */,
|
||||
34D1F0C01F8EC1760066283D /* MessageRecipientStatusUtils.swift in Sources */,
|
||||
45F659731E1BD99C00444429 /* CallKitCallUIAdaptee.swift in Sources */,
|
||||
45BB93381E688E14001E3939 /* UIDevice+featureSupport.swift in Sources */,
|
||||
45B9EE9C200E91FB005D2F2D /* MediaDetailViewController.m in Sources */,
|
||||
458DE9D61DEE3FD00071BB03 /* PeerConnectionClient.swift in Sources */,
|
||||
34D1F0841F8678AA0066283D /* ConversationInputToolbar.m in Sources */,
|
||||
340CB2271EAC25820001CAA1 /* UpdateGroupViewController.m in Sources */,
|
||||
FCC81A981A44558300DFEC7D /* UIDevice+TSHardwareVersion.m in Sources */,
|
||||
76EB054018170B33006006FC /* AppDelegate.m in Sources */,
|
||||
34D1F0831F8678AA0066283D /* ConversationInputTextView.m in Sources */,
|
||||
347E0B7A2003CD7500BC2F76 /* OWSBackupExportViewController.m in Sources */,
|
||||
340FC8B6204DAC8D007AEB0F /* OWSQRCodeScanningViewController.m in Sources */,
|
||||
34D1F0B11F867BFC0066283D /* OWSUnreadIndicatorCell.m in Sources */,
|
||||
34B3F89C1E8DF3270035BE1A /* BlockListViewController.m in Sources */,
|
||||
340FC8B5204DAC8D007AEB0F /* AboutTableViewController.m in Sources */,
|
||||
34BECE2B1F74C12700D7438D /* DebugUIStress.m in Sources */,
|
||||
34074F5B203D093B004596AE /* OWSSoundSettingsViewController.m in Sources */,
|
||||
34C42D5B1F45F7A80072EC04 /* OWSNavigationController.m in Sources */,
|
||||
340FC8B9204DAC8D007AEB0F /* UpdateGroupViewController.m in Sources */,
|
||||
B609597C1C2C0FC6004E8797 /* iRate.m in Sources */,
|
||||
4574A5D61DD6704700C6B692 /* CallService.swift in Sources */,
|
||||
34B3F8721E8DF1700035BE1A /* AdvancedSettingsTableViewController.m in Sources */,
|
||||
340FC8A8204DAC8D007AEB0F /* CodeVerificationViewController.m in Sources */,
|
||||
3461299C1FD1EA9E00532771 /* NotificationsManager.m in Sources */,
|
||||
4521C3C01F59F3BA00B4C582 /* TextFieldHelper.swift in Sources */,
|
||||
34B3F8891E8DF1700035BE1A /* OWSConversationSettingsViewController.m in Sources */,
|
||||
34B3F87E1E8DF1700035BE1A /* InboxTableViewCell.m in Sources */,
|
||||
34B3F88B1E8DF1700035BE1A /* OWSLinkedDevicesTableViewController.m in Sources */,
|
||||
340FC8AC204DAC8D007AEB0F /* PrivacySettingsTableViewController.m in Sources */,
|
||||
340FC8C5204DE223007AEB0F /* DebugUIBackup.m in Sources */,
|
||||
340FC8AE204DAC8D007AEB0F /* OWSSoundSettingsViewController.m in Sources */,
|
||||
4579431E1E7C8CE9008ED0C0 /* Pastelog.m in Sources */,
|
||||
34B3F8941E8DF1710035BE1A /* HomeViewController.m in Sources */,
|
||||
34E8BF381EE9E2FD00F5F4CA /* FingerprintViewScanController.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 */,
|
||||
|
@ -3170,6 +3207,7 @@
|
|||
45A663C51F92EC760027B59E /* GroupTableViewCell.swift in Sources */,
|
||||
34D1F0861F8678AA0066283D /* ConversationViewController.m in Sources */,
|
||||
B90418E6183E9DD40038554A /* DateUtil.m in Sources */,
|
||||
340FC8BD204DAC8D007AEB0F /* ShowGroupMembersViewController.m in Sources */,
|
||||
459311FC1D75C948008DD4F0 /* OWSDeviceTableViewCell.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
|
@ -12,12 +12,10 @@
|
|||
</array>
|
||||
<key>com.apple.developer.icloud-services</key>
|
||||
<array>
|
||||
<string>CloudDocuments</string>
|
||||
</array>
|
||||
<key>com.apple.developer.ubiquity-container-identifiers</key>
|
||||
<array>
|
||||
<string>iCloud.$(CFBundleIdentifier)</string>
|
||||
<string>CloudKit</string>
|
||||
</array>
|
||||
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
|
||||
<string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.org.whispersystems.signal.group</string>
|
||||
|
|
|
@ -149,10 +149,6 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
|
||||
[self startupLogging];
|
||||
|
||||
// If a backup restore is in progress, try to complete it.
|
||||
// Otherwise, cleanup backup state.
|
||||
[OWSBackup applicationDidFinishLaunching];
|
||||
|
||||
// Prevent the device from sleeping during database view async registration
|
||||
// (e.g. long database upgrades).
|
||||
//
|
||||
|
@ -1170,6 +1166,8 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
[OWSPreferences setIsReadyForAppExtensions];
|
||||
|
||||
[self ensureRootViewController];
|
||||
|
||||
[OWSBackup.sharedManager setup];
|
||||
}
|
||||
|
||||
- (void)registrationStateDidChange
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSTableViewController.h"
|
|
@ -13,7 +13,8 @@
|
|||
|
||||
@implementation AboutTableViewController
|
||||
|
||||
- (void)dealloc {
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
|
@ -88,8 +89,10 @@
|
|||
OWSPreferences *preferences = [Environment preferences];
|
||||
NSString *_Nullable pushToken = [preferences getPushToken];
|
||||
NSString *_Nullable voipToken = [preferences getVoipToken];
|
||||
[debugSection addItem:[OWSTableItem labelItemWithText:[NSString stringWithFormat:@"Push Token: %@", pushToken ?: @"None" ]]];
|
||||
[debugSection addItem:[OWSTableItem labelItemWithText:[NSString stringWithFormat:@"VOIP Token: %@", voipToken ?: @"None" ]]];
|
||||
[debugSection
|
||||
addItem:[OWSTableItem labelItemWithText:[NSString stringWithFormat:@"Push Token: %@", pushToken ?: @"None"]]];
|
||||
[debugSection
|
||||
addItem:[OWSTableItem labelItemWithText:[NSString stringWithFormat:@"VOIP Token: %@", voipToken ?: @"None"]]];
|
||||
|
||||
// Strip prefix from category, otherwise it's too long to fit into cell on a small device.
|
||||
NSString *audioCategory =
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SelectRecipientViewController.h"
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AddToBlockListViewController.h"
|
||||
|
@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
self.delegate = self;
|
||||
|
||||
[super loadView];
|
||||
|
||||
|
||||
self.title = NSLocalizedString(@"SETTINGS_ADD_TO_BLOCK_LIST_TITLE", @"Title for the 'add to block list' view.");
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSTableViewController.h"
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AdvancedSettingsTableViewController.h"
|
||||
|
@ -254,7 +254,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
});
|
||||
}
|
||||
|
||||
- (void)didToggleEnableLogSwitch:(UISwitch *)sender {
|
||||
- (void)didToggleEnableLogSwitch:(UISwitch *)sender
|
||||
{
|
||||
if (!sender.isOn) {
|
||||
[[DebugLogger sharedLogger] wipeLogs];
|
||||
[[DebugLogger sharedLogger] disableFileLogging];
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSTableViewController.h"
|
|
@ -7,6 +7,7 @@
|
|||
#import "AdvancedSettingsTableViewController.h"
|
||||
#import "DebugUITableViewController.h"
|
||||
#import "NotificationSettingsViewController.h"
|
||||
#import "OWSBackupSettingsViewController.h"
|
||||
#import "OWSLinkedDevicesTableViewController.h"
|
||||
#import "OWSNavigationController.h"
|
||||
#import "PrivacySettingsTableViewController.h"
|
||||
|
@ -187,6 +188,13 @@
|
|||
actionBlock:^{
|
||||
[weakSelf showAdvanced];
|
||||
}]];
|
||||
#ifdef DEBUG
|
||||
[section addItem:[OWSTableItem disclosureItemWithText:NSLocalizedString(@"SETTINGS_BACKUP",
|
||||
@"Label for the backup view in app settings.")
|
||||
actionBlock:^{
|
||||
[weakSelf showBackup];
|
||||
}]];
|
||||
#endif
|
||||
[section addItem:[OWSTableItem disclosureItemWithText:NSLocalizedString(@"SETTINGS_ABOUT", @"")
|
||||
actionBlock:^{
|
||||
[weakSelf showAbout];
|
||||
|
@ -304,7 +312,8 @@
|
|||
[disclosureButton autoVCenterInSuperview];
|
||||
[disclosureButton autoPinTrailingToSuperview];
|
||||
[disclosureButton autoPinLeadingToTrailingOfView:nameView margin:16.f];
|
||||
[disclosureButton setContentCompressionResistancePriority:(UILayoutPriorityDefaultHigh + 1) forAxis:UILayoutConstraintAxisHorizontal];
|
||||
[disclosureButton setContentCompressionResistancePriority:(UILayoutPriorityDefaultHigh + 1)
|
||||
forAxis:UILayoutConstraintAxisHorizontal];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
@ -352,6 +361,12 @@
|
|||
[self.navigationController pushViewController:vc animated:YES];
|
||||
}
|
||||
|
||||
- (void)showBackup
|
||||
{
|
||||
OWSBackupSettingsViewController *vc = [OWSBackupSettingsViewController new];
|
||||
[self.navigationController pushViewController:vc animated:YES];
|
||||
}
|
||||
|
||||
- (void)showDebugUI
|
||||
{
|
||||
[DebugUITableViewController presentDebugUIFromViewController:self];
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "BlockListViewController.h"
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DomainFrontingCountryViewController.h"
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSTableViewController.h"
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
@implementation NotificationSettingsOptionsViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[self updateTableContents];
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSTableViewController.h"
|
|
@ -11,7 +11,8 @@
|
|||
|
||||
@implementation NotificationSettingsViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
[self setTitle:NSLocalizedString(@"SETTINGS_NOTIFICATIONS", nil)];
|
||||
|
@ -19,7 +20,8 @@
|
|||
[self updateTableContents];
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated {
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
[self updateTableContents];
|
||||
}
|
||||
|
||||
|
@ -32,9 +34,9 @@
|
|||
__weak NotificationSettingsViewController *weakSelf = self;
|
||||
|
||||
OWSPreferences *prefs = [Environment preferences];
|
||||
|
||||
|
||||
// Sounds section.
|
||||
|
||||
|
||||
OWSTableSection *soundsSection = [OWSTableSection new];
|
||||
soundsSection.headerTitle
|
||||
= NSLocalizedString(@"SETTINGS_SECTION_SOUNDS", @"Header Label for the sounds section of settings views.");
|
||||
|
@ -56,7 +58,7 @@
|
|||
target:weakSelf
|
||||
selector:@selector(didToggleSoundNotificationsSwitch:)]];
|
||||
[contents addSection:soundsSection];
|
||||
|
||||
|
||||
OWSTableSection *backgroundSection = [OWSTableSection new];
|
||||
backgroundSection.headerTitle = NSLocalizedString(@"SETTINGS_NOTIFICATION_CONTENT_TITLE", @"table section header");
|
||||
[backgroundSection
|
||||
|
@ -77,7 +79,8 @@
|
|||
|
||||
#pragma mark - Events
|
||||
|
||||
- (void)didToggleSoundNotificationsSwitch:(UISwitch *)sender {
|
||||
- (void)didToggleSoundNotificationsSwitch:(UISwitch *)sender
|
||||
{
|
||||
[Environment.preferences setSoundInForeground:sender.on];
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <SignalMessaging/OWSTableViewController.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSBackupSettingsViewController : OWSTableViewController
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -0,0 +1,90 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSBackupSettingsViewController.h"
|
||||
#import "OWSBackup.h"
|
||||
#import "OWSProgressView.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import "ThreadUtil.h"
|
||||
#import <SignalMessaging/AttachmentSharing.h>
|
||||
#import <SignalMessaging/Environment.h>
|
||||
#import <SignalMessaging/SignalMessaging-Swift.h>
|
||||
#import <SignalMessaging/UIColor+OWS.h>
|
||||
#import <SignalMessaging/UIFont+OWS.h>
|
||||
#import <SignalMessaging/UIView+OWS.h>
|
||||
#import <SignalServiceKit/MIMETypeUtil.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSBackupSettingsViewController ()
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation OWSBackupSettingsViewController
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
self.title = NSLocalizedString(@"SETTINGS_BACKUP", @"Label for the backup view in app settings.");
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(backupStateDidChange:)
|
||||
name:NSNotificationNameBackupStateDidChange
|
||||
object:nil];
|
||||
|
||||
[self updateTableContents];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
[self updateTableContents];
|
||||
}
|
||||
|
||||
#pragma mark - Table Contents
|
||||
|
||||
- (void)updateTableContents
|
||||
{
|
||||
OWSTableContents *contents = [OWSTableContents new];
|
||||
|
||||
BOOL isBackupEnabled = [OWSBackup.sharedManager isBackupEnabled];
|
||||
|
||||
// TODO: This UI is temporary.
|
||||
// Enabling backup will involve entering and registering a PIN.
|
||||
OWSTableSection *enableSection = [OWSTableSection new];
|
||||
enableSection.headerTitle = NSLocalizedString(@"SETTINGS_BACKUP", @"Label for the backup view in app settings.");
|
||||
[enableSection
|
||||
addItem:[OWSTableItem switchItemWithText:
|
||||
NSLocalizedString(@"SETTINGS_BACKUP_ENABLING_SWITCH",
|
||||
@"Label for switch in settings that controls whether or not backup is enabled.")
|
||||
isOn:isBackupEnabled
|
||||
target:self
|
||||
selector:@selector(isBackupEnabledDidChange:)]];
|
||||
[contents addSection:enableSection];
|
||||
|
||||
self.contents = contents;
|
||||
}
|
||||
|
||||
- (void)isBackupEnabledDidChange:(UISwitch *)sender
|
||||
{
|
||||
[OWSBackup.sharedManager setIsBackupEnabled:sender.isOn];
|
||||
}
|
||||
|
||||
#pragma mark - Events
|
||||
|
||||
- (void)backupStateDidChange:(NSNotification *)notification
|
||||
{
|
||||
[self updateTableContents];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -85,13 +85,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
OWSDeviceProvisioningURLParser *parser = [[OWSDeviceProvisioningURLParser alloc] initWithProvisioningURL:string];
|
||||
if (!parser.isValid) {
|
||||
DDLogError(@"Unable to parse provisioning params from QRCode: %@", string);
|
||||
|
||||
NSString* title = NSLocalizedString(@"LINK_DEVICE_INVALID_CODE_TITLE", @"report an invalid linking code");
|
||||
NSString* body = NSLocalizedString(@"LINK_DEVICE_INVALID_CODE_BODY", @"report an invalid linking code");
|
||||
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
|
||||
message:body
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
NSString *title = NSLocalizedString(@"LINK_DEVICE_INVALID_CODE_TITLE", @"report an invalid linking code");
|
||||
NSString *body = NSLocalizedString(@"LINK_DEVICE_INVALID_CODE_BODY", @"report an invalid linking code");
|
||||
|
||||
UIAlertController *alertController =
|
||||
[UIAlertController alertControllerWithTitle:title message:body preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
UIAlertAction *cancelAction =
|
||||
[UIAlertAction actionWithTitle:CommonStrings.cancelButton
|
||||
|
@ -102,19 +101,19 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
});
|
||||
}];
|
||||
[alertController addAction:cancelAction];
|
||||
|
||||
|
||||
UIAlertAction *proceedAction =
|
||||
[UIAlertAction actionWithTitle:NSLocalizedString(@"LINK_DEVICE_RESTART", @"attempt another linking")
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {
|
||||
[self.qrScanningController startCapture];
|
||||
}];
|
||||
[UIAlertAction actionWithTitle:NSLocalizedString(@"LINK_DEVICE_RESTART", @"attempt another linking")
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {
|
||||
[self.qrScanningController startCapture];
|
||||
}];
|
||||
[alertController addAction:proceedAction];
|
||||
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
} else {
|
||||
NSString *title
|
||||
= NSLocalizedString(@"LINK_DEVICE_PERMISSION_ALERT_TITLE", @"confirm the users intent to link a new device");
|
||||
NSString *title = NSLocalizedString(
|
||||
@"LINK_DEVICE_PERMISSION_ALERT_TITLE", @"confirm the users intent to link a new device");
|
||||
NSString *linkingDescription
|
||||
= NSLocalizedString(@"LINK_DEVICE_PERMISSION_ALERT_BODY", @"confirm the users intent to link a new device");
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
|
@ -288,12 +288,11 @@ int const OWSLinkedDevicesTableViewControllerSectionAddDevice = 1;
|
|||
}
|
||||
}
|
||||
|
||||
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
|
||||
|
||||
if (indexPath.section == OWSLinkedDevicesTableViewControllerSectionAddDevice)
|
||||
{
|
||||
if (indexPath.section == OWSLinkedDevicesTableViewControllerSectionAddDevice) {
|
||||
[self ows_askForCameraPermissions:^(BOOL granted) {
|
||||
if (!granted) {
|
||||
return;
|
||||
|
@ -358,11 +357,12 @@ int const OWSLinkedDevicesTableViewControllerSectionAddDevice = 1;
|
|||
{
|
||||
if (editingStyle == UITableViewCellEditingStyleDelete) {
|
||||
OWSDevice *device = [self deviceForRowAtIndexPath:indexPath];
|
||||
[self touchedUnlinkControlForDevice:device
|
||||
success:^{
|
||||
DDLogInfo(@"Removing unlinked device with deviceId: %ld", (long)device.deviceId);
|
||||
[device remove];
|
||||
}];
|
||||
[self
|
||||
touchedUnlinkControlForDevice:device
|
||||
success:^{
|
||||
DDLogInfo(@"Removing unlinked device with deviceId: %ld", (long)device.deviceId);
|
||||
[device remove];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
|
@ -28,9 +28,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[super viewDidLoad];
|
||||
|
||||
[self setTitle:NSLocalizedString(@"SETTINGS_ITEM_NOTIFICATION_SOUND",
|
||||
@"Label for settings view that allows user to change the notification sound.")];
|
||||
@"Label for settings view that allows user to change the notification sound.")];
|
||||
self.currentSound
|
||||
= (self.thread ? [OWSSounds notificationSoundForThread:self.thread] : [OWSSounds globalNotificationSound]);
|
||||
= (self.thread ? [OWSSounds notificationSoundForThread:self.thread] : [OWSSounds globalNotificationSound]);
|
||||
|
||||
[self updateTableContents];
|
||||
[self updateNavigationItems];
|
||||
|
@ -69,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
OWSTableSection *soundsSection = [OWSTableSection new];
|
||||
soundsSection.headerTitle = NSLocalizedString(
|
||||
@"NOTIFICATIONS_SECTION_SOUNDS", @"Label for settings UI that allows user to change the notification sound.");
|
||||
|
||||
|
||||
NSArray<NSNumber *> *allSounds = [OWSSounds allNotificationSounds];
|
||||
for (NSNumber *nsValue in allSounds) {
|
||||
OWSSound sound = (OWSSound)nsValue.intValue;
|
|
@ -15,7 +15,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@implementation PrivacySettingsTableViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
self.title = NSLocalizedString(@"SETTINGS_PRIVACY_TITLE", @"");
|
||||
|
@ -231,7 +232,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[SignalApp.sharedApp.callService createCallUIAdapter];
|
||||
}
|
||||
|
||||
- (void)didToggleEnableCallKitSwitch:(UISwitch *)sender {
|
||||
- (void)didToggleEnableCallKitSwitch:(UISwitch *)sender
|
||||
{
|
||||
DDLogInfo(@"%@ user toggled call kit preference: %@", self.logTag, (sender.isOn ? @"ON" : @"OFF"));
|
||||
[[Environment current].preferences setIsCallKitEnabled:sender.isOn];
|
||||
|
||||
|
@ -242,7 +244,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[self updateTableContents];
|
||||
}
|
||||
|
||||
- (void)didToggleEnableCallKitPrivacySwitch:(UISwitch *)sender {
|
||||
- (void)didToggleEnableCallKitPrivacySwitch:(UISwitch *)sender
|
||||
{
|
||||
DDLogInfo(@"%@ user toggled call kit privacy preference: %@", self.logTag, (sender.isOn ? @"ON" : @"OFF"));
|
||||
[[Environment current].preferences setIsCallKitPrivacyEnabled:!sender.isOn];
|
||||
|
|
@ -8,8 +8,6 @@
|
|||
#import "ConversationViewItem.h"
|
||||
#import "NSAttributedString+OWS.h"
|
||||
#import "OWSAudioMessageView.h"
|
||||
#import "OWSBackup.h"
|
||||
#import "OWSBackupImportViewController.h"
|
||||
#import "OWSExpirationTimerView.h"
|
||||
#import "OWSGenericAttachmentView.h"
|
||||
#import "Signal-Swift.h"
|
||||
|
@ -1321,16 +1319,7 @@ const CGFloat OWSMessageCellCornerRadius = 17;
|
|||
imageView:self.stillImageView];
|
||||
return;
|
||||
case OWSMessageCellType_GenericAttachment:
|
||||
#ifdef DEBUG
|
||||
if ([self.attachmentStream.filePath.lastPathComponent hasSuffix:OWSBackup_FileExtension]) {
|
||||
[self showBackupImportConfirmAlert:self.attachmentStream.filePath];
|
||||
} else {
|
||||
[AttachmentSharing showShareUIForAttachment:self.attachmentStream];
|
||||
}
|
||||
#else
|
||||
[AttachmentSharing showShareUIForAttachment:self.attachmentStream];
|
||||
#endif
|
||||
|
||||
break;
|
||||
case OWSMessageCellType_DownloadingAttachment: {
|
||||
OWSAssert(self.attachmentPointer);
|
||||
|
@ -1342,42 +1331,6 @@ const CGFloat OWSMessageCellCornerRadius = 17;
|
|||
}
|
||||
}
|
||||
|
||||
- (void)showBackupImportConfirmAlert:(NSString *)backupZipPath
|
||||
{
|
||||
OWSAssert(backupZipPath.length > 0);
|
||||
|
||||
UIAlertController *controller =
|
||||
[UIAlertController alertControllerWithTitle:NSLocalizedString(@"BACKUP_IMPORT_CONFIRM_ALERT_TITLE",
|
||||
@"Title for alert confirming backup import.")
|
||||
message:NSLocalizedString(@"BACKUP_IMPORT_CONFIRM_ALERT_MESSAGE",
|
||||
@"Message for alert confirming backup import.")
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[controller addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"BACKUP_IMPORT_CONFIRM_ALERT_BUTTON",
|
||||
@"Label for button confirming backup import.")
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *_Nonnull action) {
|
||||
[self showBackupImportUI:backupZipPath];
|
||||
}]];
|
||||
[controller addAction:OWSAlerts.cancelAction];
|
||||
|
||||
UIViewController *fromViewController = [[UIApplication sharedApplication] frontmostViewController];
|
||||
[fromViewController presentViewController:controller animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)showBackupImportUI:(NSString *)backupZipPath
|
||||
{
|
||||
OWSAssert(backupZipPath.length > 0);
|
||||
|
||||
OWSBackupImportViewController *backupViewController = [OWSBackupImportViewController new];
|
||||
// There currently isn't any support for restoring password-protected backups.
|
||||
[backupViewController importBackup:backupZipPath password:nil];
|
||||
UINavigationController *navigationController =
|
||||
[[UINavigationController alloc] initWithRootViewController:backupViewController];
|
||||
UIViewController *fromViewController = [[UIApplication sharedApplication] frontmostViewController];
|
||||
[fromViewController presentViewController:navigationController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)handleTextLongPressGesture:(UILongPressGestureRecognizer *)sender
|
||||
{
|
||||
OWSAssert(self.delegate);
|
||||
|
|
13
Signal/src/ViewControllers/DebugUI/DebugUIBackup.h
Normal file
13
Signal/src/ViewControllers/DebugUI/DebugUIBackup.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DebugUIPage.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DebugUIBackup : DebugUIPage
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
60
Signal/src/ViewControllers/DebugUI/DebugUIBackup.m
Normal file
60
Signal/src/ViewControllers/DebugUI/DebugUIBackup.m
Normal file
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DebugUIBackup.h"
|
||||
#import "OWSBackup.h"
|
||||
#import "OWSTableViewController.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import <Curve25519Kit/Randomness.h>
|
||||
|
||||
@import CloudKit;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation DebugUIBackup
|
||||
|
||||
#pragma mark - Factory Methods
|
||||
|
||||
- (NSString *)name
|
||||
{
|
||||
return @"Backup";
|
||||
}
|
||||
|
||||
- (nullable OWSTableSection *)sectionForThread:(nullable TSThread *)thread
|
||||
{
|
||||
NSMutableArray<OWSTableItem *> *items = [NSMutableArray new];
|
||||
[items addObject:[OWSTableItem itemWithTitle:@"Backup test file @ CloudKit"
|
||||
actionBlock:^{
|
||||
[DebugUIBackup backupTestFile];
|
||||
}]];
|
||||
|
||||
return [OWSTableSection sectionWithTitle:self.name items:items];
|
||||
}
|
||||
|
||||
+ (void)backupTestFile
|
||||
{
|
||||
DDLogInfo(@"%@ backupTestFile.", self.logTag);
|
||||
|
||||
NSData *_Nullable data = [Randomness generateRandomBytes:32];
|
||||
OWSAssert(data);
|
||||
NSString *filePath = [OWSFileSystem temporaryFilePathWithFileExtension:@"pdf"];
|
||||
BOOL success = [data writeToFile:filePath atomically:YES];
|
||||
OWSAssert(success);
|
||||
|
||||
[OWSBackupAPI checkCloudKitAccessWithCompletion:^(BOOL hasAccess) {
|
||||
if (hasAccess) {
|
||||
[OWSBackupAPI saveTestFileToCloudWithFileUrl:[NSURL fileURLWithPath:filePath]
|
||||
success:^(NSString *recordName) {
|
||||
// Do nothing, the API method will log for us.
|
||||
}
|
||||
failure:^(NSError *error){
|
||||
// Do nothing, the API method will log for us.
|
||||
}];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -693,12 +693,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
{
|
||||
OWSAssert(size % 4 == 0);
|
||||
|
||||
NSMutableData *data = [NSMutableData dataWithCapacity:size];
|
||||
for (size_t i = 0; i < size / 4; ++i) {
|
||||
u_int32_t randomBits = arc4random();
|
||||
[data appendBytes:(void *)&randomBits length:4];
|
||||
}
|
||||
return data;
|
||||
return [Randomness generateRandomBytes:size];
|
||||
}
|
||||
|
||||
+ (void)sendRandomAttachment:(TSThread *)thread uti:(NSString *)uti
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DebugUIPage.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class TSThread;
|
||||
|
||||
@interface DebugUIMisc : DebugUIPage
|
||||
|
||||
@end
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#import "DebugUIMisc.h"
|
||||
#import "OWSBackup.h"
|
||||
#import "OWSBackupExportViewController.h"
|
||||
#import "OWSCountryMetadata.h"
|
||||
#import "OWSTableViewController.h"
|
||||
#import "RegistrationViewController.h"
|
||||
|
@ -96,15 +95,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[DebugUIMisc sendUnencryptedDatabase:thread];
|
||||
}]];
|
||||
}
|
||||
[items addObject:[OWSTableItem subPageItemWithText:@"Export Backup w/o Password"
|
||||
actionBlock:^(UIViewController *viewController) {
|
||||
OWSBackupExportViewController *backupViewController =
|
||||
[OWSBackupExportViewController new];
|
||||
[backupViewController exportBackup:thread skipPassword:YES];
|
||||
[viewController.navigationController
|
||||
pushViewController:backupViewController
|
||||
animated:YES];
|
||||
}]];
|
||||
|
||||
[items addObject:[OWSTableItem itemWithTitle:@"Show 2FA Reminder"
|
||||
actionBlock:^() {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
//
|
||||
|
||||
#import "DebugUITableViewController.h"
|
||||
#import "DebugUIBackup.h"
|
||||
#import "DebugUIContacts.h"
|
||||
#import "DebugUIDiskUsage.h"
|
||||
#import "DebugUIMessages.h"
|
||||
|
@ -110,6 +111,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}];
|
||||
[subsectionItems addObject:documentsFileBrowserItem];
|
||||
[subsectionItems addObject:[self itemForSubsection:[DebugUIMisc new] viewController:viewController thread:thread]];
|
||||
[subsectionItems
|
||||
addObject:[self itemForSubsection:[DebugUIBackup new] viewController:viewController thread:thread]];
|
||||
|
||||
[contents addSection:[OWSTableSection sectionWithTitle:@"Sections" items:subsectionItems]];
|
||||
|
||||
|
@ -135,6 +138,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[subsectionItems
|
||||
addObject:[self itemForSubsection:[DebugUISyncMessages new] viewController:viewController thread:nil]];
|
||||
[subsectionItems addObject:[self itemForSubsection:[DebugUIMisc new] viewController:viewController thread:nil]];
|
||||
[subsectionItems addObject:[self itemForSubsection:[DebugUIBackup new] viewController:viewController thread:nil]];
|
||||
[contents addSection:[OWSTableSection sectionWithTitle:@"Sections" items:subsectionItems]];
|
||||
|
||||
viewController.contents = contents;
|
||||
|
|
|
@ -188,7 +188,7 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
|
|||
|
||||
bottomBanner.autoPinEdge(toSuperviewEdge: .top)
|
||||
bottomBanner.autoPinWidthToSuperview()
|
||||
self.autoPinView(toBottomGuideOrKeyboard:bottomBanner)
|
||||
self.autoPinView(toBottomGuideOrKeyboard: bottomBanner)
|
||||
|
||||
// The Giphy API requires us to "show their trademark prominently" in our GIF experience.
|
||||
let logoImage = UIImage(named: "giphy_logo")
|
||||
|
@ -454,9 +454,7 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
|
|||
progressiveSearchTimer = nil
|
||||
|
||||
guard let text = searchBar.text else {
|
||||
OWSAlerts.showAlert(title: NSLocalizedString("ALERT_ERROR_TITLE",
|
||||
comment: ""),
|
||||
message: NSLocalizedString("GIF_PICKER_VIEW_MISSING_QUERY",
|
||||
OWSAlerts.showErrorAlert(withMessage: NSLocalizedString("GIF_PICKER_VIEW_MISSING_QUERY",
|
||||
comment: "Alert message shown when user tries to search for GIFs without entering any search terms."))
|
||||
return
|
||||
}
|
||||
|
|
|
@ -728,8 +728,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
if ([MFMessageComposeViewController canSendText]) {
|
||||
[inviteFlow sendSMSToPhoneNumbers:@[ phoneNumber ]];
|
||||
} else {
|
||||
[OWSAlerts showAlertWithTitle:NSLocalizedString(@"ALERT_ERROR_TITLE", @"")
|
||||
message:NSLocalizedString(@"UNSUPPORTED_FEATURE_ERROR", @"")];
|
||||
[OWSAlerts showErrorAlertWithMessage:NSLocalizedString(@"UNSUPPORTED_FEATURE_ERROR", @"")];
|
||||
}
|
||||
}];
|
||||
|
||||
|
|
|
@ -322,10 +322,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
// Clear the PIN so that the user can try again.
|
||||
self.pinTextfield.text = nil;
|
||||
|
||||
[OWSAlerts
|
||||
showAlertWithTitle:NSLocalizedString(@"ALERT_ERROR_TITLE", @"")
|
||||
message:NSLocalizedString(@"ENABLE_2FA_VIEW_PIN_DOES_NOT_MATCH",
|
||||
@"Error indicating that the entered 'two-factor auth PINs' do not match.")];
|
||||
[OWSAlerts showErrorAlertWithMessage:
|
||||
NSLocalizedString(@"ENABLE_2FA_VIEW_PIN_DOES_NOT_MATCH",
|
||||
@"Error indicating that the entered 'two-factor auth PINs' do not match.")];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -370,11 +369,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[modalActivityIndicator dismissWithCompletion:^{
|
||||
[weakSelf updateTableContents];
|
||||
|
||||
[OWSAlerts
|
||||
showAlertWithTitle:NSLocalizedString(@"ALERT_ERROR_TITLE", @"")
|
||||
message:NSLocalizedString(@"ENABLE_2FA_VIEW_COULD_NOT_DISABLE_2FA",
|
||||
@"Error indicating that attempt to disable 'two-factor "
|
||||
@"auth' failed.")];
|
||||
[OWSAlerts showErrorAlertWithMessage:
|
||||
NSLocalizedString(@"ENABLE_2FA_VIEW_COULD_NOT_DISABLE_2FA",
|
||||
@"Error indicating that attempt to disable 'two-factor "
|
||||
@"auth' failed.")];
|
||||
}];
|
||||
}];
|
||||
}];
|
||||
|
@ -407,11 +405,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
[weakSelf updateTableContents];
|
||||
|
||||
[OWSAlerts
|
||||
showAlertWithTitle:NSLocalizedString(@"ENABLE_2FA_VIEW_COULD_NOT_ENABLE_2FA",
|
||||
@"Error indicating that attempt to enable 'two-factor "
|
||||
@"auth' failed.")
|
||||
message:error.localizedDescription];
|
||||
[OWSAlerts showErrorAlertWithMessage:
|
||||
NSLocalizedString(@"ENABLE_2FA_VIEW_COULD_NOT_ENABLE_2FA",
|
||||
@"Error indicating that attempt to enable 'two-factor "
|
||||
@"auth' failed.")];
|
||||
}];
|
||||
}];
|
||||
}];
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <SignalMessaging/OWSViewController.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class TSThread;
|
||||
|
||||
@interface OWSBackupExportViewController : OWSViewController
|
||||
|
||||
// If currentThread is non-nil, we should offer to let users send the
|
||||
// backup in that thread.
|
||||
- (void)exportBackup:(TSThread *_Nullable)currentThread skipPassword:(BOOL)skipPassword;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -1,312 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSBackupExportViewController.h"
|
||||
#import "OWSBackup.h"
|
||||
#import "OWSProgressView.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import "ThreadUtil.h"
|
||||
#import <SignalMessaging/AttachmentSharing.h>
|
||||
#import <SignalMessaging/Environment.h>
|
||||
#import <SignalMessaging/SignalMessaging-Swift.h>
|
||||
#import <SignalMessaging/UIColor+OWS.h>
|
||||
#import <SignalMessaging/UIFont+OWS.h>
|
||||
#import <SignalMessaging/UIView+OWS.h>
|
||||
#import <SignalServiceKit/MIMETypeUtil.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSBackupExportViewController () <OWSBackupDelegate>
|
||||
|
||||
@property (nonatomic) OWSBackup *backup;
|
||||
|
||||
@property (nonatomic, nullable) OWSProgressView *progressView;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation OWSBackupExportViewController
|
||||
|
||||
- (void)loadView
|
||||
{
|
||||
[super loadView];
|
||||
|
||||
self.view.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
self.navigationItem.title = NSLocalizedString(@"BACKUP_EXPORT_VIEW_TITLE", @"Title for the 'backup export' view.");
|
||||
self.navigationItem.leftBarButtonItem =
|
||||
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop
|
||||
target:self
|
||||
action:@selector(dismissWasPressed:)];
|
||||
|
||||
self.backup.delegate = self;
|
||||
|
||||
[self updateUI];
|
||||
}
|
||||
|
||||
- (void)exportBackup:(TSThread *_Nullable)currentThread skipPassword:(BOOL)skipPassword
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
// We set ourselves as the delegate of the backup later,
|
||||
// after we've loaded our view.
|
||||
self.backup = [OWSBackup new];
|
||||
[self.backup exportBackup:currentThread skipPassword:skipPassword];
|
||||
}
|
||||
|
||||
- (void)updateUI
|
||||
{
|
||||
for (UIView *subview in self.view.subviews) {
|
||||
[subview removeFromSuperview];
|
||||
}
|
||||
self.progressView = nil;
|
||||
|
||||
switch (self.backup.backupState) {
|
||||
case OWSBackupState_InProgress:
|
||||
[self showInProgressUI];
|
||||
break;
|
||||
case OWSBackupState_Cancelled:
|
||||
[self showCancelledUI];
|
||||
break;
|
||||
case OWSBackupState_Complete:
|
||||
[self showCompleteUI];
|
||||
break;
|
||||
case OWSBackupState_Failed:
|
||||
[self showFailedUI];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showInProgressUI
|
||||
{
|
||||
self.progressView = [OWSProgressView new];
|
||||
self.progressView.color = [UIColor ows_materialBlueColor];
|
||||
self.progressView.progress = self.backup.backupProgress;
|
||||
[self.progressView autoSetDimension:ALDimensionWidth toSize:300];
|
||||
[self.progressView autoSetDimension:ALDimensionHeight toSize:20];
|
||||
|
||||
UILabel *label = [UILabel new];
|
||||
label.text = NSLocalizedString(
|
||||
@"BACKUP_EXPORT_IN_PROGRESS_MESSAGE", @"Message indicating that backup export is in progress.");
|
||||
label.textColor = [UIColor blackColor];
|
||||
label.font = [UIFont ows_regularFontWithSize:18.f];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
label.numberOfLines = 0;
|
||||
label.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
|
||||
UIView *container = [UIView verticalStackWithSubviews:@[
|
||||
label,
|
||||
self.progressView,
|
||||
]
|
||||
spacing:10];
|
||||
[self.view addSubview:container];
|
||||
[container autoVCenterInSuperview];
|
||||
[container autoPinWidthToSuperviewWithMargin:25.f];
|
||||
}
|
||||
|
||||
- (void)showCancelledUI
|
||||
{
|
||||
// Show nothing.
|
||||
}
|
||||
|
||||
- (void)showCompleteUI
|
||||
{
|
||||
NSMutableArray<UIView *> *subviews = [NSMutableArray new];
|
||||
|
||||
{
|
||||
NSString *message = NSLocalizedString(
|
||||
@"BACKUP_EXPORT_COMPLETE_MESSAGE", @"Message indicating that backup export is complete.");
|
||||
|
||||
UILabel *label = [UILabel new];
|
||||
label.text = message;
|
||||
label.textColor = [UIColor blackColor];
|
||||
label.font = [UIFont ows_regularFontWithSize:18.f];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
label.numberOfLines = 0;
|
||||
label.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
[subviews addObject:label];
|
||||
}
|
||||
|
||||
if (self.backup.backupPassword) {
|
||||
NSString *message = [NSString stringWithFormat:NSLocalizedString(@"BACKUP_EXPORT_PASSWORD_MESSAGE_FORMAT",
|
||||
@"Format for message indicating that backup export "
|
||||
@"is complete. Embeds: {{the backup password}}."),
|
||||
self.backup.backupPassword];
|
||||
|
||||
UILabel *label = [UILabel new];
|
||||
label.text = message;
|
||||
label.textColor = [UIColor blackColor];
|
||||
label.font = [UIFont ows_regularFontWithSize:14.f];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
label.numberOfLines = 0;
|
||||
label.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
[subviews addObject:label];
|
||||
}
|
||||
|
||||
[subviews addObject:[UIView new]];
|
||||
|
||||
if (self.backup.backupPassword) {
|
||||
[subviews
|
||||
addObject:[self makeButtonWithTitle:NSLocalizedString(@"BACKUP_EXPORT_COPY_PASSWORD_BUTTON",
|
||||
@"Label for button that copies backup password to the pasteboard.")
|
||||
selector:@selector(copyPassword)]];
|
||||
}
|
||||
|
||||
[subviews addObject:[self makeButtonWithTitle:NSLocalizedString(@"BACKUP_EXPORT_SHARE_BACKUP_BUTTON",
|
||||
@"Label for button that opens share UI for backup.")
|
||||
selector:@selector(shareBackup)]];
|
||||
|
||||
if (self.backup.currentThread) {
|
||||
[subviews
|
||||
addObject:[self makeButtonWithTitle:NSLocalizedString(@"BACKUP_EXPORT_SEND_BACKUP_BUTTON",
|
||||
@"Label for button that 'send backup' in the current conversation.")
|
||||
selector:@selector(sendBackup)]];
|
||||
}
|
||||
|
||||
// TODO: We should offer the option to save the backup to "Files", iCloud, Dropbox, etc.
|
||||
|
||||
UIView *container = [UIView verticalStackWithSubviews:subviews spacing:10];
|
||||
[self.view addSubview:container];
|
||||
[container autoVCenterInSuperview];
|
||||
[container autoPinWidthToSuperviewWithMargin:25.f];
|
||||
}
|
||||
|
||||
- (void)showFailedUI
|
||||
{
|
||||
NSMutableArray<UIView *> *subviews = [NSMutableArray new];
|
||||
|
||||
{
|
||||
NSString *message
|
||||
= NSLocalizedString(@"BACKUP_EXPORT_FAILED_MESSAGE", @"Message indicating that backup export failed.");
|
||||
|
||||
UILabel *label = [UILabel new];
|
||||
label.text = message;
|
||||
label.textColor = [UIColor blackColor];
|
||||
label.font = [UIFont ows_regularFontWithSize:18.f];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
label.numberOfLines = 0;
|
||||
label.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
[subviews addObject:label];
|
||||
}
|
||||
|
||||
// TODO: We should offer the option to save the backup to "Files", iCloud, Dropbox, etc.
|
||||
|
||||
UIView *container = [UIView verticalStackWithSubviews:subviews spacing:10];
|
||||
[self.view addSubview:container];
|
||||
[container autoVCenterInSuperview];
|
||||
[container autoPinWidthToSuperviewWithMargin:25.f];
|
||||
}
|
||||
|
||||
- (UIView *)makeButtonWithTitle:(NSString *)title selector:(SEL)selector
|
||||
{
|
||||
const CGFloat kButtonHeight = 40;
|
||||
OWSFlatButton *button = [OWSFlatButton buttonWithTitle:title
|
||||
font:[OWSFlatButton fontForHeight:kButtonHeight]
|
||||
titleColor:[UIColor whiteColor]
|
||||
backgroundColor:[UIColor ows_materialBlueColor]
|
||||
target:self
|
||||
selector:selector];
|
||||
[button autoSetDimension:ALDimensionWidth toSize:140];
|
||||
[button autoSetDimension:ALDimensionHeight toSize:kButtonHeight];
|
||||
return button;
|
||||
}
|
||||
|
||||
- (void)copyPassword
|
||||
{
|
||||
OWSAssert(self.backup.backupPassword.length > 0);
|
||||
|
||||
// TODO: We could consider clearing the password from the pasteboard after a certain delay.
|
||||
[UIPasteboard.generalPasteboard setString:self.backup.backupPassword];
|
||||
}
|
||||
|
||||
- (void)shareBackup
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssert(self.backup.backupZipPath.length > 0);
|
||||
|
||||
[AttachmentSharing showShareUIForURL:[NSURL fileURLWithPath:self.backup.backupZipPath]];
|
||||
}
|
||||
|
||||
- (void)sendBackup
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssert(self.backup.backupZipPath.length > 0);
|
||||
OWSAssert(self.backup.currentThread);
|
||||
|
||||
[ModalActivityIndicatorViewController
|
||||
presentFromViewController:self
|
||||
canCancel:NO
|
||||
backgroundBlock:^(ModalActivityIndicatorViewController *modalActivityIndicator) {
|
||||
NSString *fileName = [self.backup.backupZipPath lastPathComponent];
|
||||
|
||||
OWSMessageSender *messageSender = [Environment current].messageSender;
|
||||
NSString *utiType = [MIMETypeUtil utiTypeForFileExtension:fileName.pathExtension];
|
||||
DataSource *_Nullable dataSource =
|
||||
[DataSourcePath dataSourceWithFilePath:self.backup.backupZipPath];
|
||||
[dataSource setSourceFilename:fileName];
|
||||
SignalAttachment *attachment =
|
||||
[SignalAttachment attachmentWithDataSource:dataSource dataUTI:utiType];
|
||||
if (!attachment || [attachment hasError]) {
|
||||
OWSFail(@"%@ attachment[%@]: %@",
|
||||
self.logTag,
|
||||
[attachment sourceFilename],
|
||||
[attachment errorName]);
|
||||
return;
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[ThreadUtil
|
||||
sendMessageWithAttachment:attachment
|
||||
inThread:self.backup.currentThread
|
||||
messageSender:messageSender
|
||||
completion:^(NSError *_Nullable error) {
|
||||
|
||||
OWSAssertIsOnMainThread();
|
||||
[modalActivityIndicator dismissWithCompletion:^{
|
||||
if (error) {
|
||||
DDLogError(@"%@ send backup failed: %@", self.logTag, error);
|
||||
[OWSAlerts
|
||||
showAlertWithTitle:NSLocalizedString(
|
||||
@"BACKUP_EXPORT_SEND_BACKUP_FAILED",
|
||||
@"Message indicating that sending "
|
||||
@"the backup failed.")];
|
||||
} else {
|
||||
[OWSAlerts
|
||||
showAlertWithTitle:
|
||||
NSLocalizedString(@"BACKUP_EXPORT_SEND_BACKUP_SUCCESS",
|
||||
@"Message indicating that sending the backup "
|
||||
@"succeeded.")];
|
||||
}
|
||||
}];
|
||||
}];
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)dismissWasPressed:(id)sender
|
||||
{
|
||||
[self.backup cancel];
|
||||
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
|
||||
#pragma mark - OWSBackupDelegate
|
||||
|
||||
- (void)backupStateDidChange
|
||||
{
|
||||
DDLogInfo(@"%@ %s.", self.logTag, __PRETTY_FUNCTION__);
|
||||
|
||||
[self updateUI];
|
||||
}
|
||||
|
||||
- (void)backupProgressDidChange
|
||||
{
|
||||
DDLogInfo(@"%@ %s.", self.logTag, __PRETTY_FUNCTION__);
|
||||
|
||||
self.progressView.progress = self.backup.backupProgress;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -1,17 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <SignalMessaging/OWSViewController.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class TSThread;
|
||||
|
||||
@interface OWSBackupImportViewController : OWSViewController
|
||||
|
||||
- (void)importBackup:(NSString *)backupZipPath password:(NSString *_Nullable)password;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -1,217 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSBackupImportViewController.h"
|
||||
#import "OWSBackup.h"
|
||||
#import "OWSProgressView.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import "ThreadUtil.h"
|
||||
#import <SignalMessaging/AttachmentSharing.h>
|
||||
#import <SignalMessaging/Environment.h>
|
||||
#import <SignalMessaging/SignalMessaging-Swift.h>
|
||||
#import <SignalMessaging/UIColor+OWS.h>
|
||||
#import <SignalMessaging/UIFont+OWS.h>
|
||||
#import <SignalMessaging/UIView+OWS.h>
|
||||
#import <SignalServiceKit/MIMETypeUtil.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSBackupImportViewController () <OWSBackupDelegate>
|
||||
|
||||
@property (nonatomic) OWSBackup *backup;
|
||||
|
||||
@property (nonatomic, nullable) OWSProgressView *progressView;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation OWSBackupImportViewController
|
||||
|
||||
- (void)loadView
|
||||
{
|
||||
[super loadView];
|
||||
|
||||
self.view.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
self.navigationItem.title = NSLocalizedString(@"BACKUP_IMPORT_VIEW_TITLE", @"Title for the 'backup import' view.");
|
||||
self.navigationItem.leftBarButtonItem =
|
||||
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop
|
||||
target:self
|
||||
action:@selector(dismissWasPressed:)];
|
||||
|
||||
self.backup.delegate = self;
|
||||
|
||||
[self updateUI];
|
||||
}
|
||||
|
||||
- (void)importBackup:(NSString *)backupZipPath password:(NSString *_Nullable)password
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssert(backupZipPath.length > 0);
|
||||
|
||||
// We set ourselves as the delegate of the backup later,
|
||||
// after we've loaded our view.
|
||||
self.backup = [OWSBackup new];
|
||||
[self.backup importBackup:backupZipPath password:password];
|
||||
}
|
||||
|
||||
- (void)updateUI
|
||||
{
|
||||
for (UIView *subview in self.view.subviews) {
|
||||
[subview removeFromSuperview];
|
||||
}
|
||||
self.progressView = nil;
|
||||
|
||||
switch (self.backup.backupState) {
|
||||
case OWSBackupState_InProgress:
|
||||
[self showInProgressUI];
|
||||
break;
|
||||
case OWSBackupState_Cancelled:
|
||||
[self showCancelledUI];
|
||||
break;
|
||||
case OWSBackupState_Complete:
|
||||
[self showCompleteUI];
|
||||
break;
|
||||
case OWSBackupState_Failed:
|
||||
[self showFailedUI];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showInProgressUI
|
||||
{
|
||||
self.progressView = [OWSProgressView new];
|
||||
self.progressView.color = [UIColor ows_materialBlueColor];
|
||||
self.progressView.progress = self.backup.backupProgress;
|
||||
[self.progressView autoSetDimension:ALDimensionWidth toSize:300];
|
||||
[self.progressView autoSetDimension:ALDimensionHeight toSize:20];
|
||||
|
||||
UILabel *label = [UILabel new];
|
||||
label.text = NSLocalizedString(
|
||||
@"BACKUP_IMPORT_IN_PROGRESS_MESSAGE", @"Message indicating that backup import is in progress.");
|
||||
label.textColor = [UIColor blackColor];
|
||||
label.font = [UIFont ows_regularFontWithSize:18.f];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
label.numberOfLines = 0;
|
||||
label.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
|
||||
UIView *container = [UIView verticalStackWithSubviews:@[
|
||||
label,
|
||||
self.progressView,
|
||||
]
|
||||
spacing:10];
|
||||
[self.view addSubview:container];
|
||||
[container autoVCenterInSuperview];
|
||||
[container autoPinWidthToSuperviewWithMargin:25.f];
|
||||
}
|
||||
|
||||
- (void)showCancelledUI
|
||||
{
|
||||
// Show nothing.
|
||||
}
|
||||
|
||||
- (void)showCompleteUI
|
||||
{
|
||||
NSMutableArray<UIView *> *subviews = [NSMutableArray new];
|
||||
|
||||
{
|
||||
NSString *message = NSLocalizedString(
|
||||
@"BACKUP_IMPORT_COMPLETE_MESSAGE", @"Message indicating that backup import is complete.");
|
||||
|
||||
UILabel *label = [UILabel new];
|
||||
label.text = message;
|
||||
label.textColor = [UIColor blackColor];
|
||||
label.font = [UIFont ows_regularFontWithSize:18.f];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
label.numberOfLines = 0;
|
||||
label.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
[subviews addObject:label];
|
||||
}
|
||||
|
||||
[subviews addObject:[UIView new]];
|
||||
|
||||
[subviews addObject:[self makeButtonWithTitle:NSLocalizedString(@"BACKUP_IMPORT_RESTART_BUTTON",
|
||||
@"Label for button that restarts app to complete restore.")
|
||||
selector:@selector(restartApp)]];
|
||||
|
||||
UIView *container = [UIView verticalStackWithSubviews:subviews spacing:10];
|
||||
[self.view addSubview:container];
|
||||
[container autoVCenterInSuperview];
|
||||
[container autoPinWidthToSuperviewWithMargin:25.f];
|
||||
}
|
||||
|
||||
- (void)showFailedUI
|
||||
{
|
||||
NSMutableArray<UIView *> *subviews = [NSMutableArray new];
|
||||
|
||||
{
|
||||
NSString *message
|
||||
= NSLocalizedString(@"BACKUP_IMPORT_FAILED_MESSAGE", @"Message indicating that backup import failed.");
|
||||
|
||||
UILabel *label = [UILabel new];
|
||||
label.text = message;
|
||||
label.textColor = [UIColor blackColor];
|
||||
label.font = [UIFont ows_regularFontWithSize:18.f];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
label.numberOfLines = 0;
|
||||
label.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
[subviews addObject:label];
|
||||
}
|
||||
|
||||
// TODO: We should offer the option to save the backup to "Files", iCloud, Dropbox, etc.
|
||||
|
||||
UIView *container = [UIView verticalStackWithSubviews:subviews spacing:10];
|
||||
[self.view addSubview:container];
|
||||
[container autoVCenterInSuperview];
|
||||
[container autoPinWidthToSuperviewWithMargin:25.f];
|
||||
}
|
||||
|
||||
- (UIView *)makeButtonWithTitle:(NSString *)title selector:(SEL)selector
|
||||
{
|
||||
const CGFloat kButtonHeight = 40;
|
||||
OWSFlatButton *button = [OWSFlatButton buttonWithTitle:title
|
||||
font:[OWSFlatButton fontForHeight:kButtonHeight]
|
||||
titleColor:[UIColor whiteColor]
|
||||
backgroundColor:[UIColor ows_materialBlueColor]
|
||||
target:self
|
||||
selector:selector];
|
||||
[button autoSetDimension:ALDimensionWidth toSize:140];
|
||||
[button autoSetDimension:ALDimensionHeight toSize:kButtonHeight];
|
||||
return button;
|
||||
}
|
||||
|
||||
- (void)dismissWasPressed:(id)sender
|
||||
{
|
||||
[self.backup cancel];
|
||||
|
||||
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)restartApp
|
||||
{
|
||||
DDLogInfo(@"%@ %s.", self.logTag, __PRETTY_FUNCTION__);
|
||||
|
||||
OWSRaiseException(@"OWSBackup_RestartAppToCompleteBackupRestore", @"Killing app to complete backup restore");
|
||||
}
|
||||
|
||||
#pragma mark - OWSBackupDelegate
|
||||
|
||||
- (void)backupStateDidChange
|
||||
{
|
||||
DDLogInfo(@"%@ %s.", self.logTag, __PRETTY_FUNCTION__);
|
||||
|
||||
[self updateUI];
|
||||
}
|
||||
|
||||
- (void)backupProgressDidChange
|
||||
{
|
||||
DDLogInfo(@"%@ %s.", self.logTag, __PRETTY_FUNCTION__);
|
||||
|
||||
self.progressView.progress = self.backup.backupProgress;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -367,8 +367,8 @@ NSString *const kProfileView_LastPresentedDate = @"kProfileView_LastPresentedDat
|
|||
|
||||
NSString *normalizedProfileName = [self normalizedProfileName];
|
||||
if ([OWSProfileManager.sharedManager isProfileNameTooLong:normalizedProfileName]) {
|
||||
[OWSAlerts showAlertWithTitle:NSLocalizedString(@"ALERT_ERROR_TITLE", @"")
|
||||
message:NSLocalizedString(@"PROFILE_VIEW_ERROR_PROFILE_NAME_TOO_LONG",
|
||||
[OWSAlerts
|
||||
showErrorAlertWithMessage:NSLocalizedString(@"PROFILE_VIEW_ERROR_PROFILE_NAME_TOO_LONG",
|
||||
@"Error message shown when user tries to update profile with a profile name "
|
||||
@"that is too long.")];
|
||||
return;
|
||||
|
@ -396,14 +396,11 @@ NSString *const kProfileView_LastPresentedDate = @"kProfileView_LastPresentedDat
|
|||
[alertController
|
||||
dismissViewControllerAnimated:NO
|
||||
completion:^{
|
||||
[OWSAlerts
|
||||
showAlertWithTitle:NSLocalizedString(
|
||||
@"ALERT_ERROR_TITLE", @"")
|
||||
message:
|
||||
NSLocalizedString(
|
||||
@"PROFILE_VIEW_ERROR_UPDATE_FAILED",
|
||||
@"Error message shown when a "
|
||||
@"profile update fails.")];
|
||||
[OWSAlerts showErrorAlertWithMessage:
|
||||
NSLocalizedString(
|
||||
@"PROFILE_VIEW_ERROR_UPDATE_FAILED",
|
||||
@"Error message shown when a "
|
||||
@"profile update fails.")];
|
||||
}];
|
||||
}];
|
||||
}];
|
||||
|
|
|
@ -64,28 +64,32 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
#pragma mark - View Lifecycle
|
||||
|
||||
- (void)viewDidLoad {
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
[self createViews];
|
||||
|
||||
|
||||
[self initializeKeyboardHandlers];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
[self enableServerActions:YES];
|
||||
[self updatePhoneNumberLabel];
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated {
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
[super viewDidAppear:animated];
|
||||
[_challengeTextField becomeFirstResponder];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark -
|
||||
|
||||
- (void)createViews {
|
||||
- (void)createViews
|
||||
{
|
||||
self.view.backgroundColor = [UIColor whiteColor];
|
||||
self.view.opaque = YES;
|
||||
|
||||
|
@ -109,16 +113,16 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[titleLabel autoHCenterInSuperview];
|
||||
|
||||
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[backButton setTitle:NSLocalizedString(@"VERIFICATION_BACK_BUTTON", @"button text for back button on verification view")
|
||||
forState:UIControlStateNormal];
|
||||
[backButton setTitleColor:[UIColor whiteColor]
|
||||
forState:UIControlStateNormal];
|
||||
[backButton
|
||||
setTitle:NSLocalizedString(@"VERIFICATION_BACK_BUTTON", @"button text for back button on verification view")
|
||||
forState:UIControlStateNormal];
|
||||
[backButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||
backButton.titleLabel.font = [UIFont ows_mediumFontWithSize:14.f];
|
||||
[header addSubview:backButton];
|
||||
[backButton autoPinLeadingToSuperviewWithMargin:10.f];
|
||||
[backButton autoAlignAxis:ALAxisHorizontal toSameAxisOfView:titleLabel];
|
||||
[backButton addTarget:self action:@selector(backButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
|
||||
_phoneNumberLabel = [UILabel new];
|
||||
_phoneNumberLabel.textColor = [UIColor ows_darkGrayColor];
|
||||
_phoneNumberLabel.font = [UIFont ows_regularFontWithSize:20.f];
|
||||
|
@ -133,25 +137,23 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
withOffset:ScaleFromIPhone5To7Plus(30, 100)];
|
||||
|
||||
const CGFloat kHMargin = 36;
|
||||
|
||||
|
||||
_challengeTextField = [UITextField new];
|
||||
_challengeTextField.textColor = [UIColor blackColor];
|
||||
_challengeTextField.placeholder = NSLocalizedString(@"VERIFICATION_CHALLENGE_DEFAULT_TEXT",
|
||||
@"Text field placeholder for SMS verification code during registration");
|
||||
@"Text field placeholder for SMS verification code during registration");
|
||||
_challengeTextField.font = [UIFont ows_lightFontWithSize:21.f];
|
||||
_challengeTextField.textAlignment = NSTextAlignmentCenter;
|
||||
_challengeTextField.keyboardType = UIKeyboardTypeNumberPad;
|
||||
_challengeTextField.delegate = self;
|
||||
_challengeTextField.delegate = self;
|
||||
[self.view addSubview:_challengeTextField];
|
||||
[_challengeTextField autoPinWidthToSuperviewWithMargin:kHMargin];
|
||||
[_challengeTextField autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:_phoneNumberLabel
|
||||
withOffset:25];
|
||||
|
||||
[_challengeTextField autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:_phoneNumberLabel withOffset:25];
|
||||
|
||||
UIView *underscoreView = [UIView new];
|
||||
underscoreView.backgroundColor = [UIColor colorWithWhite:0.5 alpha:1.f];
|
||||
[self.view addSubview:underscoreView];
|
||||
[underscoreView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:_challengeTextField
|
||||
withOffset:3];
|
||||
[underscoreView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:_challengeTextField withOffset:3];
|
||||
[underscoreView autoPinWidthToSuperviewWithMargin:kHMargin];
|
||||
[underscoreView autoSetDimension:ALDimensionHeight toSize:1.f];
|
||||
|
||||
|
@ -175,7 +177,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
const CGFloat kSpinnerSize = 20;
|
||||
const CGFloat kSpinnerSpacing = ScaleFromIPhone5To7Plus(5, 15);
|
||||
|
||||
_submitCodeSpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
|
||||
_submitCodeSpinner =
|
||||
[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
|
||||
[_submitButton addSubview:_submitCodeSpinner];
|
||||
[_submitCodeSpinner autoSetDimension:ALDimensionWidth toSize:kSpinnerSize];
|
||||
[_submitCodeSpinner autoSetDimension:ALDimensionHeight toSize:kSpinnerSize];
|
||||
|
@ -184,10 +187,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
_sendCodeViaSMSAgainButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
_sendCodeViaSMSAgainButton.backgroundColor = [UIColor whiteColor];
|
||||
[_sendCodeViaSMSAgainButton setTitle:NSLocalizedString(@"VERIFICATION_CHALLENGE_SUBMIT_AGAIN", @"button text during registration to request another SMS code be sent")
|
||||
forState:UIControlStateNormal];
|
||||
[_sendCodeViaSMSAgainButton setTitleColor:signalBlueColor
|
||||
forState:UIControlStateNormal];
|
||||
[_sendCodeViaSMSAgainButton setTitle:NSLocalizedString(@"VERIFICATION_CHALLENGE_SUBMIT_AGAIN",
|
||||
@"button text during registration to request another SMS code be sent")
|
||||
forState:UIControlStateNormal];
|
||||
[_sendCodeViaSMSAgainButton setTitleColor:signalBlueColor forState:UIControlStateNormal];
|
||||
_sendCodeViaSMSAgainButton.titleLabel.font = [UIFont ows_mediumFontWithSize:14.f];
|
||||
[_sendCodeViaSMSAgainButton addTarget:self
|
||||
action:@selector(sendCodeViaSMSAction:)
|
||||
|
@ -196,8 +199,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[_sendCodeViaSMSAgainButton autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:_submitButton withOffset:10];
|
||||
[_sendCodeViaSMSAgainButton autoPinWidthToSuperviewWithMargin:kHMargin];
|
||||
[_sendCodeViaSMSAgainButton autoSetDimension:ALDimensionHeight toSize:35];
|
||||
|
||||
_requestCodeAgainSpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
|
||||
_requestCodeAgainSpinner =
|
||||
[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
[_sendCodeViaSMSAgainButton addSubview:_requestCodeAgainSpinner];
|
||||
[_requestCodeAgainSpinner autoSetDimension:ALDimensionWidth toSize:kSpinnerSize];
|
||||
[_requestCodeAgainSpinner autoSetDimension:ALDimensionHeight toSize:kSpinnerSize];
|
||||
|
@ -206,11 +210,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
_sendCodeViaVoiceButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
_sendCodeViaVoiceButton.backgroundColor = [UIColor whiteColor];
|
||||
[_sendCodeViaVoiceButton setTitle:NSLocalizedString(@"VERIFICATION_CHALLENGE_SEND_VIA_VOICE",
|
||||
@"button text during registration to request phone number verification be done via phone call")
|
||||
forState:UIControlStateNormal];
|
||||
[_sendCodeViaVoiceButton setTitleColor:signalBlueColor
|
||||
forState:UIControlStateNormal];
|
||||
[_sendCodeViaVoiceButton
|
||||
setTitle:NSLocalizedString(@"VERIFICATION_CHALLENGE_SEND_VIA_VOICE",
|
||||
@"button text during registration to request phone number verification be done via phone call")
|
||||
forState:UIControlStateNormal];
|
||||
[_sendCodeViaVoiceButton setTitleColor:signalBlueColor forState:UIControlStateNormal];
|
||||
_sendCodeViaVoiceButton.titleLabel.font = [UIFont ows_mediumFontWithSize:14.f];
|
||||
[_sendCodeViaVoiceButton addTarget:self
|
||||
action:@selector(sendCodeViaVoiceAction:)
|
||||
|
@ -219,8 +223,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[_sendCodeViaVoiceButton autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:_sendCodeViaSMSAgainButton];
|
||||
[_sendCodeViaVoiceButton autoPinWidthToSuperviewWithMargin:kHMargin];
|
||||
[_sendCodeViaVoiceButton autoSetDimension:ALDimensionHeight toSize:35];
|
||||
|
||||
_requestCallSpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
|
||||
_requestCallSpinner =
|
||||
[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
[_sendCodeViaVoiceButton addSubview:_requestCallSpinner];
|
||||
[_requestCallSpinner autoSetDimension:ALDimensionWidth toSize:kSpinnerSize];
|
||||
[_requestCallSpinner autoSetDimension:ALDimensionHeight toSize:kSpinnerSize];
|
||||
|
@ -316,13 +321,15 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[self presentViewController:alert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (NSString *)validationCodeFromTextField {
|
||||
- (NSString *)validationCodeFromTextField
|
||||
{
|
||||
return [self.challengeTextField.text stringByReplacingOccurrencesOfString:@"-" withString:@""];
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (void)sendCodeViaSMSAction:(id)sender {
|
||||
- (void)sendCodeViaSMSAction:(id)sender
|
||||
{
|
||||
OWSProdInfo([OWSAnalyticsEvents registrationRegisteringRequestedNewCodeBySms]);
|
||||
|
||||
[self enableServerActions:NO];
|
||||
|
@ -343,7 +350,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}];
|
||||
}
|
||||
|
||||
- (void)sendCodeViaVoiceAction:(id)sender {
|
||||
- (void)sendCodeViaVoiceAction:(id)sender
|
||||
{
|
||||
OWSProdInfo([OWSAnalyticsEvents registrationRegisteringRequestedNewCodeByVoice]);
|
||||
|
||||
[self enableServerActions:NO];
|
||||
|
@ -365,18 +373,21 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}];
|
||||
}
|
||||
|
||||
- (void)showRegistrationErrorMessage:(NSError *)registrationError {
|
||||
- (void)showRegistrationErrorMessage:(NSError *)registrationError
|
||||
{
|
||||
[OWSAlerts showAlertWithTitle:registrationError.localizedDescription
|
||||
message:registrationError.localizedRecoverySuggestion];
|
||||
}
|
||||
|
||||
- (void)enableServerActions:(BOOL)enabled {
|
||||
- (void)enableServerActions:(BOOL)enabled
|
||||
{
|
||||
[_submitButton setEnabled:enabled];
|
||||
[_sendCodeViaSMSAgainButton setEnabled:enabled];
|
||||
[_sendCodeViaVoiceButton setEnabled:enabled];
|
||||
}
|
||||
|
||||
- (void)backButtonPressed:(id)sender {
|
||||
- (void)backButtonPressed:(id)sender
|
||||
{
|
||||
OWSProdInfo([OWSAnalyticsEvents registrationVerificationBack]);
|
||||
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
|
@ -384,20 +395,23 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
#pragma mark - Keyboard notifications
|
||||
|
||||
- (void)initializeKeyboardHandlers {
|
||||
- (void)initializeKeyboardHandlers
|
||||
{
|
||||
UITapGestureRecognizer *outsideTabRecognizer =
|
||||
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboardFromAppropriateSubView)];
|
||||
[self.view addGestureRecognizer:outsideTabRecognizer];
|
||||
self.view.userInteractionEnabled = YES;
|
||||
}
|
||||
|
||||
- (void)dismissKeyboardFromAppropriateSubView {
|
||||
- (void)dismissKeyboardFromAppropriateSubView
|
||||
{
|
||||
[self.view endEditing:NO];
|
||||
}
|
||||
|
||||
- (BOOL)textField:(UITextField *)textField
|
||||
shouldChangeCharactersInRange:(NSRange)range
|
||||
replacementString:(NSString *)insertionText {
|
||||
replacementString:(NSString *)insertionText
|
||||
{
|
||||
|
||||
// Verification codes take this form: "123-456".
|
||||
//
|
||||
|
@ -412,7 +426,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
// * Always accept deletes.
|
||||
// * Ignore invalid input.
|
||||
// * Take partial input if possible.
|
||||
|
||||
|
||||
NSString *oldText = textField.text;
|
||||
// Construct the new contents of the text field by:
|
||||
// 1. Determining the "left" substring: the contents of the old text _before_ the deletion range.
|
||||
|
@ -424,21 +438,18 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
NSString *center = insertionText.digitsOnly;
|
||||
// 3a. Trim the tail of the "center" substring to ensure that we don't end up
|
||||
// with more than 6 decimal digits.
|
||||
while (center.length > 0 &&
|
||||
left.length + center.length + right.length > 6) {
|
||||
while (center.length > 0 && left.length + center.length + right.length > 6) {
|
||||
center = [center substringToIndex:center.length - 1];
|
||||
}
|
||||
// 4. Construct the "raw" new text by concatenating left, center and right.
|
||||
NSString *rawNewText = [[left stringByAppendingString:center]
|
||||
stringByAppendingString:right];
|
||||
NSString *rawNewText = [[left stringByAppendingString:center] stringByAppendingString:right];
|
||||
// 5. Construct the "formatted" new text by inserting a hyphen if necessary.
|
||||
NSString *formattedNewText = (rawNewText.length <= 3
|
||||
? rawNewText
|
||||
: [[[rawNewText substringToIndex:3]
|
||||
stringByAppendingString:@"-"]
|
||||
stringByAppendingString:[rawNewText substringFromIndex:3]]);
|
||||
NSString *formattedNewText
|
||||
= (rawNewText.length <= 3 ? rawNewText
|
||||
: [[[rawNewText substringToIndex:3] stringByAppendingString:@"-"]
|
||||
stringByAppendingString:[rawNewText substringFromIndex:3]]);
|
||||
textField.text = formattedNewText;
|
||||
|
||||
|
||||
// Move the cursor after the newly inserted text.
|
||||
NSUInteger newInsertionPoint = left.length + center.length;
|
||||
if (newInsertionPoint > 3) {
|
||||
|
@ -446,32 +457,32 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
// if necessary.
|
||||
newInsertionPoint++;
|
||||
}
|
||||
UITextPosition *newPosition = [textField positionFromPosition:textField.beginningOfDocument
|
||||
offset:(NSInteger) newInsertionPoint];
|
||||
textField.selectedTextRange = [textField textRangeFromPosition:newPosition
|
||||
toPosition:newPosition];
|
||||
|
||||
UITextPosition *newPosition =
|
||||
[textField positionFromPosition:textField.beginningOfDocument offset:(NSInteger)newInsertionPoint];
|
||||
textField.selectedTextRange = [textField textRangeFromPosition:newPosition toPosition:newPosition];
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
|
||||
- (BOOL)textFieldShouldReturn:(UITextField *)textField
|
||||
{
|
||||
[self submitVerificationCode];
|
||||
[textField resignFirstResponder];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)setVerificationCodeAndTryToVerify:(NSString *)verificationCode {
|
||||
- (void)setVerificationCodeAndTryToVerify:(NSString *)verificationCode
|
||||
{
|
||||
NSString *rawNewText = verificationCode.digitsOnly;
|
||||
NSString *formattedNewText = (rawNewText.length <= 3
|
||||
? rawNewText
|
||||
: [[[rawNewText substringToIndex:3]
|
||||
stringByAppendingString:@"-"]
|
||||
stringByAppendingString:[rawNewText substringFromIndex:3]]);
|
||||
NSString *formattedNewText
|
||||
= (rawNewText.length <= 3 ? rawNewText
|
||||
: [[[rawNewText substringToIndex:3] stringByAppendingString:@"-"]
|
||||
stringByAppendingString:[rawNewText substringFromIndex:3]]);
|
||||
self.challengeTextField.text = formattedNewText;
|
||||
// Move the cursor after the newly inserted text.
|
||||
UITextPosition *newPosition = [self.challengeTextField endOfDocument];
|
||||
self.challengeTextField.selectedTextRange = [self.challengeTextField textRangeFromPosition:newPosition
|
||||
toPosition:newPosition];
|
||||
self.challengeTextField.selectedTextRange =
|
||||
[self.challengeTextField textRangeFromPosition:newPosition toPosition:newPosition];
|
||||
[self submitVerificationCode];
|
||||
}
|
||||
|
|
@ -53,7 +53,8 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi
|
|||
[SignalApp.sharedApp setSignUpFlowNavigationController:self.navigationController];
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
OWSProdInfo([OWSAnalyticsEvents registrationBegan]);
|
||||
|
@ -69,7 +70,7 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi
|
|||
UIView *headerWrapper = [UIView containerView];
|
||||
[self.view addSubview:headerWrapper];
|
||||
headerWrapper.backgroundColor = UIColor.ows_signalBrandBlueColor;
|
||||
|
||||
|
||||
UIView *headerContent = [UIView new];
|
||||
[headerWrapper addSubview:headerContent];
|
||||
[headerWrapper autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero excludingEdge:ALEdgeBottom];
|
||||
|
@ -230,7 +231,8 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi
|
|||
[spinnerView stopAnimating];
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated {
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
[super viewDidAppear:animated];
|
||||
|
||||
[self.activateButton setEnabled:YES];
|
||||
|
@ -240,7 +242,8 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi
|
|||
|
||||
#pragma mark - Country
|
||||
|
||||
- (void)populateDefaultCountryNameAndCode {
|
||||
- (void)populateDefaultCountryNameAndCode
|
||||
{
|
||||
NSString *countryCode = [PhoneNumber defaultCountryCode];
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -253,15 +256,14 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi
|
|||
NSNumber *callingCode = [[PhoneNumberUtil sharedUtil].nbPhoneNumberUtil getCountryCodeForRegion:countryCode];
|
||||
NSString *countryName = [PhoneNumberUtil countryNameFromCountryCode:countryCode];
|
||||
[self updateCountryWithName:countryName
|
||||
callingCode:[NSString stringWithFormat:@"%@%@",
|
||||
COUNTRY_CODE_PREFIX,
|
||||
callingCode]
|
||||
callingCode:[NSString stringWithFormat:@"%@%@", COUNTRY_CODE_PREFIX, callingCode]
|
||||
countryCode:countryCode];
|
||||
}
|
||||
|
||||
- (void)updateCountryWithName:(NSString *)countryName
|
||||
callingCode:(NSString *)callingCode
|
||||
countryCode:(NSString *)countryCode {
|
||||
countryCode:(NSString *)countryCode
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssert(countryName.length > 0);
|
||||
OWSAssert(callingCode.length > 0);
|
||||
|
@ -270,9 +272,7 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi
|
|||
_countryCode = countryCode;
|
||||
_callingCode = callingCode;
|
||||
|
||||
NSString *title = [NSString stringWithFormat:@"%@ (%@)",
|
||||
callingCode,
|
||||
countryCode.uppercaseString];
|
||||
NSString *title = [NSString stringWithFormat:@"%@ (%@)", callingCode, countryCode.uppercaseString];
|
||||
self.countryCodeLabel.text = title;
|
||||
[self.countryCodeLabel setNeedsLayout];
|
||||
|
||||
|
@ -385,13 +385,15 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi
|
|||
|
||||
#pragma mark - Keyboard notifications
|
||||
|
||||
- (void)initializeKeyboardHandlers {
|
||||
- (void)initializeKeyboardHandlers
|
||||
{
|
||||
UITapGestureRecognizer *outsideTabRecognizer =
|
||||
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboardFromAppropriateSubView)];
|
||||
[self.view addGestureRecognizer:outsideTabRecognizer];
|
||||
}
|
||||
|
||||
- (void)dismissKeyboardFromAppropriateSubView {
|
||||
- (void)dismissKeyboardFromAppropriateSubView
|
||||
{
|
||||
[self.view endEditing:NO];
|
||||
}
|
||||
|
||||
|
@ -399,7 +401,8 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi
|
|||
|
||||
- (BOOL)textField:(UITextField *)textField
|
||||
shouldChangeCharactersInRange:(NSRange)range
|
||||
replacementString:(NSString *)insertionText {
|
||||
replacementString:(NSString *)insertionText
|
||||
{
|
||||
|
||||
[ViewControllerUtils phoneNumberTextField:textField
|
||||
shouldChangeCharactersInRange:range
|
||||
|
@ -409,7 +412,8 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi
|
|||
return NO; // inform our caller that we took care of performing the change
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
|
||||
- (BOOL)textFieldShouldReturn:(UITextField *)textField
|
||||
{
|
||||
[self sendCodeAction];
|
||||
[textField resignFirstResponder];
|
||||
return NO;
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SelectRecipientViewController.h"
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AddToGroupViewController.h"
|
|
@ -263,13 +263,19 @@ typedef void (^CustomLayoutBlock)(void);
|
|||
fingerprintLabel.userInteractionEnabled = YES;
|
||||
[self.view addSubview:fingerprintLabel];
|
||||
[fingerprintLabel autoPinWidthToSuperviewWithMargin:ScaleFromIPhone5To7Plus(50.f, 60.f)];
|
||||
[fingerprintLabel autoPinEdge:ALEdgeBottom toEdge:ALEdgeTop ofView:instructionsLabel withOffset:-ScaleFromIPhone5To7Plus(8.f, 15.f)];
|
||||
[fingerprintLabel autoPinEdge:ALEdgeBottom
|
||||
toEdge:ALEdgeTop
|
||||
ofView:instructionsLabel
|
||||
withOffset:-ScaleFromIPhone5To7Plus(8.f, 15.f)];
|
||||
|
||||
// Fingerprint Image
|
||||
CustomLayoutView *fingerprintView = [CustomLayoutView new];
|
||||
[self.view addSubview:fingerprintView];
|
||||
[fingerprintView autoPinWidthToSuperview];
|
||||
[fingerprintView autoPinEdge:ALEdgeBottom toEdge:ALEdgeTop ofView:fingerprintLabel withOffset:-ScaleFromIPhone5To7Plus(10.f, 15.f)];
|
||||
[fingerprintView autoPinEdge:ALEdgeBottom
|
||||
toEdge:ALEdgeTop
|
||||
ofView:fingerprintLabel
|
||||
withOffset:-ScaleFromIPhone5To7Plus(10.f, 15.f)];
|
||||
[fingerprintView
|
||||
addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self
|
||||
action:@selector(fingerprintViewTapped:)]];
|
||||
|
@ -406,14 +412,18 @@ typedef void (^CustomLayoutBlock)(void);
|
|||
|
||||
OWSCompareSafetyNumbersActivity *compareActivity = [[OWSCompareSafetyNumbersActivity alloc] initWithDelegate:self];
|
||||
|
||||
NSString *shareFormat = NSLocalizedString(@"SAFETY_NUMBER_SHARE_FORMAT", @"Snippet to share {{safety number}} with a friend. sent e.g. via SMS");
|
||||
NSString *shareFormat = NSLocalizedString(
|
||||
@"SAFETY_NUMBER_SHARE_FORMAT", @"Snippet to share {{safety number}} with a friend. sent e.g. via SMS");
|
||||
NSString *shareString = [NSString stringWithFormat:shareFormat, self.fingerprint.displayableText];
|
||||
|
||||
UIActivityViewController *activityController =
|
||||
[[UIActivityViewController alloc] initWithActivityItems:@[ shareString ]
|
||||
applicationActivities:@[ compareActivity ]];
|
||||
|
||||
activityController.completionWithItemsHandler = ^void(UIActivityType __nullable activityType, BOOL completed, NSArray * __nullable returnedItems, NSError * __nullable activityError){
|
||||
activityController.completionWithItemsHandler = ^void(UIActivityType __nullable activityType,
|
||||
BOOL completed,
|
||||
NSArray *__nullable returnedItems,
|
||||
NSError *__nullable activityError) {
|
||||
if (completionHandler) {
|
||||
completionHandler();
|
||||
}
|
||||
|
@ -512,20 +522,20 @@ typedef void (^CustomLayoutBlock)(void);
|
|||
- (void)verifyUnverifyButtonTapped:(UIGestureRecognizer *)gestureRecognizer
|
||||
{
|
||||
if (gestureRecognizer.state == UIGestureRecognizerStateRecognized) {
|
||||
[OWSPrimaryStorage.sharedManager.newDatabaseConnection readWriteWithBlock:^(
|
||||
YapDatabaseReadWriteTransaction *transaction) {
|
||||
BOOL isVerified = [[OWSIdentityManager sharedManager] verificationStateForRecipientId:self.recipientId
|
||||
transaction:transaction]
|
||||
== OWSVerificationStateVerified;
|
||||
[OWSPrimaryStorage.sharedManager.newDatabaseConnection
|
||||
readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
BOOL isVerified = [[OWSIdentityManager sharedManager] verificationStateForRecipientId:self.recipientId
|
||||
transaction:transaction]
|
||||
== OWSVerificationStateVerified;
|
||||
|
||||
OWSVerificationState newVerificationState
|
||||
= (isVerified ? OWSVerificationStateDefault : OWSVerificationStateVerified);
|
||||
[[OWSIdentityManager sharedManager] setVerificationState:newVerificationState
|
||||
identityKey:self.identityKey
|
||||
recipientId:self.recipientId
|
||||
isUserInitiatedChange:YES
|
||||
transaction:transaction];
|
||||
}];
|
||||
OWSVerificationState newVerificationState
|
||||
= (isVerified ? OWSVerificationStateDefault : OWSVerificationStateVerified);
|
||||
[[OWSIdentityManager sharedManager] setVerificationState:newVerificationState
|
||||
identityKey:self.identityKey
|
||||
recipientId:self.recipientId
|
||||
isUserInitiatedChange:YES
|
||||
transaction:transaction];
|
||||
}];
|
||||
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSTableViewController.h"
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSAddToContactViewController.h"
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSConversationSettingsViewDelegate.h"
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSTableViewController.h"
|
|
@ -93,7 +93,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
self.memberRecipientIds = [NSSet setWithArray:self.thread.groupModel.groupMemberIds];
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
OWSAssert([self.navigationController isKindOfClass:[OWSNavigationController class]]);
|
||||
|
@ -225,12 +226,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
__weak ShowGroupMembersViewController *weakSelf = self;
|
||||
UIAlertAction *verifyAction = [UIAlertAction
|
||||
actionWithTitle:NSLocalizedString(@"OK", nil)
|
||||
style:UIAlertActionStyleDestructive
|
||||
handler:^(UIAlertAction *_Nonnull action) {
|
||||
[weakSelf resetAllNoLongerVerified];
|
||||
}];
|
||||
UIAlertAction *verifyAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
|
||||
style:UIAlertActionStyleDestructive
|
||||
handler:^(UIAlertAction *_Nonnull action) {
|
||||
[weakSelf resetAllNoLongerVerified];
|
||||
}];
|
||||
[actionSheetController addAction:verifyAction];
|
||||
[actionSheetController addAction:[OWSAlerts cancelAction]];
|
||||
|
|
@ -4,71 +4,33 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern NSString *const OWSBackup_FileExtension;
|
||||
|
||||
@protocol OWSBackupDelegate <NSObject>
|
||||
|
||||
- (void)backupStateDidChange;
|
||||
|
||||
- (void)backupProgressDidChange;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
extern NSString *const NSNotificationNameBackupStateDidChange;
|
||||
|
||||
typedef NS_ENUM(NSUInteger, OWSBackupState) {
|
||||
// Has never backed up, not trying to backup yet.
|
||||
OWSBackupState_Idle = 0,
|
||||
// Backing up.
|
||||
OWSBackupState_InProgress,
|
||||
OWSBackupState_Cancelled,
|
||||
OWSBackupState_Complete,
|
||||
// Last backup failed.
|
||||
OWSBackupState_Failed,
|
||||
// Last backup succeeded.
|
||||
OWSBackupState_Succeeded,
|
||||
};
|
||||
|
||||
@class TSThread;
|
||||
|
||||
// We restore backups as part of the app launch process.
|
||||
//
|
||||
// applicationDidFinishLaunching must complete quickly even for
|
||||
// large backups, to prevent the app from being killed on launch.
|
||||
// Therefore, we break up backup import/restoration into two parts:
|
||||
//
|
||||
// * Preparation (which includes the costly decryption/unzip of the
|
||||
// backup file)
|
||||
// * Completion (file moves, NSUserDefaults writes, keychain writes).
|
||||
//
|
||||
// To protect data during backup and restore, we:
|
||||
//
|
||||
// * Optionally encrypt backup files with a password.
|
||||
// * Separately encrypt files containing keychain & NSUserDefaults data.
|
||||
// * Delete data from disk ASAP.
|
||||
@interface OWSBackup : NSObject
|
||||
|
||||
@property (nonatomic, weak) id<OWSBackupDelegate> delegate;
|
||||
@property (nonatomic, readonly) OWSBackupState backupExportState;
|
||||
|
||||
// An instance of `OWSBackup` is used for three separate tasks:
|
||||
//
|
||||
// * Backup export
|
||||
// * Backup import preparation
|
||||
// * Backup import completion
|
||||
//
|
||||
// The "backup state" and "progress" apply to all three tasks.
|
||||
@property (nonatomic, readonly) OWSBackupState backupState;
|
||||
@property (nonatomic, readonly) CGFloat backupProgress;
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
// If non-nil, backup is encrypted.
|
||||
@property (nonatomic, nullable, readonly) NSString *backupPassword;
|
||||
+ (instancetype)sharedManager;
|
||||
|
||||
// Only applies to "backup export" task.
|
||||
@property (nonatomic, nullable, readonly) TSThread *currentThread;
|
||||
- (BOOL)isBackupEnabled;
|
||||
- (void)setIsBackupEnabled:(BOOL)value;
|
||||
|
||||
@property (nonatomic, readonly) NSString *backupZipPath;
|
||||
|
||||
- (void)exportBackup:(nullable TSThread *)currentThread skipPassword:(BOOL)skipPassword;
|
||||
|
||||
- (void)importBackup:(NSString *)backupZipPath password:(NSString *_Nullable)password;
|
||||
|
||||
- (void)cancel;
|
||||
|
||||
+ (void)applicationDidFinishLaunching;
|
||||
- (void)setup;
|
||||
|
||||
@end
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
245
Signal/src/util/OWSBackupAPI.swift
Normal file
245
Signal/src/util/OWSBackupAPI.swift
Normal file
|
@ -0,0 +1,245 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SignalServiceKit
|
||||
import CloudKit
|
||||
|
||||
@objc public class OWSBackupAPI: NSObject {
|
||||
@objc
|
||||
public class func recordIdForTest() -> String {
|
||||
return "test-\(NSUUID().uuidString)"
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func saveTestFileToCloud(fileUrl: URL,
|
||||
success: @escaping (String) -> Swift.Void,
|
||||
failure: @escaping (Error) -> Swift.Void) {
|
||||
saveFileToCloud(fileUrl: fileUrl,
|
||||
recordName: NSUUID().uuidString,
|
||||
recordType: "test",
|
||||
success: success,
|
||||
failure: failure)
|
||||
}
|
||||
|
||||
// "Ephemeral" files are specific to this backup export and will always need to
|
||||
// be saved. For example, a complete image of the database is exported each time.
|
||||
// We wouldn't want to overwrite previous images until the entire backup export is
|
||||
// complete.
|
||||
@objc
|
||||
public class func saveEphemeralDatabaseFileToCloud(fileUrl: URL,
|
||||
success: @escaping (String) -> Swift.Void,
|
||||
failure: @escaping (Error) -> Swift.Void) {
|
||||
saveFileToCloud(fileUrl: fileUrl,
|
||||
recordName: NSUUID().uuidString,
|
||||
recordType: "ephemeralFile",
|
||||
success: success,
|
||||
failure: failure)
|
||||
}
|
||||
|
||||
// "Persistent" files may be shared between backup export; they should only be saved
|
||||
// once. For example, attachment files should only be uploaded once. Subsequent
|
||||
//
|
||||
@objc
|
||||
public class func savePersistentFileOnceToCloud(fileId: String,
|
||||
fileUrlBlock: @escaping (Swift.Void) -> URL?,
|
||||
success: @escaping (String) -> Swift.Void,
|
||||
failure: @escaping (Error) -> Swift.Void) {
|
||||
saveFileOnceToCloud(recordName: "persistentFile-\(fileId)",
|
||||
recordType: "persistentFile",
|
||||
fileUrlBlock: fileUrlBlock,
|
||||
success: success,
|
||||
failure: failure)
|
||||
}
|
||||
|
||||
// TODO:
|
||||
static let manifestRecordName = "manifest_"
|
||||
static let manifestRecordType = "manifest"
|
||||
static let payloadKey = "payload"
|
||||
|
||||
@objc
|
||||
public class func upsertAttachmentToCloud(fileUrl: URL,
|
||||
success: @escaping (String) -> Swift.Void,
|
||||
failure: @escaping (Error) -> Swift.Void) {
|
||||
// We want to use a well-known record id and type for manifest files.
|
||||
upsertFileToCloud(fileUrl: fileUrl,
|
||||
recordName: manifestRecordName,
|
||||
recordType: manifestRecordType,
|
||||
success: success,
|
||||
failure: failure)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func upsertManifestFileToCloud(fileUrl: URL,
|
||||
success: @escaping (String) -> Swift.Void,
|
||||
failure: @escaping (Error) -> Swift.Void) {
|
||||
// We want to use a well-known record id and type for manifest files.
|
||||
upsertFileToCloud(fileUrl: fileUrl,
|
||||
recordName: manifestRecordName,
|
||||
recordType: manifestRecordType,
|
||||
success: success,
|
||||
failure: failure)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func saveFileToCloud(fileUrl: URL,
|
||||
recordName: String,
|
||||
recordType: String,
|
||||
success: @escaping (String) -> Swift.Void,
|
||||
failure: @escaping (Error) -> Swift.Void) {
|
||||
let recordID = CKRecordID(recordName: recordName)
|
||||
let record = CKRecord(recordType: recordType, recordID: recordID)
|
||||
let asset = CKAsset(fileURL: fileUrl)
|
||||
record[payloadKey] = asset
|
||||
|
||||
saveRecordToCloud(record: record,
|
||||
success: success,
|
||||
failure: failure)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func saveRecordToCloud(record: CKRecord,
|
||||
success: @escaping (String) -> Swift.Void,
|
||||
failure: @escaping (Error) -> Swift.Void) {
|
||||
|
||||
let myContainer = CKContainer.default()
|
||||
let privateDatabase = myContainer.privateCloudDatabase
|
||||
privateDatabase.save(record) {
|
||||
(record, error) in
|
||||
|
||||
if let error = error {
|
||||
Logger.error("\(self.logTag) error saving record: \(error)")
|
||||
failure(error)
|
||||
} else {
|
||||
guard let recordName = record?.recordID.recordName else {
|
||||
Logger.error("\(self.logTag) error retrieving saved record's name.")
|
||||
failure(OWSErrorWithCodeDescription(.exportBackupError,
|
||||
NSLocalizedString("BACKUP_EXPORT_ERROR_SAVE_FILE_TO_CLOUD_FAILED",
|
||||
comment: "Error indicating the a backup export failed to save a file to the cloud.")))
|
||||
return
|
||||
}
|
||||
Logger.info("\(self.logTag) saved record.")
|
||||
success(recordName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func upsertFileToCloud(fileUrl: URL,
|
||||
recordName: String,
|
||||
recordType: String,
|
||||
success: @escaping (String) -> Swift.Void,
|
||||
failure: @escaping (Error) -> Swift.Void) {
|
||||
let recordId = CKRecordID(recordName: recordName)
|
||||
let fetchOperation = CKFetchRecordsOperation(recordIDs: [recordId ])
|
||||
// Don't download the file; we're just using the fetch to check whether or
|
||||
// not this record already exists.
|
||||
fetchOperation.desiredKeys = []
|
||||
fetchOperation.perRecordCompletionBlock = { (record, recordId, error) in
|
||||
if let error = error {
|
||||
if let ckerror = error as? CKError {
|
||||
if ckerror.code == .unknownItem {
|
||||
// No record found to update, saving new record.
|
||||
saveFileToCloud(fileUrl: fileUrl,
|
||||
recordName: recordName,
|
||||
recordType: recordType,
|
||||
success: success,
|
||||
failure: failure)
|
||||
return
|
||||
}
|
||||
Logger.error("\(self.logTag) error fetching record: \(error) \(ckerror.code).")
|
||||
} else {
|
||||
Logger.error("\(self.logTag) error fetching record: \(error).")
|
||||
}
|
||||
failure(error)
|
||||
return
|
||||
}
|
||||
guard let record = record else {
|
||||
Logger.error("\(self.logTag) error missing record.")
|
||||
Logger.flush()
|
||||
failure(OWSErrorWithCodeDescription(.exportBackupError,
|
||||
NSLocalizedString("BACKUP_EXPORT_ERROR_SAVE_FILE_TO_CLOUD_FAILED",
|
||||
comment: "Error indicating the a backup export failed to save a file to the cloud.")))
|
||||
return
|
||||
}
|
||||
Logger.verbose("\(self.logTag) updating record.")
|
||||
let asset = CKAsset(fileURL: fileUrl)
|
||||
record[payloadKey] = asset
|
||||
saveRecordToCloud(record: record,
|
||||
success: success,
|
||||
failure: failure)
|
||||
}
|
||||
let myContainer = CKContainer.default()
|
||||
let privateDatabase = myContainer.privateCloudDatabase
|
||||
privateDatabase.add(fetchOperation)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func saveFileOnceToCloud(recordName: String,
|
||||
recordType: String,
|
||||
fileUrlBlock: @escaping (Swift.Void) -> URL?,
|
||||
success: @escaping (String) -> Swift.Void,
|
||||
failure: @escaping (Error) -> Swift.Void) {
|
||||
let recordId = CKRecordID(recordName: recordName)
|
||||
let fetchOperation = CKFetchRecordsOperation(recordIDs: [recordId ])
|
||||
// Don't download the file; we're just using the fetch to check whether or
|
||||
// not this record already exists.
|
||||
fetchOperation.desiredKeys = []
|
||||
fetchOperation.perRecordCompletionBlock = { (record, recordId, error) in
|
||||
if let error = error {
|
||||
if let ckerror = error as? CKError {
|
||||
if ckerror.code == .unknownItem {
|
||||
// No record found to update, saving new record.
|
||||
|
||||
guard let fileUrl = fileUrlBlock() else {
|
||||
Logger.error("\(self.logTag) error preparing file for upload: \(error).")
|
||||
return
|
||||
}
|
||||
|
||||
saveFileToCloud(fileUrl: fileUrl,
|
||||
recordName: recordName,
|
||||
recordType: recordType,
|
||||
success: success,
|
||||
failure: failure)
|
||||
return
|
||||
}
|
||||
Logger.error("\(self.logTag) error fetching record: \(error) \(ckerror.code).")
|
||||
} else {
|
||||
Logger.error("\(self.logTag) error fetching record: \(error).")
|
||||
}
|
||||
failure(error)
|
||||
return
|
||||
}
|
||||
Logger.info("\(self.logTag) record already exists; skipping save.")
|
||||
success(recordName)
|
||||
}
|
||||
let myContainer = CKContainer.default()
|
||||
let privateDatabase = myContainer.privateCloudDatabase
|
||||
privateDatabase.add(fetchOperation)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func checkCloudKitAccess(completion: @escaping (Bool) -> Swift.Void) {
|
||||
CKContainer.default().accountStatus(completionHandler: { (accountStatus, error) in
|
||||
DispatchQueue.main.async {
|
||||
switch accountStatus {
|
||||
case .couldNotDetermine:
|
||||
Logger.error("\(self.logTag) could not determine CloudKit account status:\(String(describing: error)).")
|
||||
OWSAlerts.showErrorAlert(withMessage: NSLocalizedString("CLOUDKIT_STATUS_COULD_NOT_DETERMINE", comment: "Error indicating that the app could not determine that user's CloudKit account status"))
|
||||
completion(false)
|
||||
case .noAccount:
|
||||
Logger.error("\(self.logTag) no CloudKit account.")
|
||||
OWSAlerts.showErrorAlert(withMessage: NSLocalizedString("CLOUDKIT_STATUS_NO_ACCOUNT", comment: "Error indicating that user does not have an iCloud account."))
|
||||
completion(false)
|
||||
case .restricted:
|
||||
Logger.error("\(self.logTag) restricted CloudKit account.")
|
||||
OWSAlerts.showErrorAlert(withMessage: NSLocalizedString("CLOUDKIT_STATUS_RESTRICTED", comment: "Error indicating that the app was prevented from accessing the user's CloudKit account."))
|
||||
completion(false)
|
||||
case .available:
|
||||
completion(true)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
42
Signal/src/util/OWSBackupExport.h
Normal file
42
Signal/src/util/OWSBackupExport.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class OWSBackupExport;
|
||||
|
||||
@protocol OWSBackupExportDelegate <NSObject>
|
||||
|
||||
// TODO: This should eventually be the backup key stored in the Signal Service
|
||||
// and retrieved with the backup PIN.
|
||||
- (nullable NSData *)backupKey;
|
||||
|
||||
// Either backupExportDidSucceed:... or backupExportDidFail:... will
|
||||
// be called exactly once on the main thread UNLESS:
|
||||
//
|
||||
// * The export was never started.
|
||||
// * The export was cancelled.
|
||||
- (void)backupExportDidSucceed:(OWSBackupExport *)backupExport;
|
||||
- (void)backupExportDidFail:(OWSBackupExport *)backupExport error:(NSError *)error;
|
||||
|
||||
@end
|
||||
|
||||
//#pragma mark -
|
||||
|
||||
@class OWSPrimaryStorage;
|
||||
|
||||
@interface OWSBackupExport : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initWithDelegate:(id<OWSBackupExportDelegate>)delegate
|
||||
primaryStorage:(OWSPrimaryStorage *)primaryStorage;
|
||||
|
||||
- (void)startAsync;
|
||||
|
||||
- (void)cancel;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
601
Signal/src/util/OWSBackupExport.m
Normal file
601
Signal/src/util/OWSBackupExport.m
Normal file
|
@ -0,0 +1,601 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSBackupExport.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import "zlib.h"
|
||||
#import <Curve25519Kit/Randomness.h>
|
||||
#import <SSZipArchive/SSZipArchive.h>
|
||||
#import <SignalServiceKit/NSDate+OWS.h>
|
||||
#import <SignalServiceKit/OWSBackgroundTask.h>
|
||||
#import <SignalServiceKit/OWSBackupStorage.h>
|
||||
#import <SignalServiceKit/OWSError.h>
|
||||
#import <SignalServiceKit/OWSFileSystem.h>
|
||||
#import <SignalServiceKit/TSAttachmentStream.h>
|
||||
#import <SignalServiceKit/TSMessage.h>
|
||||
#import <SignalServiceKit/TSThread.h>
|
||||
#import <SignalServiceKit/Threading.h>
|
||||
#import <SignalServiceKit/YapDatabaseConnection+OWS.h>
|
||||
#import <YapDatabase/YapDatabase.h>
|
||||
#import <YapDatabase/YapDatabaseCryptoUtils.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef void (^OWSBackupExportBoolCompletion)(BOOL success);
|
||||
typedef void (^OWSBackupExportCompletion)(NSError *_Nullable error);
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface OWSAttachmentExport : NSObject
|
||||
|
||||
@property (nonatomic) NSString *exportDirPath;
|
||||
@property (nonatomic) NSString *attachmentId;
|
||||
@property (nonatomic) NSString *attachmentFilePath;
|
||||
@property (nonatomic, nullable) NSString *tempFilePath;
|
||||
@property (nonatomic, nullable) NSString *relativeFilePath;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation OWSAttachmentExport
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
// Surface memory leaks by logging the deallocation.
|
||||
DDLogVerbose(@"Dealloc: %@", self.class);
|
||||
|
||||
// Delete temporary file ASAP.
|
||||
if (self.tempFilePath) {
|
||||
[OWSFileSystem deleteFileIfExists:self.tempFilePath];
|
||||
}
|
||||
}
|
||||
|
||||
// On success, tempFilePath will be non-nil.
|
||||
- (void)prepareForUpload
|
||||
{
|
||||
OWSAssert(self.exportDirPath.length > 0);
|
||||
OWSAssert(self.attachmentId.length > 0);
|
||||
OWSAssert(self.attachmentFilePath.length > 0);
|
||||
|
||||
NSString *attachmentsDirPath = [TSAttachmentStream attachmentsFolder];
|
||||
if (![self.attachmentFilePath hasPrefix:attachmentsDirPath]) {
|
||||
DDLogError(@"%@ attachment has unexpected path.", self.logTag);
|
||||
OWSFail(@"%@ attachment has unexpected path: %@", self.logTag, self.attachmentFilePath);
|
||||
return;
|
||||
}
|
||||
NSString *relativeFilePath = [self.attachmentFilePath substringFromIndex:attachmentsDirPath.length];
|
||||
NSString *pathSeparator = @"/";
|
||||
if ([relativeFilePath hasPrefix:pathSeparator]) {
|
||||
relativeFilePath = [relativeFilePath substringFromIndex:pathSeparator.length];
|
||||
}
|
||||
self.relativeFilePath = relativeFilePath;
|
||||
|
||||
NSString *_Nullable tempFilePath = [self encryptAsTempFile:self.attachmentFilePath];
|
||||
if (!tempFilePath) {
|
||||
DDLogError(@"%@ attachment could not be encrypted.", self.logTag);
|
||||
OWSFail(@"%@ attachment could not be encrypted: %@", self.logTag, self.attachmentFilePath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
- (nullable NSString *)encryptAsTempFile:(NSString *)srcFilePath
|
||||
{
|
||||
OWSAssert(self.exportDirPath.length > 0);
|
||||
|
||||
// TODO: Encrypt the file using self.delegate.backupKey;
|
||||
|
||||
NSString *dstFilePath = [self.exportDirPath stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSError *error;
|
||||
BOOL success = [fileManager copyItemAtPath:srcFilePath toPath:dstFilePath error:&error];
|
||||
if (!success || error) {
|
||||
OWSProdLogAndFail(@"%@ error writing encrypted file: %@", self.logTag, error);
|
||||
return nil;
|
||||
}
|
||||
return dstFilePath;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface OWSBackupExport () <SSZipArchiveDelegate>
|
||||
|
||||
@property (nonatomic, weak) id<OWSBackupExportDelegate> delegate;
|
||||
|
||||
@property (nonatomic, nullable) YapDatabaseConnection *srcDBConnection;
|
||||
|
||||
@property (nonatomic, nullable) YapDatabaseConnection *dstDBConnection;
|
||||
|
||||
// Indicates that the backup succeeded, failed or was cancelled.
|
||||
@property (atomic) BOOL isComplete;
|
||||
|
||||
@property (nonatomic, nullable) OWSBackupStorage *backupStorage;
|
||||
|
||||
@property (nonatomic, nullable) NSData *databaseSalt;
|
||||
|
||||
@property (nonatomic, nullable) OWSBackgroundTask *backgroundTask;
|
||||
|
||||
@property (nonatomic) NSMutableArray<NSString *> *databaseFilePaths;
|
||||
// A map of "record name"-to-"file name".
|
||||
@property (nonatomic) NSMutableDictionary<NSString *, NSString *> *databaseRecordMap;
|
||||
|
||||
// A map of "attachment id"-to-"local file path".
|
||||
@property (nonatomic) NSMutableDictionary<NSString *, NSString *> *attachmentFilePathMap;
|
||||
// A map of "record name"-to-"file relative path".
|
||||
@property (nonatomic) NSMutableDictionary<NSString *, NSString *> *attachmentRecordMap;
|
||||
|
||||
@property (nonatomic, nullable) NSString *manifestFilePath;
|
||||
@property (nonatomic, nullable) NSString *manifestRecordName;
|
||||
|
||||
@property (nonatomic) NSString *exportDirPath;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation OWSBackupExport
|
||||
|
||||
- (instancetype)initWithDelegate:(id<OWSBackupExportDelegate>)delegate
|
||||
primaryStorage:(OWSPrimaryStorage *)primaryStorage
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
OWSAssert(primaryStorage);
|
||||
OWSAssert([OWSStorage isStorageReady]);
|
||||
|
||||
self.delegate = delegate;
|
||||
_srcDBConnection = primaryStorage.newDatabaseConnection;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
// Surface memory leaks by logging the deallocation.
|
||||
DDLogVerbose(@"Dealloc: %@", self.class);
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
if (self.exportDirPath) {
|
||||
[OWSFileSystem deleteFileIfExists:self.exportDirPath];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)startAsync
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
|
||||
|
||||
self.backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__];
|
||||
|
||||
__weak OWSBackupExport *weakSelf = self;
|
||||
[OWSBackupAPI checkCloudKitAccessWithCompletion:^(BOOL hasAccess) {
|
||||
if (hasAccess) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
[weakSelf start];
|
||||
});
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)start
|
||||
{
|
||||
__weak OWSBackupExport *weakSelf = self;
|
||||
[self configureExport:^(BOOL success) {
|
||||
if (!success) {
|
||||
[self failWithErrorDescription:
|
||||
NSLocalizedString(@"BACKUP_EXPORT_ERROR_COULD_NOT_EXPORT",
|
||||
@"Error indicating the a backup export could not export the user's data.")];
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.isComplete) {
|
||||
return;
|
||||
}
|
||||
if (![self exportDatabase]) {
|
||||
[self failWithErrorDescription:
|
||||
NSLocalizedString(@"BACKUP_EXPORT_ERROR_COULD_NOT_EXPORT",
|
||||
@"Error indicating the a backup export could not export the user's data.")];
|
||||
return;
|
||||
}
|
||||
if (self.isComplete) {
|
||||
return;
|
||||
}
|
||||
[self saveToCloud:^(NSError *_Nullable error) {
|
||||
if (error) {
|
||||
[weakSelf failWithError:error];
|
||||
} else {
|
||||
[weakSelf succeed];
|
||||
}
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)configureExport:(OWSBackupExportBoolCompletion)completion
|
||||
{
|
||||
DDLogVerbose(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
|
||||
|
||||
NSString *temporaryDirectory = NSTemporaryDirectory();
|
||||
self.exportDirPath = [temporaryDirectory stringByAppendingString:[NSUUID UUID].UUIDString];
|
||||
NSString *exportDatabaseDirPath = [self.exportDirPath stringByAppendingPathComponent:@"Database"];
|
||||
self.databaseSalt = [Randomness generateRandomBytes:(int)kSQLCipherSaltLength];
|
||||
|
||||
if (![OWSFileSystem ensureDirectoryExists:self.exportDirPath]) {
|
||||
OWSProdLogAndFail(@"%@ Could not create exportDirPath.", self.logTag);
|
||||
return completion(NO);
|
||||
}
|
||||
if (![OWSFileSystem ensureDirectoryExists:exportDatabaseDirPath]) {
|
||||
OWSProdLogAndFail(@"%@ Could not create exportDatabaseDirPath.", self.logTag);
|
||||
return completion(NO);
|
||||
}
|
||||
if (!self.databaseSalt) {
|
||||
OWSProdLogAndFail(@"%@ Could not create databaseSalt.", self.logTag);
|
||||
return completion(NO);
|
||||
}
|
||||
__weak OWSBackupExport *weakSelf = self;
|
||||
BackupStorageKeySpecBlock keySpecBlock = ^{
|
||||
NSData *_Nullable backupKey = [weakSelf.delegate backupKey];
|
||||
if (!backupKey) {
|
||||
return (NSData *)nil;
|
||||
}
|
||||
NSData *_Nullable databaseSalt = weakSelf.databaseSalt;
|
||||
if (!databaseSalt) {
|
||||
return (NSData *)nil;
|
||||
}
|
||||
OWSCAssert(backupKey.length > 0);
|
||||
NSData *_Nullable keySpec =
|
||||
[YapDatabaseCryptoUtils deriveDatabaseKeySpecForPassword:backupKey saltData:databaseSalt];
|
||||
return keySpec;
|
||||
};
|
||||
self.backupStorage =
|
||||
[[OWSBackupStorage alloc] initBackupStorageWithDatabaseDirPath:exportDatabaseDirPath keySpecBlock:keySpecBlock];
|
||||
if (!self.backupStorage) {
|
||||
OWSProdLogAndFail(@"%@ Could not create backupStorage.", self.logTag);
|
||||
return completion(NO);
|
||||
}
|
||||
_dstDBConnection = self.backupStorage.newDatabaseConnection;
|
||||
if (!self.dstDBConnection) {
|
||||
OWSProdLogAndFail(@"%@ Could not create dstDBConnection.", self.logTag);
|
||||
return completion(NO);
|
||||
}
|
||||
|
||||
// TODO: Do we really need to run these registrations on the main thread?
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.backupStorage runSyncRegistrations];
|
||||
[self.backupStorage runAsyncRegistrationsWithCompletion:^{
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
completion(YES);
|
||||
});
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
- (BOOL)exportDatabase
|
||||
{
|
||||
DDLogVerbose(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
|
||||
|
||||
__block unsigned long long copiedThreads = 0;
|
||||
__block unsigned long long copiedInteractions = 0;
|
||||
__block unsigned long long copiedEntities = 0;
|
||||
__block unsigned long long copiedAttachments = 0;
|
||||
|
||||
self.attachmentFilePathMap = [NSMutableDictionary new];
|
||||
|
||||
[self.srcDBConnection readWithBlock:^(YapDatabaseReadTransaction *srcTransaction) {
|
||||
[self.dstDBConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *dstTransaction) {
|
||||
// Copy threads.
|
||||
[srcTransaction
|
||||
enumerateKeysAndObjectsInCollection:[TSThread collection]
|
||||
usingBlock:^(NSString *key, id object, BOOL *stop) {
|
||||
if (self.isComplete) {
|
||||
*stop = YES;
|
||||
return;
|
||||
}
|
||||
if (![object isKindOfClass:[TSThread class]]) {
|
||||
OWSProdLogAndFail(
|
||||
@"%@ unexpected class: %@", self.logTag, [object class]);
|
||||
return;
|
||||
}
|
||||
TSThread *thread = object;
|
||||
[thread saveWithTransaction:dstTransaction];
|
||||
copiedThreads++;
|
||||
copiedEntities++;
|
||||
}];
|
||||
|
||||
// Copy interactions.
|
||||
[srcTransaction
|
||||
enumerateKeysAndObjectsInCollection:[TSInteraction collection]
|
||||
usingBlock:^(NSString *key, id object, BOOL *stop) {
|
||||
if (self.isComplete) {
|
||||
*stop = YES;
|
||||
return;
|
||||
}
|
||||
if (![object isKindOfClass:[TSInteraction class]]) {
|
||||
OWSProdLogAndFail(
|
||||
@"%@ unexpected class: %@", self.logTag, [object class]);
|
||||
return;
|
||||
}
|
||||
// Ignore disappearing messages.
|
||||
if ([object isKindOfClass:[TSMessage class]]) {
|
||||
TSMessage *message = object;
|
||||
if (message.isExpiringMessage) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
TSInteraction *interaction = object;
|
||||
// Ignore dynamic interactions.
|
||||
if (interaction.isDynamicInteraction) {
|
||||
return;
|
||||
}
|
||||
[interaction saveWithTransaction:dstTransaction];
|
||||
copiedInteractions++;
|
||||
copiedEntities++;
|
||||
}];
|
||||
|
||||
// Copy attachments.
|
||||
[srcTransaction
|
||||
enumerateKeysAndObjectsInCollection:[TSAttachmentStream collection]
|
||||
usingBlock:^(NSString *key, id object, BOOL *stop) {
|
||||
if (self.isComplete) {
|
||||
*stop = YES;
|
||||
return;
|
||||
}
|
||||
if (![object isKindOfClass:[TSAttachment class]]) {
|
||||
OWSProdLogAndFail(
|
||||
@"%@ unexpected class: %@", self.logTag, [object class]);
|
||||
return;
|
||||
}
|
||||
if ([object isKindOfClass:[TSAttachmentStream class]]) {
|
||||
TSAttachmentStream *attachmentStream = object;
|
||||
NSString *_Nullable filePath = attachmentStream.filePath;
|
||||
if (filePath) {
|
||||
OWSAssert(attachmentStream.uniqueId.length > 0);
|
||||
self.attachmentFilePathMap[attachmentStream.uniqueId] = filePath;
|
||||
}
|
||||
}
|
||||
TSAttachment *attachment = object;
|
||||
[attachment saveWithTransaction:dstTransaction];
|
||||
copiedAttachments++;
|
||||
copiedEntities++;
|
||||
}];
|
||||
}];
|
||||
}];
|
||||
|
||||
// TODO: Should we do a database checkpoint?
|
||||
|
||||
DDLogInfo(@"%@ copiedThreads: %llu", self.logTag, copiedThreads);
|
||||
DDLogInfo(@"%@ copiedMessages: %llu", self.logTag, copiedInteractions);
|
||||
DDLogInfo(@"%@ copiedEntities: %llu", self.logTag, copiedEntities);
|
||||
DDLogInfo(@"%@ copiedAttachments: %llu", self.logTag, copiedAttachments);
|
||||
|
||||
[self.backupStorage logFileSizes];
|
||||
|
||||
// Capture the list of files to save.
|
||||
self.databaseFilePaths = [@[
|
||||
self.backupStorage.databaseFilePath,
|
||||
self.backupStorage.databaseFilePath_WAL,
|
||||
self.backupStorage.databaseFilePath_SHM,
|
||||
] mutableCopy];
|
||||
|
||||
// Close the database.
|
||||
self.dstDBConnection = nil;
|
||||
self.backupStorage = nil;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)saveToCloud:(OWSBackupExportCompletion)completion
|
||||
{
|
||||
DDLogVerbose(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
|
||||
|
||||
self.databaseRecordMap = [NSMutableDictionary new];
|
||||
self.attachmentRecordMap = [NSMutableDictionary new];
|
||||
|
||||
[self saveNextFileToCloud:completion];
|
||||
}
|
||||
|
||||
- (void)saveNextFileToCloud:(OWSBackupExportCompletion)completion
|
||||
{
|
||||
if (self.isComplete) {
|
||||
return;
|
||||
}
|
||||
|
||||
__weak OWSBackupExport *weakSelf = self;
|
||||
|
||||
if (self.databaseFilePaths.count > 0) {
|
||||
NSString *filePath = self.databaseFilePaths.lastObject;
|
||||
[self.databaseFilePaths removeLastObject];
|
||||
// Database files are encrypted and can be safely stored unencrypted in the cloud.
|
||||
// TODO: Security review.
|
||||
[OWSBackupAPI saveEphemeralDatabaseFileToCloudWithFileUrl:[NSURL fileURLWithPath:filePath]
|
||||
success:^(NSString *recordName) {
|
||||
// Ensure that we continue to perform the backup export
|
||||
// off the main thread.
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
OWSBackupExport *strongSelf = weakSelf;
|
||||
if (!strongSelf) {
|
||||
return;
|
||||
}
|
||||
strongSelf.databaseRecordMap[recordName] = [filePath lastPathComponent];
|
||||
[strongSelf saveNextFileToCloud:completion];
|
||||
});
|
||||
}
|
||||
failure:^(NSError *error) {
|
||||
// Database files are critical so any error uploading them is unrecoverable.
|
||||
completion(error);
|
||||
}];
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.attachmentFilePathMap.count > 0) {
|
||||
NSString *attachmentId = self.attachmentFilePathMap.allKeys.lastObject;
|
||||
NSString *attachmentFilePath = self.attachmentFilePathMap[attachmentId];
|
||||
[self.attachmentFilePathMap removeObjectForKey:attachmentId];
|
||||
|
||||
// OWSAttachmentExport is used to lazily write an encrypted copy of the
|
||||
// attachment to disk.
|
||||
OWSAttachmentExport *attachmentExport = [OWSAttachmentExport new];
|
||||
attachmentExport.exportDirPath = self.exportDirPath;
|
||||
attachmentExport.attachmentId = attachmentId;
|
||||
attachmentExport.attachmentFilePath = attachmentFilePath;
|
||||
|
||||
[OWSBackupAPI savePersistentFileOnceToCloudWithFileId:attachmentId
|
||||
fileUrlBlock:^{
|
||||
[attachmentExport prepareForUpload];
|
||||
if (attachmentExport.tempFilePath.length < 1 || attachmentExport.relativeFilePath.length < 1) {
|
||||
return (NSURL *)nil;
|
||||
}
|
||||
return [NSURL fileURLWithPath:attachmentExport.tempFilePath];
|
||||
}
|
||||
success:^(NSString *recordName) {
|
||||
// Ensure that we continue to perform the backup export
|
||||
// off the main thread.
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
OWSBackupExport *strongSelf = weakSelf;
|
||||
if (!strongSelf) {
|
||||
return;
|
||||
}
|
||||
strongSelf.attachmentRecordMap[recordName] = attachmentExport.relativeFilePath;
|
||||
[strongSelf saveNextFileToCloud:completion];
|
||||
});
|
||||
}
|
||||
failure:^(NSError *error) {
|
||||
// Ensure that we continue to perform the backup export
|
||||
// off the main thread.
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
// Attachment files are non-critical so any error uploading them is recoverable.
|
||||
[weakSelf saveNextFileToCloud:completion];
|
||||
});
|
||||
}];
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self.manifestFilePath) {
|
||||
if (![self writeManifestFile]) {
|
||||
completion(OWSErrorWithCodeDescription(OWSErrorCodeExportBackupFailed,
|
||||
NSLocalizedString(@"BACKUP_EXPORT_ERROR_COULD_NOT_EXPORT",
|
||||
@"Error indicating the a backup export could not export the user's data.")));
|
||||
return;
|
||||
}
|
||||
OWSAssert(self.manifestFilePath);
|
||||
|
||||
[OWSBackupAPI upsertManifestFileToCloudWithFileUrl:[NSURL fileURLWithPath:self.manifestFilePath]
|
||||
success:^(NSString *recordName) {
|
||||
// Ensure that we continue to perform the backup export
|
||||
// off the main thread.
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
OWSBackupExport *strongSelf = weakSelf;
|
||||
if (!strongSelf) {
|
||||
return;
|
||||
}
|
||||
strongSelf.manifestRecordName = recordName;
|
||||
[strongSelf saveNextFileToCloud:completion];
|
||||
});
|
||||
}
|
||||
failure:^(NSError *error) {
|
||||
// The manifest file is critical so any error uploading them is unrecoverable.
|
||||
completion(error);
|
||||
}];
|
||||
return;
|
||||
}
|
||||
|
||||
// All files have been saved to the cloud.
|
||||
completion(nil);
|
||||
}
|
||||
|
||||
- (nullable NSString *)encryptAsTempFile:(NSString *)srcFilePath
|
||||
{
|
||||
OWSAssert(self.exportDirPath.length > 0);
|
||||
|
||||
// TODO: Encrypt the file using self.delegate.backupKey;
|
||||
|
||||
NSString *dstFilePath = [self.exportDirPath stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSError *error;
|
||||
BOOL success = [fileManager copyItemAtPath:srcFilePath toPath:dstFilePath error:&error];
|
||||
if (!success || error) {
|
||||
OWSProdLogAndFail(@"%@ error writing encrypted file: %@", self.logTag, error);
|
||||
return nil;
|
||||
}
|
||||
return dstFilePath;
|
||||
}
|
||||
|
||||
- (BOOL)writeManifestFile
|
||||
{
|
||||
OWSAssert(self.databaseRecordMap.count > 0);
|
||||
OWSAssert(self.attachmentRecordMap);
|
||||
OWSAssert(self.exportDirPath.length > 0);
|
||||
|
||||
NSDictionary *json = @{
|
||||
@"database_files" : self.databaseRecordMap,
|
||||
@"attachment_files" : self.attachmentRecordMap,
|
||||
};
|
||||
NSError *error;
|
||||
NSData *_Nullable jsonData =
|
||||
[NSJSONSerialization dataWithJSONObject:json options:NSJSONWritingPrettyPrinted error:&error];
|
||||
if (!jsonData || error) {
|
||||
OWSProdLogAndFail(@"%@ error encoding manifest file: %@", self.logTag, error);
|
||||
return NO;
|
||||
}
|
||||
// TODO: Encrypt the manifest.
|
||||
self.manifestFilePath = [self.exportDirPath stringByAppendingPathComponent:@"manifest.json"];
|
||||
if (![jsonData writeToFile:self.manifestFilePath atomically:YES]) {
|
||||
OWSProdLogAndFail(@"%@ error writing manifest file: %@", self.logTag, error);
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)cancel
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
// TODO:
|
||||
self.isComplete = YES;
|
||||
}
|
||||
|
||||
- (void)succeed
|
||||
{
|
||||
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (self.isComplete) {
|
||||
return;
|
||||
}
|
||||
self.isComplete = YES;
|
||||
[self.delegate backupExportDidSucceed:self];
|
||||
});
|
||||
// TODO:
|
||||
}
|
||||
|
||||
- (void)failWithErrorDescription:(NSString *)description
|
||||
{
|
||||
[self failWithError:OWSErrorWithCodeDescription(OWSErrorCodeExportBackupFailed, description)];
|
||||
}
|
||||
|
||||
- (void)failWithError:(NSError *)error
|
||||
{
|
||||
OWSProdLogAndFail(@"%@ %s %@", self.logTag, __PRETTY_FUNCTION__, error);
|
||||
|
||||
// TODO:
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (self.isComplete) {
|
||||
return;
|
||||
}
|
||||
self.isComplete = YES;
|
||||
[self.delegate backupExportDidFail:self error:error];
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -163,7 +163,8 @@
|
|||
/* Message indicating that backup export is complete. */
|
||||
"BACKUP_EXPORT_COMPLETE_MESSAGE" = "Backup complete.";
|
||||
|
||||
/* Label for button that copies backup password to the pasteboard. */
|
||||
/* Label for button that copies backup password to the
|
||||
// pasteboard. */
|
||||
"BACKUP_EXPORT_COPY_PASSWORD_BUTTON" = "Copy Password";
|
||||
|
||||
/* Message indicating that backup export failed. */
|
||||
|
@ -175,10 +176,12 @@
|
|||
/* Format for message indicating that backup export is complete. Embeds: {{the backup password}}. */
|
||||
"BACKUP_EXPORT_PASSWORD_MESSAGE_FORMAT" = "Your backup password is: %@. Make sure to keep a copy of this password or you won't be able to restore from this backup.";
|
||||
|
||||
/* Label for button that 'send backup' in the current conversation. */
|
||||
/* Label for button that 'send backup' in the current
|
||||
// conversation. */
|
||||
"BACKUP_EXPORT_SEND_BACKUP_BUTTON" = "Send Backup as Message";
|
||||
|
||||
/* Message indicating that sending the backup failed. */
|
||||
/* Message indicating that sending
|
||||
// the backup failed. */
|
||||
"BACKUP_EXPORT_SEND_BACKUP_FAILED" = "Sending Backup Failed.";
|
||||
|
||||
/* Message indicating that sending the backup succeeded. */
|
||||
|
@ -187,36 +190,13 @@
|
|||
/* Label for button that opens share UI for backup. */
|
||||
"BACKUP_EXPORT_SHARE_BACKUP_BUTTON" = "Share Backup";
|
||||
|
||||
/* Title for the 'backup export' view. */
|
||||
/* Title for the 'backup export'
|
||||
// view. */
|
||||
"BACKUP_EXPORT_VIEW_TITLE" = "Backup";
|
||||
|
||||
/* Format for backup filenames. Embeds: {{the date and time of the backup}}. Should not include characters like slash (/ or \\) or colon (:). */
|
||||
"BACKUP_FILENAME_FORMAT" = "Signal Backup %@";
|
||||
|
||||
/* Message indicating that backup import is complete. */
|
||||
"BACKUP_IMPORT_COMPLETE_MESSAGE" = "Restore Complete";
|
||||
|
||||
/* Label for button confirming backup import. */
|
||||
"BACKUP_IMPORT_CONFIRM_ALERT_BUTTON" = "Restore";
|
||||
|
||||
/* Message for alert confirming backup import. */
|
||||
"BACKUP_IMPORT_CONFIRM_ALERT_MESSAGE" = "To restore this backup you must restart the Signal app. Warning: you will lose all of your current Signal data.";
|
||||
|
||||
/* Title for alert confirming backup import. */
|
||||
"BACKUP_IMPORT_CONFIRM_ALERT_TITLE" = "Restore Backup?";
|
||||
|
||||
/* Message indicating that backup import failed. */
|
||||
"BACKUP_IMPORT_FAILED_MESSAGE" = "Restore Failed";
|
||||
|
||||
/* Message indicating that backup import is in progress. */
|
||||
"BACKUP_IMPORT_IN_PROGRESS_MESSAGE" = "Restoring Backup...";
|
||||
|
||||
/* Label for button that restarts app to complete restore. */
|
||||
"BACKUP_IMPORT_RESTART_BUTTON" = "Restart App";
|
||||
|
||||
/* Title for the 'backup import' view. */
|
||||
"BACKUP_IMPORT_VIEW_TITLE" = "Restore Backup";
|
||||
|
||||
/* An explanation of the consequences of blocking another user. */
|
||||
"BLOCK_BEHAVIOR_EXPLANATION" = "Blocked users will not be able to call you or send you messages.";
|
||||
|
||||
|
@ -1603,6 +1583,12 @@
|
|||
/* Format string for the default 'Note' sound. Embeds the system {{sound name}}. */
|
||||
"SETTINGS_AUDIO_DEFAULT_TONE_LABEL_FORMAT" = "%@ (default)";
|
||||
|
||||
/* Label for the backup view in app settings. */
|
||||
"SETTINGS_BACKUP" = "Backup";
|
||||
|
||||
/* Label for switch in settings that controls whether or not backup is enabled. */
|
||||
"SETTINGS_BACKUP_ENABLING_SWITCH" = "Backup Enabled";
|
||||
|
||||
/* A label for the 'add phone number' button in the block list table. */
|
||||
"SETTINGS_BLOCK_LIST_ADD_BUTTON" = "Add…";
|
||||
|
||||
|
|
|
@ -338,10 +338,8 @@ NSString *const kSelectRecipientViewControllerCellIdentifier = @"kSelectRecipien
|
|||
[modalActivityIndicator
|
||||
dismissViewControllerAnimated:NO
|
||||
completion:^{
|
||||
[OWSAlerts showAlertWithTitle:
|
||||
NSLocalizedString(@"ALERT_ERROR_TITLE",
|
||||
@"Title for a generic error alert.")
|
||||
message:error.localizedDescription];
|
||||
[OWSAlerts
|
||||
showErrorAlertWithMessage:error.localizedDescription];
|
||||
}];
|
||||
}];
|
||||
}];
|
||||
|
|
|
@ -132,8 +132,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
if ([error.domain isEqualToString:NSOSStatusErrorDomain]
|
||||
&& (error.code == kAudioFileInvalidFileError || error.code == kAudioFileStreamError_InvalidFile)) {
|
||||
[OWSAlerts showAlertWithTitle:NSLocalizedString(@"ALERT_ERROR_TITLE", @"")
|
||||
message:NSLocalizedString(@"INVALID_AUDIO_FILE_ALERT_ERROR_MESSAGE",
|
||||
[OWSAlerts
|
||||
showErrorAlertWithMessage:NSLocalizedString(@"INVALID_AUDIO_FILE_ALERT_ERROR_MESSAGE",
|
||||
@"Message for the alert indicating that an audio file is invalid.")];
|
||||
}
|
||||
|
||||
|
|
|
@ -12,11 +12,13 @@ import Foundation
|
|||
@objc
|
||||
static public let dismissButton = NSLocalizedString("DISMISS_BUTTON_TEXT", comment: "Short text to dismiss current modal / actionsheet / screen")
|
||||
@objc
|
||||
static public let cancelButton = NSLocalizedString("TXT_CANCEL_TITLE", comment:"Label for the cancel button in an alert or action sheet.")
|
||||
static public let cancelButton = NSLocalizedString("TXT_CANCEL_TITLE", comment: "Label for the cancel button in an alert or action sheet.")
|
||||
@objc
|
||||
static public let retryButton = NSLocalizedString("RETRY_BUTTON_TEXT", comment:"Generic text for button that retries whatever the last action was.")
|
||||
static public let retryButton = NSLocalizedString("RETRY_BUTTON_TEXT", comment: "Generic text for button that retries whatever the last action was.")
|
||||
@objc
|
||||
static public let openSettingsButton = NSLocalizedString("OPEN_SETTINGS_BUTTON", comment: "Button text which opens the settings app")
|
||||
@objc
|
||||
static public let errorAlertTitle = NSLocalizedString("ALERT_ERROR_TITLE", comment: "")
|
||||
}
|
||||
|
||||
@objc public class MessageStrings: NSObject {
|
||||
|
|
|
@ -54,6 +54,11 @@ import Foundation
|
|||
CurrentAppContext().frontmostViewController()?.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func showErrorAlert(withMessage message: String) {
|
||||
self.showAlert(title: CommonStrings.errorAlertTitle, message: message, buttonTitle: nil)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class var cancelAction: UIAlertAction {
|
||||
let action = UIAlertAction(title: CommonStrings.cancelButton, style: .cancel) { _ in
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
NSString *const kNSNotificationName_BlockedPhoneNumbersDidChange = @"kNSNotificationName_BlockedPhoneNumbersDidChange";
|
||||
extern NSString *const kNSNotificationName_BlockedPhoneNumbersDidChange;
|
||||
|
||||
NSString *const kOWSBlockingManager_BlockedPhoneNumbersCollection = @"kOWSBlockingManager_BlockedPhoneNumbersCollection";
|
||||
// This key is used to persist the current "blocked phone numbers" state.
|
||||
|
|
38
SignalServiceKit/src/Storage/OWSBackupStorage.h
Normal file
38
SignalServiceKit/src/Storage/OWSBackupStorage.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
#import "OWSPrimaryStorage.h"
|
||||
#import "OWSStorage.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NSData *_Nullable (^BackupStorageKeySpecBlock)(void);
|
||||
|
||||
@interface OWSBackupStorage : OWSStorage
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initStorage NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initBackupStorageWithDatabaseDirPath:(NSString *)databaseDirPath
|
||||
keySpecBlock:(BackupStorageKeySpecBlock)keySpecBlock NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (YapDatabaseConnection *)dbConnection;
|
||||
|
||||
- (void)logFileSizes;
|
||||
|
||||
- (void)runSyncRegistrations;
|
||||
- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion;
|
||||
- (BOOL)areAllRegistrationsComplete;
|
||||
|
||||
- (NSString *)databaseFilePath;
|
||||
- (NSString *)databaseFilePath_SHM;
|
||||
- (NSString *)databaseFilePath_WAL;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
160
SignalServiceKit/src/Storage/OWSBackupStorage.m
Normal file
160
SignalServiceKit/src/Storage/OWSBackupStorage.m
Normal file
|
@ -0,0 +1,160 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSBackupStorage.h"
|
||||
#import "OWSFileSystem.h"
|
||||
#import "OWSStorage+Subclass.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSBackupStorage ()
|
||||
|
||||
@property (atomic) BOOL areAsyncRegistrationsComplete;
|
||||
@property (atomic) BOOL areSyncRegistrationsComplete;
|
||||
|
||||
@property (nonatomic, readonly) NSString *databaseDirPath;
|
||||
@property (nonatomic, readonly) BackupStorageKeySpecBlock keySpecBlock;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation OWSBackupStorage
|
||||
|
||||
- (instancetype)initBackupStorageWithDatabaseDirPath:(NSString *)databaseDirPath
|
||||
keySpecBlock:(BackupStorageKeySpecBlock)keySpecBlock
|
||||
{
|
||||
OWSAssert(databaseDirPath.length > 0);
|
||||
OWSAssert(keySpecBlock);
|
||||
OWSAssert([OWSFileSystem ensureDirectoryExists:databaseDirPath]);
|
||||
|
||||
self = [super initStorage];
|
||||
|
||||
if (self) {
|
||||
_databaseDirPath = databaseDirPath;
|
||||
_keySpecBlock = keySpecBlock;
|
||||
|
||||
[self loadDatabase];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)loadDatabase
|
||||
{
|
||||
[super loadDatabase];
|
||||
|
||||
[self protectFiles];
|
||||
}
|
||||
|
||||
- (void)resetStorage
|
||||
{
|
||||
[super resetStorage];
|
||||
}
|
||||
|
||||
- (void)runSyncRegistrations
|
||||
{
|
||||
runSyncRegistrationsForStorage(self);
|
||||
|
||||
// See comments on OWSDatabaseConnection.
|
||||
//
|
||||
// In the absence of finding documentation that can shed light on the issue we've been
|
||||
// seeing, this issue only seems to affect sync and not async registrations. We've always
|
||||
// been opening write transactions before the async registrations complete without negative
|
||||
// consequences.
|
||||
OWSAssert(!self.areSyncRegistrationsComplete);
|
||||
self.areSyncRegistrationsComplete = YES;
|
||||
}
|
||||
|
||||
- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion
|
||||
{
|
||||
OWSAssert(completion);
|
||||
|
||||
runAsyncRegistrationsForStorage(self);
|
||||
|
||||
DDLogVerbose(@"%@ async registrations enqueued.", self.logTag);
|
||||
|
||||
// Block until all async registrations are complete.
|
||||
//
|
||||
// NOTE: This has to happen on the "registration connection" for this
|
||||
// database.
|
||||
YapDatabaseConnection *dbConnection = self.registrationConnection;
|
||||
OWSAssert(self.registrationConnection);
|
||||
[dbConnection flushTransactionsWithCompletionQueue:dispatch_get_main_queue()
|
||||
completionBlock:^{
|
||||
OWSAssert(!self.areAsyncRegistrationsComplete);
|
||||
|
||||
DDLogVerbose(@"%@ async registrations complete.", self.logTag);
|
||||
|
||||
self.areAsyncRegistrationsComplete = YES;
|
||||
|
||||
completion();
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)logFileSizes
|
||||
{
|
||||
DDLogInfo(@"%@ Database file size: %@", self.logTag, [OWSFileSystem fileSizeOfPath:self.databaseFilePath]);
|
||||
DDLogInfo(@"%@ \t SHM file size: %@", self.logTag, [OWSFileSystem fileSizeOfPath:self.databaseFilePath_SHM]);
|
||||
DDLogInfo(@"%@ \t WAL file size: %@", self.logTag, [OWSFileSystem fileSizeOfPath:self.databaseFilePath_WAL]);
|
||||
}
|
||||
|
||||
- (void)protectFiles
|
||||
{
|
||||
[self logFileSizes];
|
||||
|
||||
// Protect the entire new database directory.
|
||||
[OWSFileSystem protectFileOrFolderAtPath:self.databaseDirPath];
|
||||
}
|
||||
|
||||
+ (NSString *)databaseFilename
|
||||
{
|
||||
return @"SignalBackup.sqlite";
|
||||
}
|
||||
|
||||
- (NSString *)databaseFilename
|
||||
{
|
||||
return OWSBackupStorage.databaseFilename;
|
||||
}
|
||||
|
||||
- (NSString *)databaseFilename_SHM
|
||||
{
|
||||
return [self.databaseFilename stringByAppendingString:@"-shm"];
|
||||
}
|
||||
|
||||
- (NSString *)databaseFilename_WAL
|
||||
{
|
||||
return [self.databaseFilename stringByAppendingString:@"-wal"];
|
||||
}
|
||||
|
||||
- (NSString *)databaseFilePath
|
||||
{
|
||||
return [self.databaseDirPath stringByAppendingPathComponent:self.databaseFilename];
|
||||
}
|
||||
|
||||
- (NSString *)databaseFilePath_SHM
|
||||
{
|
||||
return [self.databaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM];
|
||||
}
|
||||
|
||||
- (NSString *)databaseFilePath_WAL
|
||||
{
|
||||
return [self.databaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL];
|
||||
}
|
||||
|
||||
- (NSData *)databaseKeySpec
|
||||
{
|
||||
OWSAssert(self.keySpecBlock);
|
||||
|
||||
return self.keySpecBlock();
|
||||
}
|
||||
|
||||
- (void)ensureDatabaseKeySpecExists
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -58,6 +58,7 @@ void runAsyncRegistrationsForStorage(OWSStorage *storage)
|
|||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface OWSPrimaryStorage ()
|
||||
|
||||
@property (nonatomic, readonly, nullable) YapDatabaseConnection *dbReadConnection;
|
||||
|
@ -91,6 +92,8 @@ void runAsyncRegistrationsForStorage(OWSStorage *storage)
|
|||
self = [super initStorage];
|
||||
|
||||
if (self) {
|
||||
[self loadDatabase];
|
||||
|
||||
_dbReadConnection = self.newDatabaseConnection;
|
||||
_dbReadWriteConnection = self.newDatabaseConnection;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSStorage.h"
|
||||
|
@ -8,6 +8,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@interface OWSStorage (Subclass)
|
||||
|
||||
- (void)loadDatabase;
|
||||
|
||||
- (void)runSyncRegistrations;
|
||||
- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion;
|
||||
|
||||
|
|
|
@ -267,30 +267,6 @@ typedef NSData *_Nullable (^CreateDatabaseMetadataBlock)(void);
|
|||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
if (![self tryToLoadDatabase]) {
|
||||
// Failing to load the database is catastrophic.
|
||||
//
|
||||
// The best we can try to do is to discard the current database
|
||||
// and behave like a clean install.
|
||||
OWSFail(@"%@ Could not load database", self.logTag);
|
||||
OWSProdCritical([OWSAnalyticsEvents storageErrorCouldNotLoadDatabase]);
|
||||
|
||||
// Try to reset app by deleting all databases.
|
||||
//
|
||||
// TODO: Possibly clean up all app files.
|
||||
// [OWSStorage deleteDatabaseFiles];
|
||||
|
||||
if (![self tryToLoadDatabase]) {
|
||||
OWSFail(@"%@ Could not load database (second try)", self.logTag);
|
||||
OWSProdCritical([OWSAnalyticsEvents storageErrorCouldNotLoadDatabaseSecondAttempt]);
|
||||
|
||||
// Sleep to give analytics events time to be delivered.
|
||||
[NSThread sleepForTimeInterval:15.0f];
|
||||
|
||||
OWSRaiseException(OWSStorageExceptionName_NoDatabase, @"Failed to initialize database.");
|
||||
}
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(resetStorage)
|
||||
name:OWSResetStorageNotification
|
||||
|
@ -305,6 +281,33 @@ typedef NSData *_Nullable (^CreateDatabaseMetadataBlock)(void);
|
|||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)loadDatabase
|
||||
{
|
||||
if (![self tryToLoadDatabase]) {
|
||||
// Failing to load the database is catastrophic.
|
||||
//
|
||||
// The best we can try to do is to discard the current database
|
||||
// and behave like a clean install.
|
||||
OWSFail(@"%@ Could not load database", self.logTag);
|
||||
OWSProdCritical([OWSAnalyticsEvents storageErrorCouldNotLoadDatabase]);
|
||||
|
||||
// Try to reset app by deleting all databases.
|
||||
//
|
||||
// TODO: Possibly clean up all app files.
|
||||
// [OWSStorage deleteDatabaseFiles];
|
||||
|
||||
if (![self tryToLoadDatabase]) {
|
||||
OWSFail(@"%@ Could not load database (second try)", self.logTag);
|
||||
OWSProdCritical([OWSAnalyticsEvents storageErrorCouldNotLoadDatabaseSecondAttempt]);
|
||||
|
||||
// Sleep to give analytics events time to be delivered.
|
||||
[NSThread sleepForTimeInterval:15.0f];
|
||||
|
||||
OWSRaiseException(OWSStorageExceptionName_NoDatabase, @"Failed to initialize database.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (nullable id)dbNotificationObject
|
||||
{
|
||||
OWSAssert(self.database);
|
||||
|
|
|
@ -31,6 +31,10 @@ typedef NS_ENUM(NSInteger, OWSErrorCode) {
|
|||
OWSErrorCodeMoveFileToSharedDataContainerError = 777412,
|
||||
OWSErrorCodeRegistrationMissing2FAPIN = 777413,
|
||||
OWSErrorCodeDebugLogUploadFailed = 777414,
|
||||
// A non-recoverable error occured while exporting a backup.
|
||||
OWSErrorCodeExportBackupFailed = 777415,
|
||||
// A possibly recoverable error occured while exporting a backup.
|
||||
OWSErrorCodeExportBackupError = 777416,
|
||||
};
|
||||
|
||||
extern NSString *const OWSErrorRecipientIdentifierKey;
|
||||
|
|
Loading…
Reference in a new issue