Implement message retention, retry mechanism, and app updates

- Add KeychainManager for secure password storage
- Implement MessageRetentionService for encrypted local storage of favorite room messages
- Add MessageRetryService for automatic retry of failed messages
- Add /favorite command to toggle room retention
- Add /discover command to find active rooms
- Fix all force unwrapped optionals in BluetoothMeshService
- Update app info screen with new features
- Integrate all services with proper cleanup on panic
This commit is contained in:
jack
2025-07-05 19:35:37 +02:00
parent 7151896102
commit 506c2bc7cb
8 changed files with 940 additions and 63 deletions
+26 -15
View File
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 63;
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
@@ -12,7 +12,9 @@
1D9674FA5F998503831DC281 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A08E03AA0C63E97C91749AEC /* ContentView.swift */; };
230B11C5BF035D35638B21C8 /* PasswordProtectedRoomTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB12482E4AD78B861C538449 /* PasswordProtectedRoomTests.swift */; };
2E71E320EA921498C57E023B /* BitchatMessageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FA8FF26ABDC1C642A8C7AE5 /* BitchatMessageTests.swift */; };
4274B6016F755946FBF2513E /* MessageRetentionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A85BFDDE65B4CD8BDF6DDB /* MessageRetentionService.swift */; };
4B747085D07A1BCE0F5BA612 /* BinaryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2136C3E22D02D4A8DBE7EAB /* BinaryProtocol.swift */; };
4E778E5A414571ACAC2A0F01 /* MessageRetentionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A85BFDDE65B4CD8BDF6DDB /* MessageRetentionService.swift */; };
56F0892E13CC0D1490A3691E /* BloomFilterTests.swift.disabled in Resources */ = {isa = PBXBuildFile; fileRef = 822AA698BDB7BB939B62A010 /* BloomFilterTests.swift.disabled */; };
61C81ED5F679D5E973EE0C07 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448F84BF86A42A3CC4A9379 /* NotificationService.swift */; };
6A624D9359BCCAAE58CE0D64 /* LoggingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96CDF6D0AF0F2052A6C7E634 /* LoggingService.swift */; };
@@ -25,6 +27,7 @@
7A50E2F04A3515A7E90EEAE4 /* BluetoothMeshService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5C3D880FF8AE1673B20E1E3 /* BluetoothMeshService.swift */; };
7DD72D928FF9DD3CA81B46B0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3A69677D382F1C3D5ED03F7D /* Assets.xcassets */; };
8F0BFC2D2B2A5E7B70C3B485 /* BinaryProtocolTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53D535D9CE0B875F47402290 /* BinaryProtocolTests.swift */; };
8F737CE0435792CC2AD65FCB /* KeychainManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136696FC4436A02D98CE6A77 /* KeychainManager.swift */; };
923027D6F2F417AFA2488127 /* BitchatProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 229F17B68CFF7AB1BC91C847 /* BitchatProtocol.swift */; };
92D34E7A07C990C8A815B0CE /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A08E03AA0C63E97C91749AEC /* ContentView.swift */; };
A0691E21A3A358AB9715AC20 /* BloomFilterTests.swift.disabled in Resources */ = {isa = PBXBuildFile; fileRef = 822AA698BDB7BB939B62A010 /* BloomFilterTests.swift.disabled */; };
@@ -32,13 +35,16 @@
AD11E46940D742AEAF547EB2 /* AppInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 763E0DBA9492A654FC0CDCB9 /* AppInfoView.swift */; };
ADC66F95FBD513B10411ADB3 /* MessagePaddingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DE9CDF66D4E52D268851048 /* MessagePaddingTests.swift */; };
BCCFEDC1EBE59323C3C470BF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3A69677D382F1C3D5ED03F7D /* Assets.xcassets */; };
C99763A4761567F587D21688 /* MessageRetryService.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4D7595A613F7ED3B386132 /* MessageRetryService.swift */; };
CDAD6629EB69916B95C80DAF /* BinaryProtocolTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53D535D9CE0B875F47402290 /* BinaryProtocolTests.swift */; };
CEAE115C9C3EB3C4ED82F128 /* MessageRetryService.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4D7595A613F7ED3B386132 /* MessageRetryService.swift */; };
D450CF41F207BDE1A1AAA56E /* ChatViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6B8F7B7D55092C2540A7996 /* ChatViewModel.swift */; };
D948085736ED8E736C1DE3B0 /* BluetoothMeshService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5C3D880FF8AE1673B20E1E3 /* BluetoothMeshService.swift */; };
DDA1DFAB1FF7AADE52DC0F53 /* EncryptionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC1563390A15C042D059CF9 /* EncryptionService.swift */; };
F00B713D5053617FB5F3F1BE /* MessagePaddingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DE9CDF66D4E52D268851048 /* MessagePaddingTests.swift */; };
F455F011B3B648ADA233F998 /* BinaryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2136C3E22D02D4A8DBE7EAB /* BinaryProtocol.swift */; };
F4A689F5F34125AE1BFD5599 /* PasswordProtectedRoomTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB12482E4AD78B861C538449 /* PasswordProtectedRoomTests.swift */; };
FB8819B4C84FAFEF5C36B216 /* KeychainManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136696FC4436A02D98CE6A77 /* KeychainManager.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -60,20 +66,23 @@
/* Begin PBXFileReference section */
03C57F452B55FD0FD8F51421 /* bitchatTests_macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = bitchatTests_macOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
136696FC4436A02D98CE6A77 /* KeychainManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainManager.swift; sourceTree = "<group>"; };
229F17B68CFF7AB1BC91C847 /* BitchatProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BitchatProtocol.swift; sourceTree = "<group>"; };
3448F84BF86A42A3CC4A9379 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
3A69677D382F1C3D5ED03F7D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
3FA8FF26ABDC1C642A8C7AE5 /* BitchatMessageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BitchatMessageTests.swift; sourceTree = "<group>"; };
53D535D9CE0B875F47402290 /* BinaryProtocolTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinaryProtocolTests.swift; sourceTree = "<group>"; };
67A85BFDDE65B4CD8BDF6DDB /* MessageRetentionService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageRetentionService.swift; sourceTree = "<group>"; };
6DC1563390A15C042D059CF9 /* EncryptionService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionService.swift; sourceTree = "<group>"; };
763E0DBA9492A654FC0CDCB9 /* AppInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppInfoView.swift; sourceTree = "<group>"; };
7EEBDA723E1CFD88758DA4AC /* bitchat.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = bitchat.app; sourceTree = BUILT_PRODUCTS_DIR; };
822AA698BDB7BB939B62A010 /* BloomFilterTests.swift.disabled */ = {isa = PBXFileReference; lastKnownFileType = text; path = BloomFilterTests.swift.disabled; sourceTree = "<group>"; };
822AA698BDB7BB939B62A010 /* BloomFilterTests.swift.disabled */ = {isa = PBXFileReference; path = BloomFilterTests.swift.disabled; sourceTree = "<group>"; };
8DE9CDF66D4E52D268851048 /* MessagePaddingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagePaddingTests.swift; sourceTree = "<group>"; };
96CDF6D0AF0F2052A6C7E634 /* LoggingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggingService.swift; sourceTree = "<group>"; };
997D512074C64904D75DDD40 /* bitchat.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = bitchat.app; sourceTree = BUILT_PRODUCTS_DIR; };
997D512074C64904D75DDD40 /* bitchat.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = bitchat.app; sourceTree = BUILT_PRODUCTS_DIR; };
A08E03AA0C63E97C91749AEC /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
A2136C3E22D02D4A8DBE7EAB /* BinaryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinaryProtocol.swift; sourceTree = "<group>"; };
AA4D7595A613F7ED3B386132 /* MessageRetryService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageRetryService.swift; sourceTree = "<group>"; };
C0DB1DE27F0AAB5092663E8E /* bitchatTests_iOS.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = bitchatTests_iOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
D5C3D880FF8AE1673B20E1E3 /* BluetoothMeshService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BluetoothMeshService.swift; sourceTree = "<group>"; };
D69A18D27F9A565FD6041E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
@@ -162,7 +171,10 @@
children = (
D5C3D880FF8AE1673B20E1E3 /* BluetoothMeshService.swift */,
6DC1563390A15C042D059CF9 /* EncryptionService.swift */,
136696FC4436A02D98CE6A77 /* KeychainManager.swift */,
96CDF6D0AF0F2052A6C7E634 /* LoggingService.swift */,
67A85BFDDE65B4CD8BDF6DDB /* MessageRetentionService.swift */,
AA4D7595A613F7ED3B386132 /* MessageRetryService.swift */,
3448F84BF86A42A3CC4A9379 /* NotificationService.swift */,
);
path = Services;
@@ -272,6 +284,7 @@
);
mainGroup = 18198ED912AAF495D8AF7763;
minimizedProjectReferenceProxies = 1;
preferredProjectObjectVersion = 54;
projectDirPath = "";
projectRoot = "";
targets = (
@@ -331,7 +344,10 @@
D450CF41F207BDE1A1AAA56E /* ChatViewModel.swift in Sources */,
92D34E7A07C990C8A815B0CE /* ContentView.swift in Sources */,
739429DFDE5C5829CF70DA7D /* EncryptionService.swift in Sources */,
FB8819B4C84FAFEF5C36B216 /* KeychainManager.swift in Sources */,
72BDC660D445E2D24AB90326 /* LoggingService.swift in Sources */,
4E778E5A414571ACAC2A0F01 /* MessageRetentionService.swift in Sources */,
C99763A4761567F587D21688 /* MessageRetryService.swift in Sources */,
749D8CF8A362B6CD0786782D /* NotificationService.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -348,7 +364,10 @@
7576A357B278E5733E9D9F33 /* ChatViewModel.swift in Sources */,
1D9674FA5F998503831DC281 /* ContentView.swift in Sources */,
DDA1DFAB1FF7AADE52DC0F53 /* EncryptionService.swift in Sources */,
8F737CE0435792CC2AD65FCB /* KeychainManager.swift in Sources */,
6A624D9359BCCAAE58CE0D64 /* LoggingService.swift in Sources */,
4274B6016F755946FBF2513E /* MessageRetentionService.swift in Sources */,
CEAE115C9C3EB3C4ED82F128 /* MessageRetryService.swift in Sources */,
61C81ED5F679D5E973EE0C07 /* NotificationService.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -457,7 +476,6 @@
CODE_SIGNING_REQUIRED = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = L3N5LHJD5Y;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = bitchat/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
@@ -469,12 +487,9 @@
PRODUCT_BUNDLE_IDENTIFIER = chat.bitchat;
PRODUCT_NAME = bitchat;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
@@ -506,7 +521,6 @@
CODE_SIGNING_REQUIRED = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = L3N5LHJD5Y;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = bitchat/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
@@ -518,12 +532,9 @@
PRODUCT_BUNDLE_IDENTIFIER = chat.bitchat;
PRODUCT_NAME = bitchat;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};