Added code to ignore migrating open group messages older than 6 months
This commit is contained in:
parent
eeccfb47d5
commit
07f4f7a4ea
|
@ -291,8 +291,6 @@
|
|||
C32C598A256D0664003C73A2 /* SNProtoEnvelope+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C38EEF09255B49A8007E1867 /* SNProtoEnvelope+Conversion.swift */; };
|
||||
C32C599E256DB02B003C73A2 /* TypingIndicators.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA87255A57FC00E217F9 /* TypingIndicators.swift */; };
|
||||
C32C5A24256DB7DB003C73A2 /* SNUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB6B255A580F00E217F9 /* SNUserDefaults.swift */; };
|
||||
C32C5A2D256DB849003C73A2 /* LKGroupUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBE1255A581A00E217F9 /* LKGroupUtilities.m */; };
|
||||
C32C5A36256DB856003C73A2 /* LKGroupUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDBCA255A581700E217F9 /* LKGroupUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
C32C5A47256DB8F0003C73A2 /* ECKeyPair+Hexadecimal.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA73255A57FA00E217F9 /* ECKeyPair+Hexadecimal.swift */; };
|
||||
C32C5A48256DB8F0003C73A2 /* BuildConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAA8255A57FF00E217F9 /* BuildConfiguration.swift */; };
|
||||
C32C5A88256DBCF9003C73A2 /* MessageReceiver+ClosedGroups.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32C5A87256DBCF9003C73A2 /* MessageReceiver+ClosedGroups.swift */; };
|
||||
|
@ -1405,11 +1403,9 @@
|
|||
C33FDBB6255A581600E217F9 /* DataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataSource.m; sourceTree = "<group>"; };
|
||||
C33FDBBC255A581600E217F9 /* SSKKeychainStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SSKKeychainStorage.swift; sourceTree = "<group>"; };
|
||||
C33FDBC2255A581700E217F9 /* SSKAsserts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSKAsserts.h; sourceTree = "<group>"; };
|
||||
C33FDBCA255A581700E217F9 /* LKGroupUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LKGroupUtilities.h; sourceTree = "<group>"; };
|
||||
C33FDBD3255A581800E217F9 /* OWSSignalAddress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSSignalAddress.swift; sourceTree = "<group>"; };
|
||||
C33FDBD8255A581900E217F9 /* SignalIOS.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalIOS.pb.swift; sourceTree = "<group>"; };
|
||||
C33FDBDE255A581900E217F9 /* PushNotificationAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PushNotificationAPI.swift; sourceTree = "<group>"; };
|
||||
C33FDBE1255A581A00E217F9 /* LKGroupUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LKGroupUtilities.m; sourceTree = "<group>"; };
|
||||
C33FDBF6255A581C00E217F9 /* NSURLSessionDataTask+StatusCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLSessionDataTask+StatusCode.h"; sourceTree = "<group>"; };
|
||||
C33FDBF9255A581C00E217F9 /* OWSError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSError.h; sourceTree = "<group>"; };
|
||||
C33FDC03255A581D00E217F9 /* ByteParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByteParser.h; sourceTree = "<group>"; };
|
||||
|
@ -2445,15 +2441,6 @@
|
|||
path = General;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B8A582B9258C696200AFD84C /* Messaging */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C33FDBCA255A581700E217F9 /* LKGroupUtilities.h */,
|
||||
C33FDBE1255A581A00E217F9 /* LKGroupUtilities.m */,
|
||||
);
|
||||
path = Messaging;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B8B3201F258B1A540020074B /* Contacts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -3158,7 +3145,6 @@
|
|||
B8A582B0258C66C900AFD84C /* General */,
|
||||
FD9004102818ABB000ABAAF6 /* JobRunner */,
|
||||
B8A582AF258C665E00AFD84C /* Media */,
|
||||
B8A582B9258C696200AFD84C /* Messaging */,
|
||||
B8A582AE258C65D000AFD84C /* Networking */,
|
||||
B8A582AD258C655E00AFD84C /* PromiseKit */,
|
||||
FD09796527F6B0A800936362 /* Utilities */,
|
||||
|
@ -4027,7 +4013,6 @@
|
|||
files = (
|
||||
C3D9E3A4256763DE0040E4F3 /* AppContext.h in Headers */,
|
||||
C3D9E38A256760390040E4F3 /* OWSFileSystem.h in Headers */,
|
||||
C32C5A36256DB856003C73A2 /* LKGroupUtilities.h in Headers */,
|
||||
C3D9E379256760340040E4F3 /* MIMETypeUtil.h in Headers */,
|
||||
C3D9E50E25677A510040E4F3 /* DataSource.h in Headers */,
|
||||
B8856DF8256F1633001CE70E /* NSString+SSK.h in Headers */,
|
||||
|
@ -5036,7 +5021,6 @@
|
|||
C352A36D2557858E00338F3E /* NSTimer+Proxying.m in Sources */,
|
||||
FD09797B27FBB25900936362 /* Updatable.swift in Sources */,
|
||||
FDCDB8F12817ABE600352A0C /* Optional+Utilities.swift in Sources */,
|
||||
C32C5A2D256DB849003C73A2 /* LKGroupUtilities.m in Sources */,
|
||||
7B7CB192271508AD0079FF93 /* CallRingTonePlayer.swift in Sources */,
|
||||
C3C2ABD22553C6C900C340D1 /* Data+SecureRandom.swift in Sources */,
|
||||
FD848B8B283DC509000E298B /* PagedDatabaseObserver.swift in Sources */,
|
||||
|
|
|
@ -412,7 +412,7 @@ final class ConversationVC: BaseVC, OWSConversationSettingsViewDelegate, Convers
|
|||
object: nil
|
||||
)
|
||||
|
||||
notificationCenter.addObserver(self, selector: #selector(handleContactThreadReplaced(_:)), name: .contactThreadReplaced, object: nil) // TODO: Is this needed???
|
||||
// notificationCenter.addObserver(self, selector: #selector(handleContactThreadReplaced(_:)), name: .contactThreadReplaced, object: nil)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
|
@ -1096,87 +1096,88 @@ final class ConversationVC: BaseVC, OWSConversationSettingsViewDelegate, Convers
|
|||
}
|
||||
|
||||
@objc private func handleContactThreadReplaced(_ notification: Notification) {
|
||||
// Ensure the current thread is one of the removed ones
|
||||
guard let newThreadId: String = notification.userInfo?[NotificationUserInfoKey.threadId] as? String else { return }
|
||||
guard let removedThreadIds: [String] = notification.userInfo?[NotificationUserInfoKey.removedThreadIds] as? [String] else {
|
||||
return
|
||||
}
|
||||
guard let threadId: String = thread.uniqueId, removedThreadIds.contains(threadId) else { return }
|
||||
|
||||
// Then look to swap the current ConversationVC with a replacement one with the new thread
|
||||
DispatchQueue.main.async {
|
||||
guard let navController: UINavigationController = self.navigationController else { return }
|
||||
guard let viewControllerIndex: Int = navController.viewControllers.firstIndex(of: self) else { return }
|
||||
guard let newThread: TSContactThread = TSContactThread.fetch(uniqueId: newThreadId) else { return }
|
||||
|
||||
// Let the view controller know we are replacing the thread
|
||||
self.isReplacingThread = true
|
||||
|
||||
// Create the new ConversationVC and swap the old one out for it
|
||||
let conversationVC: ConversationVC = ConversationVC(thread: newThread)
|
||||
let currentlyOnThisScreen: Bool = (navController.topViewController == self)
|
||||
|
||||
navController.viewControllers = [
|
||||
(viewControllerIndex == 0 ?
|
||||
[] :
|
||||
navController.viewControllers[0..<viewControllerIndex]
|
||||
),
|
||||
[conversationVC],
|
||||
(viewControllerIndex == (navController.viewControllers.count - 1) ?
|
||||
[] :
|
||||
navController.viewControllers[(viewControllerIndex + 1)..<navController.viewControllers.count]
|
||||
)
|
||||
].flatMap { $0 }
|
||||
|
||||
// If the top vew controller isn't the current one then we need to make sure to swap out child ones as well
|
||||
if !currentlyOnThisScreen {
|
||||
let maybeSettingsViewController: UIViewController? = navController
|
||||
.viewControllers[viewControllerIndex..<navController.viewControllers.count]
|
||||
.first(where: { $0 is OWSConversationSettingsViewController })
|
||||
|
||||
// Update the settings screen (if there is one)
|
||||
if let settingsViewController: OWSConversationSettingsViewController = maybeSettingsViewController as? OWSConversationSettingsViewController {
|
||||
settingsViewController.configure(with: newThread, uiDatabaseConnection: OWSPrimaryStorage.shared().uiDatabaseConnection)
|
||||
}
|
||||
}
|
||||
|
||||
// Try to minimise painful UX issues by keeping the 'first responder' state, current input text and
|
||||
// cursor position (Unfortunately there doesn't seem to be a way to prevent the keyboard from
|
||||
// flickering during the swap but other than that it's relatively seamless)
|
||||
if self.snInputView.inputTextViewIsFirstResponder {
|
||||
conversationVC.isReplacingThread = true
|
||||
conversationVC.snInputView.frame = self.snInputView.frame
|
||||
conversationVC.snInputView.text = self.snInputView.text
|
||||
conversationVC.snInputView.selectedRange = self.snInputView.selectedRange
|
||||
|
||||
// Make the current snInputView invisible and add the new one the the UI
|
||||
self.snInputView.alpha = 0
|
||||
self.snInputView.superview?.addSubview(conversationVC.snInputView)
|
||||
|
||||
// Add the old first responder to the window so it the keyboard won't get dismissed when the
|
||||
// OS removes it's parent view from the view hierarchy due to the view controller swap
|
||||
var maybeOldFirstResponderView: UIView?
|
||||
|
||||
if let oldFirstResponderView: UIView = UIResponder.currentFirstResponder() as? UIView {
|
||||
maybeOldFirstResponderView = oldFirstResponderView
|
||||
self.view.window?.addSubview(oldFirstResponderView)
|
||||
}
|
||||
|
||||
// On the next run loop setup the first responder state for the new screen and remove the
|
||||
// old first responder from the window
|
||||
DispatchQueue.main.async {
|
||||
UIView.performWithoutAnimation {
|
||||
conversationVC.isReplacingThread = false
|
||||
maybeOldFirstResponderView?.resignFirstResponder()
|
||||
maybeOldFirstResponderView?.removeFromSuperview()
|
||||
conversationVC.snInputView.removeFromSuperview()
|
||||
|
||||
_ = conversationVC.becomeFirstResponder()
|
||||
conversationVC.snInputView.inputTextViewBecomeFirstResponder()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print("ASDASDASD")
|
||||
// // Ensure the current thread is one of the removed ones
|
||||
// guard let newThreadId: String = notification.userInfo?[NotificationUserInfoKey.threadId] as? String else { return }
|
||||
// guard let removedThreadIds: [String] = notification.userInfo?[NotificationUserInfoKey.removedThreadIds] as? [String] else {
|
||||
// return
|
||||
// }
|
||||
// guard let threadId: String = thread.uniqueId, removedThreadIds.contains(threadId) else { return }
|
||||
//
|
||||
// // Then look to swap the current ConversationVC with a replacement one with the new thread
|
||||
// DispatchQueue.main.async {
|
||||
// guard let navController: UINavigationController = self.navigationController else { return }
|
||||
// guard let viewControllerIndex: Int = navController.viewControllers.firstIndex(of: self) else { return }
|
||||
// guard let newThread: TSContactThread = TSContactThread.fetch(uniqueId: newThreadId) else { return }
|
||||
//
|
||||
// // Let the view controller know we are replacing the thread
|
||||
// self.isReplacingThread = true
|
||||
//
|
||||
// // Create the new ConversationVC and swap the old one out for it
|
||||
// let conversationVC: ConversationVC = ConversationVC(thread: newThread)
|
||||
// let currentlyOnThisScreen: Bool = (navController.topViewController == self)
|
||||
//
|
||||
// navController.viewControllers = [
|
||||
// (viewControllerIndex == 0 ?
|
||||
// [] :
|
||||
// navController.viewControllers[0..<viewControllerIndex]
|
||||
// ),
|
||||
// [conversationVC],
|
||||
// (viewControllerIndex == (navController.viewControllers.count - 1) ?
|
||||
// [] :
|
||||
// navController.viewControllers[(viewControllerIndex + 1)..<navController.viewControllers.count]
|
||||
// )
|
||||
// ].flatMap { $0 }
|
||||
//
|
||||
// // If the top vew controller isn't the current one then we need to make sure to swap out child ones as well
|
||||
// if !currentlyOnThisScreen {
|
||||
// let maybeSettingsViewController: UIViewController? = navController
|
||||
// .viewControllers[viewControllerIndex..<navController.viewControllers.count]
|
||||
// .first(where: { $0 is OWSConversationSettingsViewController })
|
||||
//
|
||||
// // Update the settings screen (if there is one)
|
||||
// if let settingsViewController: OWSConversationSettingsViewController = maybeSettingsViewController as? OWSConversationSettingsViewController {
|
||||
// settingsViewController.configure(with: newThread, uiDatabaseConnection: OWSPrimaryStorage.shared().uiDatabaseConnection)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Try to minimise painful UX issues by keeping the 'first responder' state, current input text and
|
||||
// // cursor position (Unfortunately there doesn't seem to be a way to prevent the keyboard from
|
||||
// // flickering during the swap but other than that it's relatively seamless)
|
||||
// if self.snInputView.inputTextViewIsFirstResponder {
|
||||
// conversationVC.isReplacingThread = true
|
||||
// conversationVC.snInputView.frame = self.snInputView.frame
|
||||
// conversationVC.snInputView.text = self.snInputView.text
|
||||
// conversationVC.snInputView.selectedRange = self.snInputView.selectedRange
|
||||
//
|
||||
// // Make the current snInputView invisible and add the new one the the UI
|
||||
// self.snInputView.alpha = 0
|
||||
// self.snInputView.superview?.addSubview(conversationVC.snInputView)
|
||||
//
|
||||
// // Add the old first responder to the window so it the keyboard won't get dismissed when the
|
||||
// // OS removes it's parent view from the view hierarchy due to the view controller swap
|
||||
// var maybeOldFirstResponderView: UIView?
|
||||
//
|
||||
// if let oldFirstResponderView: UIView = UIResponder.currentFirstResponder() as? UIView {
|
||||
// maybeOldFirstResponderView = oldFirstResponderView
|
||||
// self.view.window?.addSubview(oldFirstResponderView)
|
||||
// }
|
||||
//
|
||||
// // On the next run loop setup the first responder state for the new screen and remove the
|
||||
// // old first responder from the window
|
||||
// DispatchQueue.main.async {
|
||||
// UIView.performWithoutAnimation {
|
||||
// conversationVC.isReplacingThread = false
|
||||
// maybeOldFirstResponderView?.resignFirstResponder()
|
||||
// maybeOldFirstResponderView?.removeFromSuperview()
|
||||
// conversationVC.snInputView.removeFromSuperview()
|
||||
//
|
||||
// _ = conversationVC.becomeFirstResponder()
|
||||
// conversationVC.snInputView.inputTextViewBecomeFirstResponder()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// MARK: - UITableViewDataSource
|
||||
|
|
|
@ -48,6 +48,5 @@
|
|||
#import <SignalUtilitiesKit/OWSDispatch.h>
|
||||
#import <SignalUtilitiesKit/OWSError.h>
|
||||
#import <SessionUtilitiesKit/OWSFileSystem.h>
|
||||
#import <SessionUtilitiesKit/LKGroupUtilities.h>
|
||||
#import <SessionUtilitiesKit/UIImage+OWS.h>
|
||||
#import <YYImage/YYImage.h>
|
||||
|
|
|
@ -12,6 +12,7 @@ public enum SMKLegacy {
|
|||
internal static let contactThreadPrefix = "c"
|
||||
internal static let groupThreadPrefix = "g"
|
||||
internal static let closedGroupIdPrefix = "__textsecure_group__!"
|
||||
internal static let openGroupIdPrefix = "__loki_public_chat_group__!"
|
||||
internal static let closedGroupKeyPairPrefix = "SNClosedGroupEncryptionKeyPairCollection-"
|
||||
|
||||
internal static let databaseMigrationCollection = "OWSDatabaseMigration"
|
||||
|
|
|
@ -24,6 +24,7 @@ enum _003_YDBToGRDBMigration: Migration {
|
|||
|
||||
// MARK: - Read from Legacy Database
|
||||
|
||||
let timestampNow: TimeInterval = Date().timeIntervalSince1970
|
||||
var shouldFailMigration: Bool = false
|
||||
var legacyMigrations: Set<SMKLegacy._DBMigration> = []
|
||||
var contacts: Set<SMKLegacy._Contact> = []
|
||||
|
@ -210,6 +211,23 @@ enum _003_YDBToGRDBMigration: Migration {
|
|||
return
|
||||
}
|
||||
|
||||
/// Prune interactions from OpenGroup thread interactions which are older than 6 months
|
||||
///
|
||||
/// The old structure for the open group id was `g{base64String(Data(__loki_public_chat_group__!{server.room}))}
|
||||
/// so we process the uniqueThreadId to see if it matches that
|
||||
if
|
||||
interaction.uniqueThreadId.starts(with: SMKLegacy.groupThreadPrefix),
|
||||
let base64Data: Data = Data(base64Encoded: interaction.uniqueThreadId.substring(from: SMKLegacy.groupThreadPrefix.count)),
|
||||
let groupIdString: String = String(data: base64Data, encoding: .utf8),
|
||||
(
|
||||
groupIdString.starts(with: SMKLegacy.openGroupIdPrefix) ||
|
||||
groupIdString.starts(with: "http")
|
||||
),
|
||||
interaction.timestamp < UInt64(floor((timestampNow - GarbageCollectionJob.approxSixMonthsInSeconds) * 1000))
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
interactions[interaction.uniqueThreadId] = (interactions[interaction.uniqueThreadId] ?? [])
|
||||
.appending(interaction)
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ public enum GarbageCollectionJob: JobExecutor {
|
|||
public static var maxFailureCount: Int = -1
|
||||
public static var requiresThreadId: Bool = false
|
||||
public static let requiresInteractionId: Bool = false
|
||||
private static let approxSixMonthsInSeconds: TimeInterval = (6 * 30 * 24 * 60 * 60)
|
||||
public static let approxSixMonthsInSeconds: TimeInterval = (6 * 30 * 24 * 60 * 60)
|
||||
|
||||
public static func run(
|
||||
_ job: Job,
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface LKGroupUtilities : NSObject
|
||||
|
||||
+(NSString *)getEncodedOpenGroupID:(NSString *)groupID;
|
||||
+(NSData *)getEncodedOpenGroupIDAsData:(NSString *)groupID;
|
||||
|
||||
+(NSString *)getEncodedClosedGroupID:(NSString *)groupID;
|
||||
+(NSData *)getEncodedClosedGroupIDAsData:(NSString *)groupID;
|
||||
|
||||
+(NSString *)getEncodedMMSGroupID:(NSString *)groupID;
|
||||
+(NSData *)getEncodedMMSGroupIDAsData:(NSString *)groupID;
|
||||
|
||||
+(NSString *)getEncodedGroupID:(NSData *)groupID;
|
||||
|
||||
+(NSString *)getDecodedGroupID:(NSData *)groupID;
|
||||
+(NSData *)getDecodedGroupIDAsData:(NSData *)groupID;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -1,58 +0,0 @@
|
|||
#import "LKGroupUtilities.h"
|
||||
|
||||
@implementation LKGroupUtilities
|
||||
|
||||
#define ClosedGroupPrefix @"__textsecure_group__!"
|
||||
#define MMSGroupPrefix @"__signal_mms_group__!"
|
||||
#define OpenGroupPrefix @"__loki_public_chat_group__!"
|
||||
|
||||
+(NSString *)getEncodedOpenGroupID:(NSString *)groupID
|
||||
{
|
||||
return [OpenGroupPrefix stringByAppendingString:groupID];
|
||||
}
|
||||
|
||||
+(NSData *)getEncodedOpenGroupIDAsData:(NSString *)groupID
|
||||
{
|
||||
return [[OpenGroupPrefix stringByAppendingString:groupID] dataUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
+(NSString *)getEncodedClosedGroupID:(NSString *)groupID
|
||||
{
|
||||
return [ClosedGroupPrefix stringByAppendingString:groupID];
|
||||
}
|
||||
|
||||
+(NSData *)getEncodedClosedGroupIDAsData:(NSString *)groupID
|
||||
{
|
||||
return [[ClosedGroupPrefix stringByAppendingString:groupID] dataUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
+(NSString *)getEncodedMMSGroupID:(NSString *)groupID
|
||||
{
|
||||
return [MMSGroupPrefix stringByAppendingString:groupID];
|
||||
}
|
||||
|
||||
+(NSData *)getEncodedMMSGroupIDAsData:(NSString *)groupID
|
||||
{
|
||||
return [[MMSGroupPrefix stringByAppendingString:groupID] dataUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
+(NSString *)getEncodedGroupID:(NSData *)groupID
|
||||
{
|
||||
return [[NSString alloc] initWithData:groupID encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
+(NSString *)getDecodedGroupID:(NSData *)groupID
|
||||
{
|
||||
NSString *encodedGroupID = [[NSString alloc] initWithData:groupID encoding:NSUTF8StringEncoding];
|
||||
if ([encodedGroupID componentsSeparatedByString:@"!"].count > 1) {
|
||||
return [encodedGroupID componentsSeparatedByString:@"!"][1];
|
||||
}
|
||||
return [encodedGroupID componentsSeparatedByString:@"!"][0];
|
||||
}
|
||||
|
||||
+(NSData *)getDecodedGroupIDAsData:(NSData *)groupID
|
||||
{
|
||||
return [[LKGroupUtilities getDecodedGroupID:groupID] dataUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
@end
|
|
@ -5,7 +5,6 @@ FOUNDATION_EXPORT const unsigned char SessionUtilitiesKitVersionString[];
|
|||
|
||||
#import <SessionUtilitiesKit/AppContext.h>
|
||||
#import <SessionUtilitiesKit/DataSource.h>
|
||||
#import <SessionUtilitiesKit/LKGroupUtilities.h>
|
||||
#import <SessionUtilitiesKit/MIMETypeUtil.h>
|
||||
#import <SessionUtilitiesKit/NSData+Image.h>
|
||||
#import <SessionUtilitiesKit/NSNotificationCenter+OWS.h>
|
||||
|
|
Loading…
Reference in New Issue