Merge pull request #320 from loki-project/cleanup

Cleanup Part 1
This commit is contained in:
Niels Andriesse 2021-01-04 10:41:28 +11:00 committed by GitHub
commit 4cd9e979bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
95 changed files with 486 additions and 1105 deletions

View File

@ -69,7 +69,6 @@
#import <SessionUtilitiesKit/NSNotificationCenter+OWS.h>
#import <SessionUtilitiesKit/NSString+SSK.h>
#import <SessionMessagingKit/OWSBackgroundTask.h>
#import <SignalUtilitiesKit/OWSContactsOutputStream.h>
#import <SignalUtilitiesKit/OWSDispatch.h>
#import <SignalUtilitiesKit/OWSError.h>
#import <SessionUtilitiesKit/OWSFileSystem.h>

View File

@ -8,7 +8,6 @@
#import <SignalUtilitiesKit/UIFont+OWS.h>
#import <SessionUtilitiesKit/UIView+OWS.h>
#import <SessionUtilitiesKit/AppContext.h>
#import <SignalUtilitiesKit/OWSUploadOperation.h>
#import <SessionMessagingKit/TSAttachmentStream.h>
NS_ASSUME_NONNULL_BEGIN
@ -42,11 +41,6 @@ NS_ASSUME_NONNULL_BEGIN
[self createContents];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(attachmentUploadProgress:)
name:kAttachmentUploadProgressNotification
object:nil];
_isAttachmentReady = self.attachment.isUploaded;
[self ensureViewState];
@ -119,23 +113,6 @@ NS_ASSUME_NONNULL_BEGIN
self.progressLabel.hidden = !isUploading;
}
- (void)attachmentUploadProgress:(NSNotification *)notification
{
NSDictionary *userinfo = [notification userInfo];
double progress = [[userinfo objectForKey:kAttachmentUploadProgressKey] doubleValue];
NSString *attachmentID = [userinfo objectForKey:kAttachmentUploadAttachmentIDKey];
if ([self.attachment.uniqueId isEqual:attachmentID]) {
if (!isnan(progress)) {
[self.progressView setProgress:(CGFloat)progress];
self.lastProgress = (CGFloat)progress;
self.isAttachmentReady = self.attachment.isUploaded;
} else {
OWSFailDebug(@"Invalid attachment progress.");
self.isAttachmentReady = YES;
}
}
}
@end
NS_ASSUME_NONNULL_END

View File

@ -26,21 +26,6 @@ public class MediaUploadView: UIView {
layer.addSublayer(shapeLayer1)
layer.addSublayer(shapeLayer2)
NotificationCenter.default.addObserver(forName: NSNotification.Name.attachmentUploadProgress, object: nil, queue: nil) { [weak self] notification in
guard let strongSelf = self else { return }
guard let notificationAttachmentId = notification.userInfo?[kAttachmentUploadAttachmentIDKey] as? String else {
return
}
guard notificationAttachmentId == strongSelf.attachmentId else {
return
}
guard let progress = notification.userInfo?[kAttachmentUploadProgressKey] as? NSNumber else {
return
}
strongSelf.lastProgress = CGFloat(progress.floatValue)
strongSelf.updateLayers()
}
}
@available(*, unavailable, message: "use other init() instead.")

View File

@ -2,6 +2,7 @@
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
import AFNetworking
import Foundation
import PromiseKit
import CoreServices

View File

@ -1,17 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@interface OWSDeviceProvisioningURLParser : NSObject
@property (readonly, getter=isValid) BOOL valid;
@property (nonatomic, readonly, nullable) NSString *ephemeralDeviceId;
@property (nonatomic, readonly, nullable) NSData *publicKey;
- (instancetype)initWithProvisioningURL:(NSString *)provisioningURL;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,45 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSDeviceProvisioningURLParser.h"
#import <SessionProtocolKit/NSData+keyVersionByte.h>
#import <SignalCoreKit/NSData+OWS.h>
NS_ASSUME_NONNULL_BEGIN
NSString *const OWSQueryItemNameEphemeralDeviceIdKey = @"uuid";
NSString *const OWSQueryItemNameEncodedPublicKeyKey = @"pub_key";
@implementation OWSDeviceProvisioningURLParser
- (instancetype)initWithProvisioningURL:(NSString *)provisioningURL
{
self = [super init];
if (!self) {
return self;
}
NSURLComponents *components = [NSURLComponents componentsWithString:provisioningURL];
for (NSURLQueryItem *queryItem in [components queryItems]) {
if ([queryItem.name isEqualToString:OWSQueryItemNameEphemeralDeviceIdKey]) {
_ephemeralDeviceId = queryItem.value;
} else if ([queryItem.name isEqualToString:OWSQueryItemNameEncodedPublicKeyKey]) {
NSString *encodedPublicKey = queryItem.value;
@try {
_publicKey = [[NSData dataFromBase64String:encodedPublicKey] throws_removeKeyType];
} @catch (NSException *exception) {
OWSFailDebug(@"exception: %@", exception);
}
} else {
OWSLogWarn(@"Unkown query item in provisioning string: %@", queryItem.name);
}
}
_valid = _ephemeralDeviceId && _publicKey;
return self;
}
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,81 @@
@objc(SNContact)
public class Contact : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
@objc public let sessionID: String
/// The display name of the contact.
///
/// - Note: In open groups use `openGroupDisplayName`.
@objc public var displayName: String?
/// The URL from which to fetch the contact's profile picture.
@objc public var profilePictureURL: String?
/// The file name of the contact's profile picture on local storage.
@objc public var profilePictureFileName: String?
/// The key with which the profile picture is encrypted.
@objc public var profilePictureEncryptionKey: OWSAES256Key?
/// The ID of the thread associated with this contact.
@objc public var threadID: String?
/// In open groups, where it's more likely that multiple users have the same name, we display a bit of the Session ID after
/// a user's display name for added context.
public var openGroupDisplayName: String? {
guard let displayName = displayName else { return nil }
let endIndex = sessionID.endIndex
let cutoffIndex = sessionID.index(endIndex, offsetBy: -8)
return "\(displayName) (...\(sessionID[cutoffIndex..<endIndex]))"
}
// MARK: Initialization
@objc public init(sessionID: String) {
self.sessionID = sessionID
super.init()
}
private override init() { preconditionFailure("Use init(sessionID:) instead.") }
// MARK: Validation
public var isValid: Bool {
if profilePictureURL != nil { return (profilePictureEncryptionKey != nil) }
if profilePictureEncryptionKey != nil { return (profilePictureURL != nil) }
return true
}
// MARK: Coding
public required init?(coder: NSCoder) {
guard let sessionID = coder.decodeObject(forKey: "sessionID") as! String? else { return nil }
self.sessionID = sessionID
if let displayName = coder.decodeObject(forKey: "displayName") as! String? { self.displayName = displayName }
if let profilePictureURL = coder.decodeObject(forKey: "profilePictureURL") as! String? { self.profilePictureURL = profilePictureURL }
if let profilePictureFileName = coder.decodeObject(forKey: "profilePictureFileName") as! String? { self.profilePictureFileName = profilePictureFileName }
if let profilePictureEncryptionKey = coder.decodeObject(forKey: "profilePictureEncryptionKey") as! OWSAES256Key? { self.profilePictureEncryptionKey = profilePictureEncryptionKey }
if let threadID = coder.decodeObject(forKey: "threadID") as! String? { self.threadID = threadID }
}
public func encode(with coder: NSCoder) {
coder.encode(sessionID, forKey: "sessionID")
coder.encode(displayName, forKey: "displayName")
coder.encode(profilePictureURL, forKey: "profilePictureURL")
coder.encode(profilePictureFileName, forKey: "profilePictureFileName")
coder.encode(profilePictureEncryptionKey, forKey: "profilePictureEncryptionKey")
coder.encode(threadID, forKey: "threadID")
}
// MARK: Equality
override public func isEqual(_ other: Any?) -> Bool {
guard let other = other as? Contact else { return false }
return sessionID == other.sessionID
}
// MARK: Hashing
override public var hash: Int { // Override NSObject.hash and not Hashable.hashValue or Hashable.hash(into:)
return sessionID.hash
}
// MARK: Description
override public var description: String {
if let displayName = displayName {
return displayName
} else {
return sessionID
}
}
}

View File

@ -0,0 +1,31 @@
import SessionProtocolKit
extension Storage {
private static let contactCollection = "LokiContactCollection"
@objc(getContactWithSessionID:)
public func getContact(with sessionID: String) -> Contact? {
var result: Contact?
Storage.read { transaction in
result = transaction.object(forKey: sessionID, inCollection: Storage.contactCollection) as? Contact
}
return result
}
@objc(setContact:usingTransaction:)
public func setContact(_ contact: Contact, using transaction: Any) {
(transaction as! YapDatabaseReadWriteTransaction).setObject(contact, forKey: contact.sessionID, inCollection: Storage.contactCollection)
}
public func getAllContacts() -> Set<Contact> {
var result: Set<Contact> = []
Storage.read { transaction in
transaction.enumerateRows(inCollection: Storage.contactCollection) { _, object, _, _ in
guard let contact = object as? Contact else { return }
result.insert(contact)
}
}
return result
}
}

View File

@ -1,7 +1,7 @@
public extension VisibleMessage {
@objc(SNContact)
@objc(SNMessageContact)
class Contact : NSObject, NSCoding {
public required init?(coder: NSCoder) { }

View File

@ -154,20 +154,24 @@ extension MessageReceiver {
// Update profile if needed
if let newProfile = message.profile {
let profileManager = SSKEnvironment.shared.profileManager
let oldProfile = OWSUserProfile.fetch(uniqueId: message.sender!, transaction: transaction)
let sessionID = message.sender!
let oldProfile = OWSUserProfile.fetch(uniqueId: sessionID, transaction: transaction)
let contact = Storage.shared.getContact(with: sessionID) ?? Contact(sessionID: sessionID)
if let displayName = newProfile.displayName, displayName != oldProfile?.profileName {
profileManager.updateProfileForContact(withID: message.sender!, displayName: displayName, with: transaction)
profileManager.updateProfileForContact(withID: sessionID, displayName: displayName, with: transaction)
contact.displayName = displayName
}
if let profileKey = newProfile.profileKey, let profilePictureURL = newProfile.profilePictureURL, profileKey.count == kAES256_KeyByteLength,
profileKey != oldProfile?.profileKey?.keyData {
profileManager.setProfileKeyData(profileKey, forRecipientId: message.sender!, avatarURL: profilePictureURL)
profileManager.setProfileKeyData(profileKey, forRecipientId: sessionID, avatarURL: profilePictureURL)
contact.profilePictureURL = profilePictureURL
contact.profilePictureEncryptionKey = OWSAES256Key(data: profileKey)
}
if let rawDisplayName = newProfile.displayName, let openGroupID = openGroupID {
let publicKey = message.sender!
let endIndex = publicKey.endIndex
let cutoffIndex = publicKey.index(endIndex, offsetBy: -8)
let displayName = "\(rawDisplayName) (...\(publicKey[cutoffIndex..<endIndex]))"
Storage.shared.setOpenGroupDisplayName(to: displayName, for: message.sender!, inOpenGroupWithID: openGroupID, using: transaction)
let endIndex = sessionID.endIndex
let cutoffIndex = sessionID.index(endIndex, offsetBy: -8)
let displayName = "\(rawDisplayName) (...\(sessionID[cutoffIndex..<endIndex]))"
Storage.shared.setOpenGroupDisplayName(to: displayName, for: sessionID, inOpenGroupWithID: openGroupID, using: transaction)
}
}
// Get or create thread

View File

@ -45,7 +45,7 @@ public final class Poller : NSObject {
// MARK: Private API
private func setUpPolling() {
guard isPolling else { return }
let _ = SnodeAPI.getSwarm(for: getUserHexEncodedPublicKey(), isForcedReload: true).then2 { [weak self] _ -> Promise<Void> in
let _ = SnodeAPI.getSwarm(for: getUserHexEncodedPublicKey()).then2 { [weak self] _ -> Promise<Void> in
guard let strongSelf = self else { return Promise { $0.fulfill(()) } }
strongSelf.usedSnodes.removeAll()
let (promise, seal) = Promise<Void>.pending()
@ -109,7 +109,7 @@ public final class Poller : NSObject {
if strongSelf.pollCount == Poller.maxPollCount {
throw Error.pollLimitReached
} else {
return withDelay(Poller.pollInterval, completionQueue: SnodeAPI.workQueue) {
return withDelay(Poller.pollInterval, completionQueue: DispatchQueue.main) {
guard let strongSelf = self, strongSelf.isPolling else { return Promise { $0.fulfill(()) } }
return strongSelf.poll(snode, seal: longTermSeal)
}

View File

@ -13,6 +13,8 @@
#import <SignalCoreKit/NSString+OWS.h>
#import <YapDatabase/YapDatabaseConnection.h>
#import <YapDatabase/YapDatabaseTransaction.h>
#import <Curve25519Kit/Curve25519.h>
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN
@ -117,6 +119,15 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId";
#pragma mark -
- (NSString *)sessionID
{
if ([self.recipientId isEqual:kLocalProfileUniqueId]) {
return OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey;
} else {
return self.recipientId;
}
}
- (nullable NSString *)avatarUrlPath
{
@synchronized(self)
@ -270,6 +281,12 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId";
functionName:__PRETTY_FUNCTION__
transaction:transaction
completion:completion];
SNContact *contact = [LKStorage.shared getContactWithSessionID:self.sessionID] ?: [[SNContact alloc] initWithSessionID:self.sessionID];
contact.displayName = [profileName ows_stripped];
contact.profilePictureURL = avatarUrlPath;
contact.profilePictureFileName = avatarFileName;
[LKStorage.shared setContact:contact usingTransaction:transaction];
}
- (void)updateWithProfileName:(nullable NSString *)profileName
@ -288,6 +305,14 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId";
functionName:__PRETTY_FUNCTION__
dbConnection:dbConnection
completion:completion];
SNContact *contact = [LKStorage.shared getContactWithSessionID:self.sessionID] ?: [[SNContact alloc] initWithSessionID:self.sessionID];
contact.displayName = [profileName ows_stripped];
contact.profilePictureURL = avatarUrlPath;
contact.profilePictureFileName = avatarFileName;
[LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[LKStorage.shared setContact:contact usingTransaction:transaction];
}];
}
- (void)updateWithProfileName:(nullable NSString *)profileName
@ -302,6 +327,13 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId";
functionName:__PRETTY_FUNCTION__
dbConnection:dbConnection
completion:completion];
SNContact *contact = [LKStorage.shared getContactWithSessionID:self.sessionID] ?: [[SNContact alloc] initWithSessionID:self.sessionID];
contact.displayName = [profileName ows_stripped];
contact.profilePictureURL = avatarUrlPath;
[LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[LKStorage.shared setContact:contact usingTransaction:transaction];
}];
}
- (void)updateWithAvatarUrlPath:(nullable NSString *)avatarUrlPath
@ -318,6 +350,13 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId";
functionName:__PRETTY_FUNCTION__
dbConnection:dbConnection
completion:completion];
SNContact *contact = [LKStorage.shared getContactWithSessionID:self.sessionID] ?: [[SNContact alloc] initWithSessionID:self.sessionID];
contact.profilePictureURL = avatarUrlPath;
contact.profilePictureFileName = avatarFileName;
[LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[LKStorage.shared setContact:contact usingTransaction:transaction];
}];
}
- (void)updateWithAvatarFileName:(nullable NSString *)avatarFileName
@ -330,6 +369,12 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId";
functionName:__PRETTY_FUNCTION__
dbConnection:dbConnection
completion:completion];
SNContact *contact = [LKStorage.shared getContactWithSessionID:self.sessionID] ?: [[SNContact alloc] initWithSessionID:self.sessionID];
contact.profilePictureFileName = avatarFileName;
[LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[LKStorage.shared setContact:contact usingTransaction:transaction];
}];
}
- (void)clearWithProfileKey:(OWSAES256Key *)profileKey
@ -368,6 +413,10 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId";
functionName:__PRETTY_FUNCTION__
transaction:transaction
completion:completion];
SNContact *contact = [LKStorage.shared getContactWithSessionID:self.sessionID] ?: [[SNContact alloc] initWithSessionID:self.sessionID];
contact.profilePictureEncryptionKey = profileKey;
[LKStorage.shared setContact:contact usingTransaction:transaction];
}
#pragma mark - Database Connection Accessors

View File

@ -3,7 +3,9 @@ import SessionUtilitiesKit
@objc(SNSnodeAPI)
public final class SnodeAPI : NSObject {
private static var hasLoadedSnodePool = false
private static var loadedSwarms: Set<String> = []
/// - Note: Should only be accessed from `Threading.workQueue` to avoid race conditions.
internal static var snodeFailureCount: [Snode:UInt] = [:]
/// - Note: Should only be accessed from `Threading.workQueue` to avoid race conditions.
@ -11,12 +13,10 @@ public final class SnodeAPI : NSObject {
/// - Note: Should only be accessed from `Threading.workQueue` to avoid race conditions.
public static var swarmCache: [String:Set<Snode>] = [:]
public static var workQueue: DispatchQueue { Threading.workQueue } // Just to make things fit with legacy code
// MARK: Settings
private static let maxRetryCount: UInt = 8
private static let minimumSnodePoolCount = 64
private static let minimumSwarmSnodeCount = 2
private static let minimumSwarmSnodeCount = 3
private static let seedNodePool: Set<String> = [ "https://storage.seed1.loki.network", "https://storage.seed3.loki.network", "https://public.loki.foundation" ]
private static let snodeFailureThreshold = 3
private static let targetSwarmSnodeCount = 2
@ -30,13 +30,13 @@ public final class SnodeAPI : NSObject {
public enum Error : LocalizedError {
case generic
case clockOutOfSync
case randomSnodePoolUpdatingFailed
case snodePoolUpdatingFailed
public var errorDescription: String? {
switch self {
case .generic: return "An error occurred."
case .clockOutOfSync: return "Your clock is out of sync with the service node network."
case .randomSnodePoolUpdatingFailed: return "Failed to update random service node pool."
case .snodePoolUpdatingFailed: return "Failed to update random service node pool."
}
}
}
@ -46,8 +46,68 @@ public final class SnodeAPI : NSObject {
public typealias RawResponse = Any
public typealias RawResponsePromise = Promise<RawResponse>
// MARK: Snode Pool Interaction
private static func loadSnodePoolIfNeeded() {
guard !hasLoadedSnodePool else { return }
snodePool = SNSnodeKitConfiguration.shared.storage.getSnodePool()
hasLoadedSnodePool = true
}
private static func setSnodePool(to newValue: Set<Snode>, persist: Bool = true) {
#if DEBUG
dispatchPrecondition(condition: .onQueue(Threading.workQueue))
#endif
snodePool = newValue
guard persist else { return }
SNSnodeKitConfiguration.shared.storage.writeSync { transaction in
SNSnodeKitConfiguration.shared.storage.setSnodePool(to: newValue, using: transaction)
}
}
private static func dropSnodeFromSnodePool(_ snode: Snode) {
#if DEBUG
dispatchPrecondition(condition: .onQueue(Threading.workQueue))
#endif
var snodePool = SnodeAPI.snodePool
snodePool.remove(snode)
setSnodePool(to: snodePool)
}
@objc public static func clearSnodePool() {
snodePool.removeAll()
setSnodePool(to: [])
}
// MARK: Swarm Interaction
private static func loadSwarmIfNeeded(for publicKey: String) {
guard !loadedSwarms.contains(publicKey) else { return }
swarmCache[publicKey] = SNSnodeKitConfiguration.shared.storage.getSwarm(for: publicKey)
loadedSwarms.insert(publicKey)
}
private static func setSwarm(to newValue: Set<Snode>, for publicKey: String, persist: Bool = true) {
#if DEBUG
dispatchPrecondition(condition: .onQueue(Threading.workQueue))
#endif
swarmCache[publicKey] = newValue
guard persist else { return }
SNSnodeKitConfiguration.shared.storage.writeSync { transaction in
SNSnodeKitConfiguration.shared.storage.setSwarm(to: newValue, for: publicKey, using: transaction)
}
}
public static func dropSnodeFromSwarmIfNeeded(_ snode: Snode, publicKey: String) {
#if DEBUG
dispatchPrecondition(condition: .onQueue(Threading.workQueue))
#endif
let swarmOrNil = swarmCache[publicKey]
guard var swarm = swarmOrNil, let index = swarm.firstIndex(of: snode) else { return }
swarm.remove(at: index)
setSwarm(to: swarm, for: publicKey)
}
// MARK: Internal API
public static func invoke(_ method: Snode.Method, on snode: Snode, associatedWith publicKey: String, parameters: JSON) -> RawResponsePromise {
internal static func invoke(_ method: Snode.Method, on snode: Snode, associatedWith publicKey: String, parameters: JSON) -> RawResponsePromise {
if useOnionRequests {
return OnionRequestAPI.sendOnionRequest(to: snode, invoking: method, with: parameters, associatedWith: publicKey).map2 { $0 as Any }
} else {
@ -58,14 +118,12 @@ public final class SnodeAPI : NSObject {
}
}
}
internal static func getRandomSnode() -> Promise<Snode> {
if snodePool.count < minimumSnodePoolCount {
snodePool = SNSnodeKitConfiguration.shared.storage.getSnodePool()
}
loadSnodePoolIfNeeded()
let now = Date()
let isSnodePoolExpired = given(Storage.shared.getLastSnodePoolRefreshDate()) { now.timeIntervalSince($0) > 24 * 60 * 60 } ?? true
let isRefreshNeeded = (snodePool.count < minimumSnodePoolCount) || isSnodePoolExpired
let isRefreshNeeded = (snodePool.isEmpty || isSnodePoolExpired)
if isRefreshNeeded {
SNSnodeKitConfiguration.shared.storage.write { transaction in
Storage.shared.setLastSnodePoolRefreshDate(to: now, using: transaction)
@ -86,28 +144,26 @@ public final class SnodeAPI : NSObject {
Threading.workQueue.async {
attempt(maxRetryCount: 4, recoveringOn: Threading.workQueue) {
HTTP.execute(.post, url, parameters: parameters, useSSLURLSession: true).map2 { json -> Snode in
guard let intermediate = json["result"] as? JSON, let rawSnodes = intermediate["service_node_states"] as? [JSON] else { throw Error.randomSnodePoolUpdatingFailed }
snodePool = Set(rawSnodes.compactMap { rawSnode in
guard let intermediate = json["result"] as? JSON, let rawSnodes = intermediate["service_node_states"] as? [JSON] else { throw Error.snodePoolUpdatingFailed }
let snodePool: Set<Snode> = Set(rawSnodes.compactMap { rawSnode in
guard let address = rawSnode["public_ip"] as? String, let port = rawSnode["storage_port"] as? Int,
let ed25519PublicKey = rawSnode["pubkey_ed25519"] as? String, let x25519PublicKey = rawSnode["pubkey_x25519"] as? String, address != "0.0.0.0" else {
SNLog("Failed to parse target from: \(rawSnode).")
SNLog("Failed to parse snode from: \(rawSnode).")
return nil
}
return Snode(address: "https://\(address)", port: UInt16(port), publicKeySet: Snode.KeySet(ed25519Key: ed25519PublicKey, x25519Key: x25519PublicKey))
})
setSnodePool(to: snodePool)
// randomElement() uses the system's default random generator, which is cryptographically secure
if !snodePool.isEmpty {
return snodePool.randomElement()!
} else {
throw Error.randomSnodePoolUpdatingFailed
throw Error.snodePoolUpdatingFailed
}
}
}.done2 { snode in
SNLog("Successfully updated snode pool.")
seal.fulfill(snode)
SNSnodeKitConfiguration.shared.storage.writeSync { transaction in
SNLog("Persisting snode pool to database.")
SNSnodeKitConfiguration.shared.storage.setSnodePool(to: SnodeAPI.snodePool, using: transaction)
}
}.catch2 { error in
SNLog("Failed to contact seed node at: \(target).")
seal.reject(error)
@ -122,50 +178,15 @@ public final class SnodeAPI : NSObject {
}
}
internal static func dropSnodeFromSnodePool(_ snode: Snode) {
#if DEBUG
dispatchPrecondition(condition: .onQueue(Threading.workQueue))
#endif
var snodePool = SnodeAPI.snodePool
snodePool.remove(snode)
SnodeAPI.snodePool = snodePool
SNSnodeKitConfiguration.shared.storage.writeSync { transaction in
SNSnodeKitConfiguration.shared.storage.setSnodePool(to: snodePool, using: transaction)
}
}
// MARK: Public API
@objc public static func clearSnodePool() {
snodePool.removeAll()
SNSnodeKitConfiguration.shared.storage.writeSync { transaction in
SNSnodeKitConfiguration.shared.storage.setSnodePool(to: [], using: transaction)
}
}
public static func dropSnodeFromSwarmIfNeeded(_ snode: Snode, publicKey: String) {
#if DEBUG
dispatchPrecondition(condition: .onQueue(Threading.workQueue))
#endif
let swarm = SnodeAPI.swarmCache[publicKey]
if var swarm = swarm, let index = swarm.firstIndex(of: snode) {
swarm.remove(at: index)
SnodeAPI.swarmCache[publicKey] = swarm
SNSnodeKitConfiguration.shared.storage.writeSync { transaction in
SNSnodeKitConfiguration.shared.storage.setSwarm(to: swarm, for: publicKey, using: transaction)
}
}
}
public static func getTargetSnodes(for publicKey: String) -> Promise<[Snode]> {
// shuffled() uses the system's default random generator, which is cryptographically secure
return getSwarm(for: publicKey).map2 { Array($0.shuffled().prefix(targetSwarmSnodeCount)) }
}
public static func getSwarm(for publicKey: String, isForcedReload: Bool = false) -> Promise<Set<Snode>> {
if swarmCache[publicKey] == nil {
swarmCache[publicKey] = SNSnodeKitConfiguration.shared.storage.getSwarm(for: publicKey)
}
if let cachedSwarm = swarmCache[publicKey], cachedSwarm.count >= minimumSwarmSnodeCount && !isForcedReload {
public static func getSwarm(for publicKey: String) -> Promise<Set<Snode>> {
loadSwarmIfNeeded(for: publicKey)
if let cachedSwarm = swarmCache[publicKey], cachedSwarm.count >= minimumSwarmSnodeCount {
return Promise<Set<Snode>> { $0.fulfill(cachedSwarm) }
} else {
SNLog("Getting swarm for: \((publicKey == SNSnodeKitConfiguration.shared.storage.getUserPublicKey()) ? "self" : publicKey).")
@ -176,23 +197,24 @@ public final class SnodeAPI : NSObject {
}
}.map2 { rawSnodes in
let swarm = parseSnodes(from: rawSnodes)
swarmCache[publicKey] = swarm
SNSnodeKitConfiguration.shared.storage.writeSync { transaction in
SNSnodeKitConfiguration.shared.storage.setSwarm(to: swarm, for: publicKey, using: transaction)
}
setSwarm(to: swarm, for: publicKey)
return swarm
}
}
}
public static func getRawMessages(from snode: Snode, associatedWith publicKey: String) -> RawResponsePromise {
let (promise, seal) = RawResponsePromise.pending()
let storage = SNSnodeKitConfiguration.shared.storage
storage.writeSync { transaction in
storage.pruneLastMessageHashInfoIfExpired(for: snode, associatedWith: publicKey, using: transaction)
Threading.workQueue.async {
storage.writeSync { transaction in
storage.pruneLastMessageHashInfoIfExpired(for: snode, associatedWith: publicKey, using: transaction)
}
let lastHash = storage.getLastMessageHash(for: snode, associatedWith: publicKey) ?? ""
let parameters = [ "pubKey" : publicKey, "lastHash" : lastHash ]
invoke(.getMessages, on: snode, associatedWith: publicKey, parameters: parameters).done2 { seal.fulfill($0) }.catch2 { seal.reject($0) }
}
let lastHash = storage.getLastMessageHash(for: snode, associatedWith: publicKey) ?? ""
let parameters = [ "pubKey" : publicKey, "lastHash" : lastHash ]
return invoke(.getMessages, on: snode, associatedWith: publicKey, parameters: parameters)
return promise
}
public static func getMessages(for publicKey: String) -> Promise<Set<MessageListPromise>> {

View File

@ -31,8 +31,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (BOOL)protectFileOrFolderAtPath:(NSString *)path
{
return
[self protectFileOrFolderAtPath:path fileProtectionType:NSFileProtectionCompleteUntilFirstUserAuthentication];
return [self protectFileOrFolderAtPath:path fileProtectionType:NSFileProtectionCompleteUntilFirstUserAuthentication];
}
+ (BOOL)protectFileOrFolderAtPath:(NSString *)path fileProtectionType:(NSFileProtectionType)fileProtectionType

View File

@ -2,8 +2,7 @@ import PromiseKit
public extension AnyPromise {
@objc
func retainUntilComplete() {
@objc func retainUntilComplete() {
var retainCycle: AnyPromise? = self
_ = self.ensure {
assert(retainCycle != nil)

View File

@ -125,7 +125,6 @@
455A16DE1F1FEA0000F86704 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 455A16DC1F1FEA0000F86704 /* MetalKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
457F671B20746193000EABCD /* QuotedReplyPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 457F671A20746193000EABCD /* QuotedReplyPreview.swift */; };
45847E871E4283C30080EAB3 /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45847E861E4283C30080EAB3 /* Intents.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
458E38371D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 458E38361D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m */; };
45A2F005204473A3002E978A /* NewMessage.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 45A2F004204473A3002E978A /* NewMessage.aifc */; };
45A663C51F92EC760027B59E /* GroupTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A663C41F92EC760027B59E /* GroupTableViewCell.swift */; };
45A6DAD61EBBF85500893231 /* ReminderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A6DAD51EBBF85500893231 /* ReminderView.swift */; };
@ -283,6 +282,11 @@
B894D0752339EDCF00B4D94D /* NukeDataModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B894D0742339EDCF00B4D94D /* NukeDataModal.swift */; };
B8A14D702589CE9000E70D57 /* KeyPairMigrationSuccessSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8A14D6F2589CE9000E70D57 /* KeyPairMigrationSuccessSheet.swift */; };
B8B26C8F234D629C004ED98C /* MentionCandidateSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8B26C8E234D629C004ED98C /* MentionCandidateSelectionView.swift */; };
B8B32021258B1A650020074B /* Contact.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8B32020258B1A650020074B /* Contact.swift */; };
B8B32033258B235D0020074B /* Storage+Contacts.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8B32032258B235D0020074B /* Storage+Contacts.swift */; };
B8B3204E258C15C80020074B /* ContactsMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8B32044258C117C0020074B /* ContactsMigration.swift */; };
B8B32072258C22200020074B /* DisplayNameUtilities2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8B32071258C22200020074B /* DisplayNameUtilities2.swift */; };
B8B3207B258C22550020074B /* DisplayNameUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8B32067258C22010020074B /* DisplayNameUtilities.swift */; };
B8B320B7258C30D70020074B /* HTMLMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8B320B6258C30D70020074B /* HTMLMetadata.swift */; };
B8BB82A5238F627000BA5194 /* HomeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8BB82A4238F627000BA5194 /* HomeVC.swift */; };
B8BC00C0257D90E30032E807 /* General.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8BC00BF257D90E30032E807 /* General.swift */; };
@ -409,7 +413,6 @@
C32C5EE5256DF506003C73A2 /* YapDatabaseConnection+OWS.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB5F255A580E00E217F9 /* YapDatabaseConnection+OWS.h */; settings = {ATTRIBUTES = (Public, ); }; };
C32C5EEE256DF54E003C73A2 /* TSDatabaseView.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB46255A580C00E217F9 /* TSDatabaseView.m */; };
C32C5EF7256DF567003C73A2 /* TSDatabaseView.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB2C255A580A00E217F9 /* TSDatabaseView.h */; settings = {ATTRIBUTES = (Public, ); }; };
C32C5F08256DF5C8003C73A2 /* DisplayNameUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAFF255A580600E217F9 /* DisplayNameUtilities.swift */; };
C32C5F11256DF79A003C73A2 /* SSKIncrementingIdFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB32255A580A00E217F9 /* SSKIncrementingIdFinder.swift */; };
C32C5F1A256DFCAD003C73A2 /* TSErrorMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAE7255A580500E217F9 /* TSErrorMessage.m */; };
C32C5F23256DFCC0003C73A2 /* TSErrorMessage_privateConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB5D255A580E00E217F9 /* TSErrorMessage_privateConstructor.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -463,45 +466,34 @@
C33FDC2F255A581F00E217F9 /* OWSSyncManagerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDA75255A57FB00E217F9 /* OWSSyncManagerProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDC39255A581F00E217F9 /* OWSRecordTranscriptJob.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA7F255A57FC00E217F9 /* OWSRecordTranscriptJob.m */; };
C33FDC45255A581F00E217F9 /* AppVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA8B255A57FD00E217F9 /* AppVersion.m */; };
C33FDC4F255A582000E217F9 /* OWSChunkedOutputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDA95255A57FE00E217F9 /* OWSChunkedOutputStream.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDC50255A582000E217F9 /* OWSDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDA96255A57FE00E217F9 /* OWSDispatch.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDC52255A582000E217F9 /* RotateSignedKeyOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA98255A57FE00E217F9 /* RotateSignedKeyOperation.swift */; };
C33FDC53255A582000E217F9 /* OutageDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA99255A57FE00E217F9 /* OutageDetection.swift */; };
C33FDC57255A582000E217F9 /* OWSContactsOutputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDA9D255A57FF00E217F9 /* OWSContactsOutputStream.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDC58255A582000E217F9 /* ReverseDispatchQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA9E255A57FF00E217F9 /* ReverseDispatchQueue.swift */; };
C33FDC61255A582000E217F9 /* OWSPrimaryStorage+SignedPreKeyStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDAA7255A57FF00E217F9 /* OWSPrimaryStorage+SignedPreKeyStore.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDC64255A582000E217F9 /* NSObject+Casting.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAAA255A580000E217F9 /* NSObject+Casting.m */; };
C33FDC71255A582000E217F9 /* OWSFailedMessagesJob.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAB7255A580100E217F9 /* OWSFailedMessagesJob.m */; };
C33FDC75255A582000E217F9 /* OWSGroupsOutputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDABB255A580100E217F9 /* OWSGroupsOutputStream.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDC78255A582000E217F9 /* TSConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDABE255A580100E217F9 /* TSConstants.m */; };
C33FDC7B255A582000E217F9 /* NSSet+Functional.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAC1255A580100E217F9 /* NSSet+Functional.m */; };
C33FDC7D255A582000E217F9 /* OWSDispatch.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAC3255A580200E217F9 /* OWSDispatch.m */; };
C33FDC89255A582000E217F9 /* OWSAttachmentDownloads.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDACF255A580300E217F9 /* OWSAttachmentDownloads.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDC92255A582000E217F9 /* OWSGroupsOutputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAD8255A580300E217F9 /* OWSGroupsOutputStream.m */; };
C33FDC95255A582000E217F9 /* OWSFailedMessagesJob.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDADB255A580400E217F9 /* OWSFailedMessagesJob.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDC96255A582000E217F9 /* NSObject+Casting.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDADC255A580400E217F9 /* NSObject+Casting.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDC98255A582000E217F9 /* SwiftSingletons.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDADE255A580400E217F9 /* SwiftSingletons.swift */; };
C33FDC99255A582000E217F9 /* PublicChatManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDADF255A580400E217F9 /* PublicChatManager.swift */; };
C33FDC9A255A582000E217F9 /* ByteParser.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAE0255A580400E217F9 /* ByteParser.m */; };
C33FDCA2255A582000E217F9 /* OWSMessageUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDAE8255A580500E217F9 /* OWSMessageUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDCA3255A582000E217F9 /* SSKMessageSenderJobRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAE9255A580500E217F9 /* SSKMessageSenderJobRecord.m */; };
C33FDCA7255A582000E217F9 /* SSKMessageSenderJobRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDAED255A580500E217F9 /* SSKMessageSenderJobRecord.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDCAD255A582000E217F9 /* OWSPrimaryStorage+SessionStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAF3255A580500E217F9 /* OWSPrimaryStorage+SessionStore.m */; };
C33FDCB1255A582000E217F9 /* OWSPrimaryStorage+SignedPreKeyStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAF7255A580600E217F9 /* OWSPrimaryStorage+SignedPreKeyStore.m */; };
C33FDCBD255A582000E217F9 /* OWSPrimaryStorage+SessionStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB03255A580700E217F9 /* OWSPrimaryStorage+SessionStore.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDCC3255A582000E217F9 /* NSError+MessageSending.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB09255A580700E217F9 /* NSError+MessageSending.m */; };
C33FDCC7255A582000E217F9 /* NSArray+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB0D255A580800E217F9 /* NSArray+OWS.m */; };
C33FDCC8255A582000E217F9 /* NSError+MessageSending.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB0E255A580800E217F9 /* NSError+MessageSending.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDCD1255A582000E217F9 /* FunctionalUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB17255A580800E217F9 /* FunctionalUtil.m */; };
C33FDCD3255A582000E217F9 /* GroupUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB19255A580900E217F9 /* GroupUtilities.swift */; };
C33FDCFA255A582000E217F9 /* SignalIOSProto.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB40255A580C00E217F9 /* SignalIOSProto.swift */; };
C33FDCFE255A582000E217F9 /* OWSContactsOutputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB44255A580C00E217F9 /* OWSContactsOutputStream.m */; };
C33FDD01255A582000E217F9 /* OWSPrimaryStorage+PreKeyStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB47255A580C00E217F9 /* OWSPrimaryStorage+PreKeyStore.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDD03255A582000E217F9 /* WeakTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB49255A580C00E217F9 /* WeakTimer.swift */; };
C33FDD05255A582000E217F9 /* OWSChunkedOutputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB4B255A580C00E217F9 /* OWSChunkedOutputStream.m */; };
C33FDD06255A582000E217F9 /* AppVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB4C255A580D00E217F9 /* AppVersion.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDD0A255A582000E217F9 /* OWSPrimaryStorage+PreKeyStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB50255A580D00E217F9 /* OWSPrimaryStorage+PreKeyStore.m */; };
C33FDD0C255A582000E217F9 /* OWSHTTPSecurityPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB52255A580D00E217F9 /* OWSHTTPSecurityPolicy.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDD0D255A582000E217F9 /* PreKeyBundle+jsonDict.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB53255A580D00E217F9 /* PreKeyBundle+jsonDict.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDD0F255A582000E217F9 /* TSInvalidIdentityKeySendingErrorMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB55255A580D00E217F9 /* TSInvalidIdentityKeySendingErrorMessage.m */; };
C33FDD12255A582000E217F9 /* OWSPrimaryStorage+Loki.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB58255A580E00E217F9 /* OWSPrimaryStorage+Loki.m */; };
@ -526,15 +518,12 @@
C33FDD6E255A582000E217F9 /* NSURLSessionDataTask+StatusCode.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBB4255A581600E217F9 /* NSURLSessionDataTask+StatusCode.m */; };
C33FDD74255A582000E217F9 /* OWSPrimaryStorage+keyFromIntLong.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDBBA255A581600E217F9 /* OWSPrimaryStorage+keyFromIntLong.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDD75255A582000E217F9 /* OWSPrimaryStorage+Loki.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDBBB255A581600E217F9 /* OWSPrimaryStorage+Loki.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDD79255A582000E217F9 /* OWSHTTPSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBBF255A581700E217F9 /* OWSHTTPSecurityPolicy.m */; };
C33FDD7C255A582000E217F9 /* SSKAsserts.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDBC2255A581700E217F9 /* SSKAsserts.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDD83255A582000E217F9 /* CreatePreKeysOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBC9255A581700E217F9 /* CreatePreKeysOperation.swift */; };
C33FDD8D255A582000E217F9 /* OWSSignalAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBD3255A581800E217F9 /* OWSSignalAddress.swift */; };
C33FDD90255A582000E217F9 /* OWSUploadOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDBD6255A581900E217F9 /* OWSUploadOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDD91255A582000E217F9 /* OWSMessageUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBD7255A581900E217F9 /* OWSMessageUtils.m */; };
C33FDD92255A582000E217F9 /* SignalIOS.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBD8255A581900E217F9 /* SignalIOS.pb.swift */; };
C33FDDA9255A582000E217F9 /* TSStorageKeys.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDBEF255A581B00E217F9 /* TSStorageKeys.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDDAE255A582000E217F9 /* DisplayNameUtilities2.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBF4255A581B00E217F9 /* DisplayNameUtilities2.swift */; };
C33FDDB0255A582000E217F9 /* NSURLSessionDataTask+StatusCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDBF6255A581C00E217F9 /* NSURLSessionDataTask+StatusCode.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDDB2255A582000E217F9 /* NSArray+OWS.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDBF8255A581C00E217F9 /* NSArray+OWS.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDDB3255A582000E217F9 /* OWSError.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDBF9255A581C00E217F9 /* OWSError.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -546,7 +535,6 @@
C33FDDCD255A582000E217F9 /* OWSAttachmentDownloads.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDC13255A581E00E217F9 /* OWSAttachmentDownloads.m */; };
C33FDDD0255A582000E217F9 /* FunctionalUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDC16255A581E00E217F9 /* FunctionalUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDDD3255A582000E217F9 /* OWSQueues.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDC19255A581F00E217F9 /* OWSQueues.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDDD8255A582000E217F9 /* OWSUploadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDC1E255A581F00E217F9 /* OWSUploadOperation.m */; };
C33FDDD9255A582000E217F9 /* LokiSessionRestorationImplementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDC1F255A581F00E217F9 /* LokiSessionRestorationImplementation.swift */; };
C33FDEF8255A656D00E217F9 /* Promise+Delaying.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A5D32553860900C340D1 /* Promise+Delaying.swift */; };
C3402FE52559036600EA6424 /* SessionUIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C331FF1B2558F9D300070591 /* SessionUIKit.framework */; };
@ -889,7 +877,6 @@
C3D90A1125773888002C9DF5 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C39DD28724F3318C008590FC /* Colors.xcassets */; };
C3D90A5C25773A25002C9DF5 /* SessionUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A679255388CC00C340D1 /* SessionUtilitiesKit.framework */; };
C3D90A7A25773A93002C9DF5 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F0A5EB255C970D007BE2A3 /* Configuration.swift */; };
C3D90A8325774A68002C9DF5 /* OWSPrimaryStorageProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D9E41E25676C870040E4F3 /* OWSPrimaryStorageProtocol.swift */; };
C3D9E35525675EE10040E4F3 /* MIMETypeUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB41255A580C00E217F9 /* MIMETypeUtil.m */; };
C3D9E35E25675F640040E4F3 /* OWSFileSystem.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA8E255A57FD00E217F9 /* OWSFileSystem.m */; };
C3D9E379256760340040E4F3 /* MIMETypeUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDAFC255A580600E217F9 /* MIMETypeUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -1225,8 +1212,6 @@
455A16DC1F1FEA0000F86704 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; };
457F671A20746193000EABCD /* QuotedReplyPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuotedReplyPreview.swift; sourceTree = "<group>"; };
45847E861E4283C30080EAB3 /* Intents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Intents.framework; path = System/Library/Frameworks/Intents.framework; sourceTree = SDKROOT; };
458E38351D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSDeviceProvisioningURLParser.h; sourceTree = "<group>"; };
458E38361D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDeviceProvisioningURLParser.m; sourceTree = "<group>"; };
45A2F004204473A3002E978A /* NewMessage.aifc */ = {isa = PBXFileReference; lastKnownFileType = file; name = NewMessage.aifc; path = Session/Meta/AudioFiles/NewMessage.aifc; sourceTree = SOURCE_ROOT; };
45A663C41F92EC760027B59E /* GroupTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupTableViewCell.swift; sourceTree = "<group>"; };
45A6DAD51EBBF85500893231 /* ReminderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReminderView.swift; sourceTree = "<group>"; };
@ -1393,6 +1378,11 @@
B894D0742339EDCF00B4D94D /* NukeDataModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NukeDataModal.swift; sourceTree = "<group>"; };
B8A14D6F2589CE9000E70D57 /* KeyPairMigrationSuccessSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPairMigrationSuccessSheet.swift; sourceTree = "<group>"; };
B8B26C8E234D629C004ED98C /* MentionCandidateSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentionCandidateSelectionView.swift; sourceTree = "<group>"; };
B8B32020258B1A650020074B /* Contact.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contact.swift; sourceTree = "<group>"; };
B8B32032258B235D0020074B /* Storage+Contacts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Storage+Contacts.swift"; sourceTree = "<group>"; };
B8B32044258C117C0020074B /* ContactsMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactsMigration.swift; sourceTree = "<group>"; };
B8B32067258C22010020074B /* DisplayNameUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayNameUtilities.swift; sourceTree = "<group>"; };
B8B32071258C22200020074B /* DisplayNameUtilities2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayNameUtilities2.swift; sourceTree = "<group>"; };
B8B320B6258C30D70020074B /* HTMLMetadata.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTMLMetadata.swift; sourceTree = "<group>"; };
B8B5BCEB2394D869003823C9 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = "<group>"; };
B8BB829F238F322400BA5194 /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
@ -1482,12 +1472,10 @@
C33FDA8C255A57FD00E217F9 /* OpenGroupPoller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenGroupPoller.swift; sourceTree = "<group>"; };
C33FDA8E255A57FD00E217F9 /* OWSFileSystem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSFileSystem.m; sourceTree = "<group>"; };
C33FDA90255A57FD00E217F9 /* TSYapDatabaseObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSYapDatabaseObject.m; sourceTree = "<group>"; };
C33FDA95255A57FE00E217F9 /* OWSChunkedOutputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSChunkedOutputStream.h; sourceTree = "<group>"; };
C33FDA96255A57FE00E217F9 /* OWSDispatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSDispatch.h; sourceTree = "<group>"; };
C33FDA97255A57FE00E217F9 /* TSIncomingMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSIncomingMessage.m; sourceTree = "<group>"; };
C33FDA98255A57FE00E217F9 /* RotateSignedKeyOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RotateSignedKeyOperation.swift; sourceTree = "<group>"; };
C33FDA99255A57FE00E217F9 /* OutageDetection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutageDetection.swift; sourceTree = "<group>"; };
C33FDA9D255A57FF00E217F9 /* OWSContactsOutputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSContactsOutputStream.h; sourceTree = "<group>"; };
C33FDA9E255A57FF00E217F9 /* ReverseDispatchQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReverseDispatchQueue.swift; sourceTree = "<group>"; };
C33FDAA0255A57FF00E217F9 /* OWSRecipientIdentity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSRecipientIdentity.h; sourceTree = "<group>"; };
C33FDAA1255A57FF00E217F9 /* TSYapDatabaseObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSYapDatabaseObject.h; sourceTree = "<group>"; };
@ -1499,7 +1487,6 @@
C33FDAB7255A580100E217F9 /* OWSFailedMessagesJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSFailedMessagesJob.m; sourceTree = "<group>"; };
C33FDAB8255A580100E217F9 /* NSArray+Functional.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Functional.m"; sourceTree = "<group>"; };
C33FDAB9255A580100E217F9 /* OWSStorage+Subclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OWSStorage+Subclass.h"; sourceTree = "<group>"; };
C33FDABB255A580100E217F9 /* OWSGroupsOutputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSGroupsOutputStream.h; sourceTree = "<group>"; };
C33FDABD255A580100E217F9 /* OWSOutgoingReceiptManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSOutgoingReceiptManager.h; sourceTree = "<group>"; };
C33FDABE255A580100E217F9 /* TSConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSConstants.m; sourceTree = "<group>"; };
C33FDAC0255A580100E217F9 /* OWSIncomingMessageFinder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSIncomingMessageFinder.h; sourceTree = "<group>"; };
@ -1511,7 +1498,6 @@
C33FDACF255A580300E217F9 /* OWSAttachmentDownloads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSAttachmentDownloads.h; sourceTree = "<group>"; };
C33FDAD3255A580300E217F9 /* TSThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSThread.h; sourceTree = "<group>"; };
C33FDAD5255A580300E217F9 /* TSQuotedMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSQuotedMessage.h; sourceTree = "<group>"; };
C33FDAD8255A580300E217F9 /* OWSGroupsOutputStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSGroupsOutputStream.m; sourceTree = "<group>"; };
C33FDAD9255A580300E217F9 /* OWSDisappearingMessagesConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSDisappearingMessagesConfiguration.h; sourceTree = "<group>"; };
C33FDADA255A580400E217F9 /* OWSDisappearingConfigurationUpdateInfoMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSDisappearingConfigurationUpdateInfoMessage.h; sourceTree = "<group>"; };
C33FDADB255A580400E217F9 /* OWSFailedMessagesJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSFailedMessagesJob.h; sourceTree = "<group>"; };
@ -1525,10 +1511,8 @@
C33FDAE6255A580400E217F9 /* TSInteraction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSInteraction.h; sourceTree = "<group>"; };
C33FDAE7255A580500E217F9 /* TSErrorMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSErrorMessage.m; sourceTree = "<group>"; };
C33FDAE8255A580500E217F9 /* OWSMessageUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessageUtils.h; sourceTree = "<group>"; };
C33FDAE9255A580500E217F9 /* SSKMessageSenderJobRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSKMessageSenderJobRecord.m; sourceTree = "<group>"; };
C33FDAEA255A580500E217F9 /* OWSBackupFragment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupFragment.h; sourceTree = "<group>"; };
C33FDAEC255A580500E217F9 /* SignalRecipient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SignalRecipient.h; sourceTree = "<group>"; };
C33FDAED255A580500E217F9 /* SSKMessageSenderJobRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSKMessageSenderJobRecord.h; sourceTree = "<group>"; };
C33FDAEF255A580500E217F9 /* NSData+Image.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Image.m"; sourceTree = "<group>"; };
C33FDAF1255A580500E217F9 /* OWSThumbnailService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSThumbnailService.swift; sourceTree = "<group>"; };
C33FDAF2255A580500E217F9 /* ProxiedContentDownloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProxiedContentDownloader.swift; sourceTree = "<group>"; };
@ -1539,14 +1523,11 @@
C33FDAFC255A580600E217F9 /* MIMETypeUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIMETypeUtil.h; sourceTree = "<group>"; };
C33FDAFD255A580600E217F9 /* LRUCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LRUCache.swift; sourceTree = "<group>"; };
C33FDAFE255A580600E217F9 /* OWSStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSStorage.h; sourceTree = "<group>"; };
C33FDAFF255A580600E217F9 /* DisplayNameUtilities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayNameUtilities.swift; sourceTree = "<group>"; };
C33FDB01255A580700E217F9 /* AppReadiness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppReadiness.h; sourceTree = "<group>"; };
C33FDB03255A580700E217F9 /* OWSPrimaryStorage+SessionStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OWSPrimaryStorage+SessionStore.h"; sourceTree = "<group>"; };
C33FDB07255A580700E217F9 /* OWSBackupFragment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupFragment.m; sourceTree = "<group>"; };
C33FDB09255A580700E217F9 /* NSError+MessageSending.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSError+MessageSending.m"; sourceTree = "<group>"; };
C33FDB0A255A580700E217F9 /* TSGroupModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSGroupModel.h; sourceTree = "<group>"; };
C33FDB0D255A580800E217F9 /* NSArray+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+OWS.m"; sourceTree = "<group>"; };
C33FDB0E255A580800E217F9 /* NSError+MessageSending.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+MessageSending.h"; sourceTree = "<group>"; };
C33FDB12255A580800E217F9 /* NSString+SSK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+SSK.h"; sourceTree = "<group>"; };
C33FDB14255A580800E217F9 /* OWSMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMath.h; sourceTree = "<group>"; };
C33FDB17255A580800E217F9 /* FunctionalUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FunctionalUtil.m; sourceTree = "<group>"; };
@ -1570,18 +1551,15 @@
C33FDB40255A580C00E217F9 /* SignalIOSProto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalIOSProto.swift; sourceTree = "<group>"; };
C33FDB41255A580C00E217F9 /* MIMETypeUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MIMETypeUtil.m; sourceTree = "<group>"; };
C33FDB43255A580C00E217F9 /* YapDatabaseConnection+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "YapDatabaseConnection+OWS.m"; sourceTree = "<group>"; };
C33FDB44255A580C00E217F9 /* OWSContactsOutputStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactsOutputStream.m; sourceTree = "<group>"; };
C33FDB45255A580C00E217F9 /* NSString+SSK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+SSK.m"; sourceTree = "<group>"; };
C33FDB46255A580C00E217F9 /* TSDatabaseView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSDatabaseView.m; sourceTree = "<group>"; };
C33FDB47255A580C00E217F9 /* OWSPrimaryStorage+PreKeyStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OWSPrimaryStorage+PreKeyStore.h"; sourceTree = "<group>"; };
C33FDB48255A580C00E217F9 /* TSOutgoingMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSOutgoingMessage.h; sourceTree = "<group>"; };
C33FDB49255A580C00E217F9 /* WeakTimer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeakTimer.swift; sourceTree = "<group>"; };
C33FDB4B255A580C00E217F9 /* OWSChunkedOutputStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSChunkedOutputStream.m; sourceTree = "<group>"; };
C33FDB4C255A580D00E217F9 /* AppVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppVersion.h; sourceTree = "<group>"; };
C33FDB4F255A580D00E217F9 /* SSKJobRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSKJobRecord.h; sourceTree = "<group>"; };
C33FDB50255A580D00E217F9 /* OWSPrimaryStorage+PreKeyStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "OWSPrimaryStorage+PreKeyStore.m"; sourceTree = "<group>"; };
C33FDB51255A580D00E217F9 /* NSUserDefaults+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSUserDefaults+OWS.h"; sourceTree = "<group>"; };
C33FDB52255A580D00E217F9 /* OWSHTTPSecurityPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSHTTPSecurityPolicy.h; sourceTree = "<group>"; };
C33FDB53255A580D00E217F9 /* PreKeyBundle+jsonDict.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "PreKeyBundle+jsonDict.h"; sourceTree = "<group>"; };
C33FDB54255A580D00E217F9 /* DataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataSource.h; sourceTree = "<group>"; };
C33FDB55255A580D00E217F9 /* TSInvalidIdentityKeySendingErrorMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSInvalidIdentityKeySendingErrorMessage.m; sourceTree = "<group>"; };
@ -1645,14 +1623,12 @@
C33FDBBA255A581600E217F9 /* OWSPrimaryStorage+keyFromIntLong.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OWSPrimaryStorage+keyFromIntLong.h"; sourceTree = "<group>"; };
C33FDBBB255A581600E217F9 /* OWSPrimaryStorage+Loki.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OWSPrimaryStorage+Loki.h"; sourceTree = "<group>"; };
C33FDBBC255A581600E217F9 /* SSKKeychainStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SSKKeychainStorage.swift; sourceTree = "<group>"; };
C33FDBBF255A581700E217F9 /* OWSHTTPSecurityPolicy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSHTTPSecurityPolicy.m; sourceTree = "<group>"; };
C33FDBC1255A581700E217F9 /* General.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = General.swift; sourceTree = "<group>"; };
C33FDBC2255A581700E217F9 /* SSKAsserts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSKAsserts.h; sourceTree = "<group>"; };
C33FDBC9255A581700E217F9 /* CreatePreKeysOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreatePreKeysOperation.swift; sourceTree = "<group>"; };
C33FDBCA255A581700E217F9 /* LKGroupUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LKGroupUtilities.h; sourceTree = "<group>"; };
C33FDBCB255A581800E217F9 /* TSInvalidIdentityKeyReceivingErrorMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSInvalidIdentityKeyReceivingErrorMessage.m; sourceTree = "<group>"; };
C33FDBD3255A581800E217F9 /* OWSSignalAddress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSSignalAddress.swift; sourceTree = "<group>"; };
C33FDBD6255A581900E217F9 /* OWSUploadOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSUploadOperation.h; sourceTree = "<group>"; };
C33FDBD7255A581900E217F9 /* OWSMessageUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSMessageUtils.m; sourceTree = "<group>"; };
C33FDBD8255A581900E217F9 /* SignalIOS.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalIOS.pb.swift; sourceTree = "<group>"; };
C33FDBDD255A581900E217F9 /* OWSDisappearingMessagesJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDisappearingMessagesJob.m; sourceTree = "<group>"; };
@ -1663,7 +1639,6 @@
C33FDBEC255A581B00E217F9 /* OWSRecipientIdentity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSRecipientIdentity.m; sourceTree = "<group>"; };
C33FDBEF255A581B00E217F9 /* TSStorageKeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSStorageKeys.h; sourceTree = "<group>"; };
C33FDBF1255A581B00E217F9 /* OWSIdentityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSIdentityManager.h; sourceTree = "<group>"; };
C33FDBF4255A581B00E217F9 /* DisplayNameUtilities2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayNameUtilities2.swift; sourceTree = "<group>"; };
C33FDBF6255A581C00E217F9 /* NSURLSessionDataTask+StatusCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLSessionDataTask+StatusCode.h"; sourceTree = "<group>"; };
C33FDBF8255A581C00E217F9 /* NSArray+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+OWS.h"; sourceTree = "<group>"; };
C33FDBF9255A581C00E217F9 /* OWSError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSError.h; sourceTree = "<group>"; };
@ -1682,7 +1657,6 @@
C33FDC18255A581F00E217F9 /* TSAttachmentPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSAttachmentPointer.h; sourceTree = "<group>"; };
C33FDC19255A581F00E217F9 /* OWSQueues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSQueues.h; sourceTree = "<group>"; };
C33FDC1B255A581F00E217F9 /* OWSBackgroundTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackgroundTask.m; sourceTree = "<group>"; };
C33FDC1E255A581F00E217F9 /* OWSUploadOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSUploadOperation.m; sourceTree = "<group>"; };
C33FDC1F255A581F00E217F9 /* LokiSessionRestorationImplementation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LokiSessionRestorationImplementation.swift; sourceTree = "<group>"; };
C3471ECA2555356A00297E91 /* MessageSender+Encryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageSender+Encryption.swift"; sourceTree = "<group>"; };
C3471F4B25553AB000297E91 /* MessageReceiver+Decryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageReceiver+Decryption.swift"; sourceTree = "<group>"; };
@ -1725,14 +1699,14 @@
C38EF226255B6D5D007E1867 /* ShareViewDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ShareViewDelegate.swift; path = SignalUtilitiesKit/Utilities/ShareViewDelegate.swift; sourceTree = SOURCE_ROOT; };
C38EF227255B6D5D007E1867 /* OWSVideoPlayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = OWSVideoPlayer.swift; path = SignalUtilitiesKit/Utilities/OWSVideoPlayer.swift; sourceTree = SOURCE_ROOT; };
C38EF236255B6D65007E1867 /* UIViewController+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIViewController+OWS.h"; path = "SignalUtilitiesKit/UI/UIViewController+OWS.h"; sourceTree = SOURCE_ROOT; };
C38EF237255B6D65007E1867 /* UIDevice+featureSupport.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIDevice+featureSupport.swift"; path = "SessionUtilitiesKit/UIDevice+featureSupport.swift"; sourceTree = SOURCE_ROOT; };
C38EF237255B6D65007E1867 /* UIDevice+featureSupport.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIDevice+featureSupport.swift"; path = "SessionUtilitiesKit/General/UIDevice+featureSupport.swift"; sourceTree = SOURCE_ROOT; };
C38EF238255B6D66007E1867 /* UIFont+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIFont+OWS.m"; path = "SignalUtilitiesKit/UI/UIFont+OWS.m"; sourceTree = SOURCE_ROOT; };
C38EF239255B6D66007E1867 /* UIFont+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIFont+OWS.h"; path = "SignalUtilitiesKit/UI/UIFont+OWS.h"; sourceTree = SOURCE_ROOT; };
C38EF23A255B6D66007E1867 /* NSAttributedString+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSAttributedString+OWS.m"; path = "SignalUtilitiesKit/Utilities/NSAttributedString+OWS.m"; sourceTree = SOURCE_ROOT; };
C38EF23B255B6D66007E1867 /* UIViewController+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIViewController+OWS.m"; path = "SignalUtilitiesKit/UI/UIViewController+OWS.m"; sourceTree = SOURCE_ROOT; };
C38EF23C255B6D66007E1867 /* UIColor+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIColor+OWS.h"; path = "SignalUtilitiesKit/UI/UIColor+OWS.h"; sourceTree = SOURCE_ROOT; };
C38EF23D255B6D66007E1867 /* UIView+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIView+OWS.h"; path = "SessionUtilitiesKit/UIView+OWS.h"; sourceTree = SOURCE_ROOT; };
C38EF23E255B6D66007E1867 /* UIView+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIView+OWS.m"; path = "SessionUtilitiesKit/UIView+OWS.m"; sourceTree = SOURCE_ROOT; };
C38EF23D255B6D66007E1867 /* UIView+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIView+OWS.h"; path = "SessionUtilitiesKit/General/UIView+OWS.h"; sourceTree = SOURCE_ROOT; };
C38EF23E255B6D66007E1867 /* UIView+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIView+OWS.m"; path = "SessionUtilitiesKit/General/UIView+OWS.m"; sourceTree = SOURCE_ROOT; };
C38EF23F255B6D67007E1867 /* NSAttributedString+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSAttributedString+OWS.h"; path = "SignalUtilitiesKit/Utilities/NSAttributedString+OWS.h"; sourceTree = SOURCE_ROOT; };
C38EF240255B6D67007E1867 /* UIView+OWS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIView+OWS.swift"; path = "SignalUtilitiesKit/UI/UIView+OWS.swift"; sourceTree = SOURCE_ROOT; };
C38EF241255B6D67007E1867 /* Collection+OWS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Collection+OWS.swift"; path = "SignalUtilitiesKit/Utilities/Collection+OWS.swift"; sourceTree = SOURCE_ROOT; };
@ -1772,7 +1746,7 @@
C38EF2E9255B6DBA007E1867 /* OWSUnreadIndicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWSUnreadIndicator.h; path = SignalUtilitiesKit/OWSUnreadIndicator.h; sourceTree = SOURCE_ROOT; };
C38EF2EC255B6DBA007E1867 /* ProximityMonitoringManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ProximityMonitoringManager.swift; path = SessionMessagingKit/Utilities/ProximityMonitoringManager.swift; sourceTree = SOURCE_ROOT; };
C38EF2ED255B6DBB007E1867 /* DisplayableText.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DisplayableText.swift; path = SignalUtilitiesKit/UI/DisplayableText.swift; sourceTree = SOURCE_ROOT; };
C38EF2EF255B6DBB007E1867 /* Weak.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Weak.swift; path = SessionUtilitiesKit/Weak.swift; sourceTree = SOURCE_ROOT; };
C38EF2EF255B6DBB007E1867 /* Weak.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Weak.swift; path = SessionUtilitiesKit/General/Weak.swift; sourceTree = SOURCE_ROOT; };
C38EF2F0255B6DBB007E1867 /* OWSAnyTouchGestureRecognizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSAnyTouchGestureRecognizer.m; path = SignalUtilitiesKit/UI/OWSAnyTouchGestureRecognizer.m; sourceTree = SOURCE_ROOT; };
C38EF2F1255B6DBB007E1867 /* OWSPreferences.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWSPreferences.h; path = SessionMessagingKit/Utilities/OWSPreferences.h; sourceTree = SOURCE_ROOT; };
C38EF2F2255B6DBC007E1867 /* Searcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Searcher.swift; path = SignalUtilitiesKit/Searcher.swift; sourceTree = SOURCE_ROOT; };
@ -2382,8 +2356,6 @@
4CEB78C72178EBAB00F315D2 /* OWSSessionResetJobRecord.h */,
4CEB78C82178EBAB00F315D2 /* OWSSessionResetJobRecord.m */,
451166BF1FD86B98000739BA /* AccountManager.swift */,
458E38351D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.h */,
458E38361D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m */,
4CB5F26820F7D060004D1B42 /* MessageActions.swift */,
451A13B01E13DED2000A50FD /* AppNotifications.swift */,
450DF2081E0DD2C6003D14BE /* UserNotificationsAdaptee.swift */,
@ -2581,6 +2553,125 @@
path = ..;
sourceTree = "<group>";
};
B8A582AB258C64E800AFD84C /* Database */ = {
isa = PBXGroup;
children = (
C33FDBAB255A581500E217F9 /* OWSFileSystem.h */,
C33FDA8E255A57FD00E217F9 /* OWSFileSystem.m */,
C3D9E41E25676C870040E4F3 /* OWSPrimaryStorageProtocol.swift */,
C33FDBBC255A581600E217F9 /* SSKKeychainStorage.swift */,
C33FDB36255A580B00E217F9 /* Storage.swift */,
C33FDAA1255A57FF00E217F9 /* TSYapDatabaseObject.h */,
C33FDA90255A57FD00E217F9 /* TSYapDatabaseObject.m */,
);
path = Database;
sourceTree = "<group>";
};
B8A582AC258C653C00AFD84C /* Crypto */ = {
isa = PBXGroup;
children = (
C3C2A5D72553860B00C340D1 /* AESGCM.swift */,
C3C2ABD12553C6C900C340D1 /* Data+SecureRandom.swift */,
C3A71D662558A0170043A11F /* DiffieHellman.swift */,
C33FDA73255A57FA00E217F9 /* ECKeyPair+Hexadecimal.swift */,
C3A71F882558BA9F0043A11F /* Mnemonic.swift */,
);
path = Crypto;
sourceTree = "<group>";
};
B8A582AD258C655E00AFD84C /* PromiseKit */ = {
isa = PBXGroup;
children = (
C3A721992558C1660043A11F /* AnyPromise+Conversion.swift */,
C3C2A5D32553860900C340D1 /* Promise+Delaying.swift */,
C3A7225D2558C38D0043A11F /* Promise+Retaining.swift */,
C3C2A5D62553860B00C340D1 /* Promise+Retrying.swift */,
);
path = PromiseKit;
sourceTree = "<group>";
};
B8A582AE258C65D000AFD84C /* Networking */ = {
isa = PBXGroup;
children = (
C33FDB68255A580F00E217F9 /* ContentProxy.swift */,
C3C2A5BC255385EE00C340D1 /* HTTP.swift */,
C3C2A5D92553860B00C340D1 /* JSON.swift */,
C33FDAF2255A580500E217F9 /* ProxiedContentDownloader.swift */,
C352A3A42557B5F000338F3E /* TSRequest.h */,
C352A3A52557B60D00338F3E /* TSRequest.m */,
);
path = Networking;
sourceTree = "<group>";
};
B8A582AF258C665E00AFD84C /* Media */ = {
isa = PBXGroup;
children = (
C33FDB54255A580D00E217F9 /* DataSource.h */,
C33FDBB6255A581600E217F9 /* DataSource.m */,
C33FDAFC255A580600E217F9 /* MIMETypeUtil.h */,
C33FDB41255A580C00E217F9 /* MIMETypeUtil.m */,
C33FDB29255A580A00E217F9 /* NSData+Image.h */,
C33FDAEF255A580500E217F9 /* NSData+Image.m */,
C33FDB22255A580900E217F9 /* OWSMediaUtils.swift */,
C33FDB1C255A580900E217F9 /* UIImage+OWS.h */,
C33FDB81255A581100E217F9 /* UIImage+OWS.m */,
);
path = Media;
sourceTree = "<group>";
};
B8A582B0258C66C900AFD84C /* General */ = {
isa = PBXGroup;
children = (
C33FDB8A255A581200E217F9 /* AppContext.h */,
C33FDB85255A581100E217F9 /* AppContext.m */,
C3C2A5D12553860800C340D1 /* Array+Description.swift */,
C33FDAA8255A57FF00E217F9 /* BuildConfiguration.swift */,
C3C2A5D52553860A00C340D1 /* Dictionary+Description.swift */,
B8BC00BF257D90E30032E807 /* General.swift */,
C33FDB6B255A580F00E217F9 /* LKUserDefaults.swift */,
C3C2A5CE2553860700C340D1 /* Logging.swift */,
C33FDAFD255A580600E217F9 /* LRUCache.swift */,
C33FDB5C255A580E00E217F9 /* NSArray+Functional.h */,
C33FDAB8255A580100E217F9 /* NSArray+Functional.m */,
C300A6302554B68200555489 /* NSDate+Timestamp.h */,
C300A6312554B6D100555489 /* NSDate+Timestamp.mm */,
C33FDB3B255A580B00E217F9 /* NSNotificationCenter+OWS.h */,
C33FDB6C255A580F00E217F9 /* NSNotificationCenter+OWS.m */,
C33FDA7A255A57FB00E217F9 /* NSRegularExpression+SSK.swift */,
C33FDB12255A580800E217F9 /* NSString+SSK.h */,
C33FDB45255A580C00E217F9 /* NSString+SSK.m */,
C352A3762557859C00338F3E /* NSTimer+Proxying.h */,
C352A36C2557858D00338F3E /* NSTimer+Proxying.m */,
C33FDB51255A580D00E217F9 /* NSUserDefaults+OWS.h */,
C33FDB77255A581000E217F9 /* NSUserDefaults+OWS.m */,
C33FDB14255A580800E217F9 /* OWSMath.h */,
C33FDB3F255A580C00E217F9 /* String+SSK.swift */,
C3C2AC2D2553CBEB00C340D1 /* String+Trimming.swift */,
C38EF237255B6D65007E1867 /* UIDevice+featureSupport.swift */,
C38EF23D255B6D66007E1867 /* UIView+OWS.h */,
C38EF23E255B6D66007E1867 /* UIView+OWS.m */,
C38EF2EF255B6DBB007E1867 /* Weak.swift */,
);
path = General;
sourceTree = "<group>";
};
B8A582B9258C696200AFD84C /* Messaging */ = {
isa = PBXGroup;
children = (
C33FDBCA255A581700E217F9 /* LKGroupUtilities.h */,
C33FDBE1255A581A00E217F9 /* LKGroupUtilities.m */,
);
path = Messaging;
sourceTree = "<group>";
};
B8B3201F258B1A540020074B /* Contacts */ = {
isa = PBXGroup;
children = (
B8B32020258B1A650020074B /* Contact.swift */,
);
path = Contacts;
sourceTree = "<group>";
};
B8CCF63B239757C10091D419 /* Components */ = {
isa = PBXGroup;
children = (
@ -2856,7 +2947,7 @@
C32C5BB9256DC7C4003C73A2 /* To Do */ = {
isa = PBXGroup;
children = (
C33FDAFF255A580600E217F9 /* DisplayNameUtilities.swift */,
B8B32067258C22010020074B /* DisplayNameUtilities.swift */,
C33FDAA0255A57FF00E217F9 /* OWSRecipientIdentity.h */,
C33FDBEC255A581B00E217F9 /* OWSRecipientIdentity.m */,
C38EF2D3255B6DAF007E1867 /* OWSUserProfile.h */,
@ -2882,6 +2973,7 @@
C33FDAB9255A580100E217F9 /* OWSStorage+Subclass.h */,
C33FDAB1255A580000E217F9 /* OWSStorage.m */,
B8D8F1372566120F0092EF10 /* Storage+ClosedGroups.swift */,
B8B32032258B235D0020074B /* Storage+Contacts.swift */,
B8D8F17625661AFA0092EF10 /* Storage+Jobs.swift */,
B8D8F19225661BF80092EF10 /* Storage+Messaging.swift */,
B8D8F18825661BA50092EF10 /* Storage+OpenGroups.swift */,
@ -3014,15 +3106,9 @@
C33FDBC9255A581700E217F9 /* CreatePreKeysOperation.swift */,
C33FDB69255A580F00E217F9 /* FeatureFlags.swift */,
C33FDB87255A581100E217F9 /* JobQueue.swift */,
C33FDB0E255A580800E217F9 /* NSError+MessageSending.h */,
C33FDB09255A580700E217F9 /* NSError+MessageSending.m */,
C33FDA99255A57FE00E217F9 /* OutageDetection.swift */,
C33FDACF255A580300E217F9 /* OWSAttachmentDownloads.h */,
C33FDC13255A581E00E217F9 /* OWSAttachmentDownloads.m */,
C33FDA95255A57FE00E217F9 /* OWSChunkedOutputStream.h */,
C33FDB4B255A580C00E217F9 /* OWSChunkedOutputStream.m */,
C33FDA9D255A57FF00E217F9 /* OWSContactsOutputStream.h */,
C33FDB44255A580C00E217F9 /* OWSContactsOutputStream.m */,
C33FDA96255A57FE00E217F9 /* OWSDispatch.h */,
C33FDAC3255A580200E217F9 /* OWSDispatch.m */,
C33FDBF9255A581C00E217F9 /* OWSError.h */,
@ -3031,10 +3117,6 @@
C33FDB59255A580E00E217F9 /* OWSFailedAttachmentDownloadsJob.m */,
C33FDADB255A580400E217F9 /* OWSFailedMessagesJob.h */,
C33FDAB7255A580100E217F9 /* OWSFailedMessagesJob.m */,
C33FDABB255A580100E217F9 /* OWSGroupsOutputStream.h */,
C33FDAD8255A580300E217F9 /* OWSGroupsOutputStream.m */,
C33FDB52255A580D00E217F9 /* OWSHTTPSecurityPolicy.h */,
C33FDBBF255A581700E217F9 /* OWSHTTPSecurityPolicy.m */,
C33FDBA1255A581400E217F9 /* OWSOperation.h */,
C33FDB78255A581000E217F9 /* OWSOperation.m */,
C33FDC19255A581F00E217F9 /* OWSQueues.h */,
@ -3043,8 +3125,6 @@
C33FDBD3255A581800E217F9 /* OWSSignalAddress.swift */,
C33FDA75255A57FB00E217F9 /* OWSSyncManagerProtocol.h */,
C33FDB5A255A580E00E217F9 /* OWSUDManager.swift */,
C33FDBD6255A581900E217F9 /* OWSUploadOperation.h */,
C33FDC1E255A581F00E217F9 /* OWSUploadOperation.m */,
C33FDB53255A580D00E217F9 /* PreKeyBundle+jsonDict.h */,
C33FDB93255A581200E217F9 /* PreKeyBundle+jsonDict.m */,
C33FDB64255A580E00E217F9 /* PreKeyRefreshOperation.swift */,
@ -3054,8 +3134,6 @@
C33FDC06255A581D00E217F9 /* SignalAccount.m */,
C33FDBD8255A581900E217F9 /* SignalIOS.pb.swift */,
C33FDB40255A580C00E217F9 /* SignalIOSProto.swift */,
C33FDAED255A580500E217F9 /* SSKMessageSenderJobRecord.h */,
C33FDAE9255A580500E217F9 /* SSKMessageSenderJobRecord.m */,
C33FDC12255A581E00E217F9 /* TSConstants.h */,
C33FDABE255A580100E217F9 /* TSConstants.m */,
C33FDB6D255A580F00E217F9 /* TSPreKeyManager.h */,
@ -3110,6 +3188,7 @@
C379DCE82567330E0002D4EB /* Migration */ = {
isa = PBXGroup;
children = (
B8B32044258C117C0020074B /* ContactsMigration.swift */,
C38EF271255B6D79007E1867 /* OWSDatabaseMigration.h */,
C38EF270255B6D79007E1867 /* OWSDatabaseMigration.m */,
C38EF26F255B6D79007E1867 /* OWSDatabaseMigrationRunner.h */,
@ -3241,7 +3320,6 @@
isa = PBXGroup;
children = (
C33FDB19255A580900E217F9 /* GroupUtilities.swift */,
C33FDBF4255A581B00E217F9 /* DisplayNameUtilities2.swift */,
C33FDADF255A580400E217F9 /* PublicChatManager.swift */,
C38EF3E5255B6DF4007E1867 /* ContactCellView.h */,
C38EF3D6255B6DEF007E1867 /* ContactCellView.m */,
@ -3251,6 +3329,7 @@
C38EF2CF255B6DAE007E1867 /* OWSProfileManager.m */,
C33FDBBB255A581600E217F9 /* OWSPrimaryStorage+Loki.h */,
C33FDB58255A580E00E217F9 /* OWSPrimaryStorage+Loki.m */,
B8B32071258C22200020074B /* DisplayNameUtilities2.swift */,
);
path = "To Do";
sourceTree = "<group>";
@ -3444,69 +3523,14 @@
isa = PBXGroup;
children = (
C3C2A68B255388D500C340D1 /* Meta */,
C3C2A5D72553860B00C340D1 /* AESGCM.swift */,
C3A721992558C1660043A11F /* AnyPromise+Conversion.swift */,
C33FDB8A255A581200E217F9 /* AppContext.h */,
C33FDB85255A581100E217F9 /* AppContext.m */,
C3C2A5D12553860800C340D1 /* Array+Description.swift */,
C33FDAA8255A57FF00E217F9 /* BuildConfiguration.swift */,
B8A582AC258C653C00AFD84C /* Crypto */,
B8A582AB258C64E800AFD84C /* Database */,
B8A582B0258C66C900AFD84C /* General */,
B8A582AF258C665E00AFD84C /* Media */,
B8A582B9258C696200AFD84C /* Messaging */,
B8A582AE258C65D000AFD84C /* Networking */,
B8A582AD258C655E00AFD84C /* PromiseKit */,
C3D9E43025676D3D0040E4F3 /* Configuration.swift */,
C33FDB68255A580F00E217F9 /* ContentProxy.swift */,
C33FDB54255A580D00E217F9 /* DataSource.h */,
C33FDBB6255A581600E217F9 /* DataSource.m */,
C3C2ABD12553C6C900C340D1 /* Data+SecureRandom.swift */,
C3C2A5D52553860A00C340D1 /* Dictionary+Description.swift */,
C3A71D662558A0170043A11F /* DiffieHellman.swift */,
C33FDA73255A57FA00E217F9 /* ECKeyPair+Hexadecimal.swift */,
B8BC00BF257D90E30032E807 /* General.swift */,
C3C2A5BC255385EE00C340D1 /* HTTP.swift */,
C3C2A5D92553860B00C340D1 /* JSON.swift */,
C33FDBCA255A581700E217F9 /* LKGroupUtilities.h */,
C33FDBE1255A581A00E217F9 /* LKGroupUtilities.m */,
C33FDB6B255A580F00E217F9 /* LKUserDefaults.swift */,
C3C2A5CE2553860700C340D1 /* Logging.swift */,
C33FDAFD255A580600E217F9 /* LRUCache.swift */,
C33FDAFC255A580600E217F9 /* MIMETypeUtil.h */,
C33FDB41255A580C00E217F9 /* MIMETypeUtil.m */,
C3A71F882558BA9F0043A11F /* Mnemonic.swift */,
C33FDB5C255A580E00E217F9 /* NSArray+Functional.h */,
C33FDAB8255A580100E217F9 /* NSArray+Functional.m */,
C33FDB29255A580A00E217F9 /* NSData+Image.h */,
C33FDAEF255A580500E217F9 /* NSData+Image.m */,
C300A6302554B68200555489 /* NSDate+Timestamp.h */,
C300A6312554B6D100555489 /* NSDate+Timestamp.mm */,
C33FDB3B255A580B00E217F9 /* NSNotificationCenter+OWS.h */,
C33FDB6C255A580F00E217F9 /* NSNotificationCenter+OWS.m */,
C33FDA7A255A57FB00E217F9 /* NSRegularExpression+SSK.swift */,
C33FDB12255A580800E217F9 /* NSString+SSK.h */,
C33FDB45255A580C00E217F9 /* NSString+SSK.m */,
C352A3762557859C00338F3E /* NSTimer+Proxying.h */,
C352A36C2557858D00338F3E /* NSTimer+Proxying.m */,
C33FDB51255A580D00E217F9 /* NSUserDefaults+OWS.h */,
C33FDB77255A581000E217F9 /* NSUserDefaults+OWS.m */,
C33FDBAB255A581500E217F9 /* OWSFileSystem.h */,
C33FDA8E255A57FD00E217F9 /* OWSFileSystem.m */,
C33FDB14255A580800E217F9 /* OWSMath.h */,
C33FDB22255A580900E217F9 /* OWSMediaUtils.swift */,
C3D9E41E25676C870040E4F3 /* OWSPrimaryStorageProtocol.swift */,
C3C2A5D32553860900C340D1 /* Promise+Delaying.swift */,
C3A7225D2558C38D0043A11F /* Promise+Retaining.swift */,
C3C2A5D62553860B00C340D1 /* Promise+Retrying.swift */,
C33FDAF2255A580500E217F9 /* ProxiedContentDownloader.swift */,
C33FDBBC255A581600E217F9 /* SSKKeychainStorage.swift */,
C33FDB36255A580B00E217F9 /* Storage.swift */,
C33FDB3F255A580C00E217F9 /* String+SSK.swift */,
C3C2AC2D2553CBEB00C340D1 /* String+Trimming.swift */,
C352A3A42557B5F000338F3E /* TSRequest.h */,
C352A3A52557B60D00338F3E /* TSRequest.m */,
C33FDAA1255A57FF00E217F9 /* TSYapDatabaseObject.h */,
C33FDA90255A57FD00E217F9 /* TSYapDatabaseObject.m */,
C38EF237255B6D65007E1867 /* UIDevice+featureSupport.swift */,
C33FDB1C255A580900E217F9 /* UIImage+OWS.h */,
C33FDB81255A581100E217F9 /* UIImage+OWS.m */,
C38EF23D255B6D66007E1867 /* UIView+OWS.h */,
C38EF23E255B6D66007E1867 /* UIView+OWS.m */,
C38EF2EF255B6DBB007E1867 /* Weak.swift */,
);
path = SessionUtilitiesKit;
sourceTree = "<group>";
@ -3528,6 +3552,7 @@
C32C5BB9256DC7C4003C73A2 /* To Do */,
C3BBE0752554CDA60050F1E3 /* Configuration.swift */,
C3BBE07F2554CDD70050F1E3 /* Storage.swift */,
B8B3201F258B1A540020074B /* Contacts */,
C32C5BCB256DC818003C73A2 /* Database */,
C300A5BB2554AFFB00555489 /* Messages */,
C32C59AF256DB31A003C73A2 /* Threads */,
@ -3968,8 +3993,6 @@
C38EF35D255B6DCC007E1867 /* OWSNavigationController.h in Headers */,
C38EF249255B6D67007E1867 /* UIColor+OWS.h in Headers */,
C38EF216255B6D3B007E1867 /* Theme.h in Headers */,
C33FDD0C255A582000E217F9 /* OWSHTTPSecurityPolicy.h in Headers */,
C33FDC57255A582000E217F9 /* OWSContactsOutputStream.h in Headers */,
C33FDCBD255A582000E217F9 /* OWSPrimaryStorage+SessionStore.h in Headers */,
C38EF3F0255B6DF7007E1867 /* ThreadViewHelper.h in Headers */,
C38EF274255B6D7A007E1867 /* OWSResaveCollectionDBMigration.h in Headers */,
@ -3979,18 +4002,14 @@
C38EF277255B6D7A007E1867 /* OWSDatabaseMigration.h in Headers */,
C38EF3F5255B6DF7007E1867 /* OWSTextField.h in Headers */,
C38EF275255B6D7A007E1867 /* OWSDatabaseMigrationRunner.h in Headers */,
C33FDCA7255A582000E217F9 /* SSKMessageSenderJobRecord.h in Headers */,
C38EF366255B6DCC007E1867 /* ScreenLockViewController.h in Headers */,
C38EF35B255B6DCC007E1867 /* SelectThreadViewController.h in Headers */,
C33FDDD3255A582000E217F9 /* OWSQueues.h in Headers */,
C33FDC96255A582000E217F9 /* NSObject+Casting.h in Headers */,
C33FDC75255A582000E217F9 /* OWSGroupsOutputStream.h in Headers */,
C33FDDB3255A582000E217F9 /* OWSError.h in Headers */,
C33FDCC8255A582000E217F9 /* NSError+MessageSending.h in Headers */,
C38EF403255B6DF7007E1867 /* ContactCellView.h in Headers */,
C33FDD68255A582000E217F9 /* SignalAccount.h in Headers */,
C38EF35E255B6DCC007E1867 /* OWSViewController.h in Headers */,
C33FDC4F255A582000E217F9 /* OWSChunkedOutputStream.h in Headers */,
C37F5396255B95BD002AEA92 /* OWSAnyTouchGestureRecognizer.h in Headers */,
C38EF404255B6DF7007E1867 /* ContactTableViewCell.h in Headers */,
C33FDDB2255A582000E217F9 /* NSArray+OWS.h in Headers */,
@ -4006,7 +4025,6 @@
C33FD9AF255A548A00E217F9 /* SignalUtilitiesKit.h in Headers */,
C33FDC50255A582000E217F9 /* OWSDispatch.h in Headers */,
C33FDD06255A582000E217F9 /* AppVersion.h in Headers */,
C33FDD90255A582000E217F9 /* OWSUploadOperation.h in Headers */,
C33FDD27255A582000E217F9 /* TSPreKeyManager.h in Headers */,
C33FDD5A255A582000E217F9 /* TSStorageHeaders.h in Headers */,
C33FDCA2255A582000E217F9 /* OWSMessageUtils.h in Headers */,
@ -4913,7 +4931,6 @@
34480B361FD0929200BC14EF /* ShareAppExtensionContext.m in Sources */,
34641E1F2088DA6D00E2EDE5 /* SAEScreenLockViewController.m in Sources */,
3461284B1FD0B94000532771 /* SAELoadViewController.swift in Sources */,
C3D90A8325774A68002C9DF5 /* OWSPrimaryStorageProtocol.swift in Sources */,
347850571FD86544007B8332 /* SAEFailedViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -4960,7 +4977,6 @@
C38EF317255B6DBF007E1867 /* DisplayableText.swift in Sources */,
C38EF30F255B6DBF007E1867 /* AppPreferences.swift in Sources */,
C33FDD45255A582000E217F9 /* Storage+SessionManagement.swift in Sources */,
C33FDCA3255A582000E217F9 /* SSKMessageSenderJobRecord.m in Sources */,
C38EF3C3255B6DE7007E1867 /* ImageEditorTextItem.swift in Sources */,
C33FDC7D255A582000E217F9 /* OWSDispatch.m in Sources */,
C38EF247255B6D67007E1867 /* NSAttributedString+OWS.m in Sources */,
@ -4973,8 +4989,8 @@
C38EF320255B6DBF007E1867 /* OWSScrubbingLogFormatter.m in Sources */,
C38EF39B255B6DDA007E1867 /* ThreadViewModel.swift in Sources */,
C38EF2A5255B6D93007E1867 /* Identicon+ObjC.swift in Sources */,
C33FDD79255A582000E217F9 /* OWSHTTPSecurityPolicy.m in Sources */,
C38EF273255B6D7A007E1867 /* OWSDatabaseMigrationRunner.m in Sources */,
B8B32072258C22200020074B /* DisplayNameUtilities2.swift in Sources */,
C33FDD12255A582000E217F9 /* OWSPrimaryStorage+Loki.m in Sources */,
C3D9E40C25676C100040E4F3 /* Storage+Conformances.swift in Sources */,
C38EF31A255B6DBF007E1867 /* OWSAnyTouchGestureRecognizer.m in Sources */,
@ -5036,9 +5052,7 @@
C38EF276255B6D7A007E1867 /* OWSDatabaseMigration.m in Sources */,
C38EF370255B6DCC007E1867 /* OWSNavigationController.m in Sources */,
C38EF24E255B6D67007E1867 /* Collection+OWS.swift in Sources */,
C33FDD05255A582000E217F9 /* OWSChunkedOutputStream.m in Sources */,
C33FDCFA255A582000E217F9 /* SignalIOSProto.swift in Sources */,
C33FDCC3255A582000E217F9 /* NSError+MessageSending.m in Sources */,
C33FDD13255A582000E217F9 /* OWSFailedAttachmentDownloadsJob.m in Sources */,
C38EF24D255B6D67007E1867 /* UIView+OWS.swift in Sources */,
C33FDD4D255A582000E217F9 /* PreKeyBundle+jsonDict.m in Sources */,
@ -5061,7 +5075,6 @@
C33FDD1E255A582000E217F9 /* PreKeyRefreshOperation.swift in Sources */,
C38EF40C255B6DF7007E1867 /* GradientView.swift in Sources */,
C33FDD14255A582000E217F9 /* OWSUDManager.swift in Sources */,
C33FDDAE255A582000E217F9 /* DisplayNameUtilities2.swift in Sources */,
C38EF35C255B6DCC007E1867 /* SelectThreadViewController.m in Sources */,
C38EF30E255B6DBF007E1867 /* FullTextSearcher.swift in Sources */,
C33FDDD9255A582000E217F9 /* LokiSessionRestorationImplementation.swift in Sources */,
@ -5084,11 +5097,11 @@
C38EF3F2255B6DF7007E1867 /* DisappearingTimerConfigurationView.swift in Sources */,
C38EF3F9255B6DF7007E1867 /* OWSLayerView.swift in Sources */,
C33FDD03255A582000E217F9 /* WeakTimer.swift in Sources */,
B8B3204E258C15C80020074B /* ContactsMigration.swift in Sources */,
C33FDD41255A582000E217F9 /* JobQueue.swift in Sources */,
C38EF3B9255B6DE7007E1867 /* ImageEditorPinchGestureRecognizer.swift in Sources */,
C33FDC98255A582000E217F9 /* SwiftSingletons.swift in Sources */,
C33FDC27255A581F00E217F9 /* YapDatabase+Promise.swift in Sources */,
C33FDCFE255A582000E217F9 /* OWSContactsOutputStream.m in Sources */,
C33FDCD3255A582000E217F9 /* GroupUtilities.swift in Sources */,
C38EF326255B6DBF007E1867 /* ConversationStyle.swift in Sources */,
C38EF3B8255B6DE7007E1867 /* ImageEditorTextViewController.swift in Sources */,
@ -5099,11 +5112,9 @@
C38EF359255B6DCC007E1867 /* SheetViewController.swift in Sources */,
C33FDCAD255A582000E217F9 /* OWSPrimaryStorage+SessionStore.m in Sources */,
C38EF386255B6DD2007E1867 /* AttachmentApprovalInputAccessoryView.swift in Sources */,
C33FDC92255A582000E217F9 /* OWSGroupsOutputStream.m in Sources */,
C38EF28E255B6D86007E1867 /* SignalKeyingStorage.m in Sources */,
B8C2B2C82563685C00551B4D /* CircleView.swift in Sources */,
C38EF331255B6DBF007E1867 /* UIGestureRecognizer+OWS.swift in Sources */,
C33FDDD8255A582000E217F9 /* OWSUploadOperation.m in Sources */,
C33FDDC5255A582000E217F9 /* OWSError.m in Sources */,
C38EF38D255B6DD2007E1867 /* AttachmentCaptionViewController.swift in Sources */,
C38EF31C255B6DBF007E1867 /* Searcher.swift in Sources */,
@ -5213,6 +5224,7 @@
C32C5BDD256DC88D003C73A2 /* OWSReadReceiptManager.m in Sources */,
C3D9E3BF25676AD70040E4F3 /* TSAttachmentStream.m in Sources */,
C3C2A7562553A3AB00C340D1 /* VisibleMessage+Quote.swift in Sources */,
B8B32021258B1A650020074B /* Contact.swift in Sources */,
C32C5C89256DD0D2003C73A2 /* Storage+Jobs.swift in Sources */,
C300A5FC2554B0A000555489 /* MessageReceiver.swift in Sources */,
C32C5A76256DBBCF003C73A2 /* SignalAttachment.swift in Sources */,
@ -5257,10 +5269,12 @@
C32C5E15256DDC78003C73A2 /* SSKPreferences.swift in Sources */,
C32C5D9C256DD6DC003C73A2 /* OWSOutgoingReceiptManager.m in Sources */,
C32C5C4F256DCC36003C73A2 /* Storage+OpenGroups.swift in Sources */,
B8B3207B258C22550020074B /* DisplayNameUtilities.swift in Sources */,
C3A3A099256E17B2004D228D /* SSKJobRecordFinder.swift in Sources */,
B8856CEE256F1054001CE70E /* OWSAudioPlayer.m in Sources */,
C32C5EDC256DF501003C73A2 /* YapDatabaseConnection+OWS.m in Sources */,
C3BBE0762554CDA60050F1E3 /* Configuration.swift in Sources */,
B8B32033258B235D0020074B /* Storage+Contacts.swift in Sources */,
B8856D69256F141F001CE70E /* OWSWindowManager.m in Sources */,
C32C5F5F256DFD90003C73A2 /* TSInvalidIdentityKeyErrorMessage.m in Sources */,
C3D9E3BE25676AD70040E4F3 /* TSAttachmentPointer.m in Sources */,
@ -5314,7 +5328,6 @@
C3BBE0C72554F1570050F1E3 /* FixedWidthInteger+BigEndian.swift in Sources */,
C32C5C88256DD0D2003C73A2 /* Storage+Messaging.swift in Sources */,
C32C59C7256DB41F003C73A2 /* TSThread.m in Sources */,
C32C5F08256DF5C8003C73A2 /* DisplayNameUtilities.swift in Sources */,
C300A5B22554AF9800555489 /* VisibleMessage+Profile.swift in Sources */,
C32C5F1A256DFCAD003C73A2 /* TSErrorMessage.m in Sources */,
C32C5A75256DBBCF003C73A2 /* TSAttachmentPointer+Conversion.swift in Sources */,
@ -5480,7 +5493,6 @@
C331FFF32558FF0300070591 /* PathStatusView.swift in Sources */,
4CC1ECFB211A553000CC13BE /* AppUpdateNag.swift in Sources */,
34B6A903218B3F63007C4606 /* TypingIndicatorView.swift in Sources */,
458E38371D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m in Sources */,
34B6A905218B4C91007C4606 /* TypingIndicatorInteraction.swift in Sources */,
2400888E239F30A600305217 /* SessionRestorationView.swift in Sources */,
B886B4A72398B23E00211ABE /* QRCodeVC.swift in Sources */,

View File

@ -0,0 +1,63 @@
@objc(SNContactsMigration)
public class ContactsMigration : OWSDatabaseMigration {
@objc
class func migrationId() -> String {
return "005"
}
override public func runUp(completion: @escaping OWSDatabaseMigrationCompletion) {
self.doMigrationAsync(completion: completion)
}
private func doMigrationAsync(completion: @escaping OWSDatabaseMigrationCompletion) {
var contacts: Set<Contact> = []
Storage.write(with: { transaction in
// One-on-one chats
TSContactThread.enumerateCollectionObjects(with: transaction) { object, _ in
guard let thread = object as? TSContactThread else { return }
let sessionID = thread.contactIdentifier()
let contact = Contact(sessionID: sessionID)
var profileOrNil: OWSUserProfile? = nil
if sessionID == getUserHexEncodedPublicKey() {
profileOrNil = OWSProfileManager.shared().getLocalUserProfile(with: transaction)
} else if let profile = OWSUserProfile.fetch(uniqueId: sessionID, transaction: transaction) {
profileOrNil = profile
}
if let profile = profileOrNil {
contact.displayName = profile.profileName
contact.profilePictureURL = profile.avatarUrlPath
contact.profilePictureFileName = profile.avatarFileName
contact.profilePictureEncryptionKey = profile.profileKey
}
contact.threadID = thread.uniqueId
contacts.insert(contact)
}
// Closed groups
TSGroupThread.enumerateCollectionObjects(with: transaction) { object, _ in
guard let thread = object as? TSGroupThread, thread.usesSharedSenderKeys else { return }
let memberSessionIDs = thread.groupModel.groupMemberIds
memberSessionIDs.forEach { memberSessionID in
guard !contacts.contains(where: { $0.sessionID == memberSessionID }) else { return }
let contact = Contact(sessionID: memberSessionID)
if let profile = OWSUserProfile.fetch(uniqueId: memberSessionID, transaction: transaction) {
contact.displayName = profile.profileName
contact.profilePictureURL = profile.avatarUrlPath
contact.profilePictureFileName = profile.avatarFileName
contact.profilePictureEncryptionKey = profile.profileKey
}
// At this point we know we don't have a one-on-one thread with this contact
contacts.insert(contact)
}
}
// Save
contacts.forEach { contact in
Storage.shared.setContact(contact, using: transaction)
}
self.save(with: transaction) // Intentionally capture self
}, completion: {
completion()
})
}
}

View File

@ -25,7 +25,9 @@ NS_ASSUME_NONNULL_BEGIN
// This should all migrations which do NOT qualify as safeBlockingMigrations:
- (NSArray<OWSDatabaseMigration *> *)allMigrations
{
return @[];
return @[
[SNContactsMigration new]
];
}
- (void)assumeAllExistingMigrationsRun

View File

@ -13,14 +13,13 @@ FOUNDATION_EXPORT const unsigned char SignalUtilitiesKitVersionString[];
#import <SignalUtilitiesKit/BlockListUIUtils.h>
#import <SignalUtilitiesKit/DebugLogger.h>
#import <SignalUtilitiesKit/NSAttributedString+OWS.h>
#import <SignalUtilitiesKit/NSError+MessageSending.h>
#import <SignalUtilitiesKit/NSURLSessionDataTask+StatusCode.h>
#import <SignalUtilitiesKit/OWSAnyTouchGestureRecognizer.h>
#import <SignalUtilitiesKit/OWSAttachmentDownloads.h>
#import <SignalUtilitiesKit/OWSDatabaseMigration.h>
#import <SignalUtilitiesKit/OWSDispatch.h>
#import <SignalUtilitiesKit/OWSError.h>
#import <SignalUtilitiesKit/OWSFormat.h>
#import <SignalUtilitiesKit/OWSHTTPSecurityPolicy.h>
#import <SignalUtilitiesKit/OWSMessageUtils.h>
#import <SignalUtilitiesKit/OWSNavigationController.h>
#import <SignalUtilitiesKit/OWSOperation.h>
@ -34,7 +33,6 @@ FOUNDATION_EXPORT const unsigned char SignalUtilitiesKitVersionString[];
#import <SignalUtilitiesKit/OWSTextField.h>
#import <SignalUtilitiesKit/OWSTextView.h>
#import <SignalUtilitiesKit/OWSUnreadIndicator.h>
#import <SignalUtilitiesKit/OWSUploadOperation.h>
#import <SignalUtilitiesKit/OWSViewController.h>
#import <SignalUtilitiesKit/ScreenLockViewController.h>
#import <SignalUtilitiesKit/SelectRecipientViewController.h>
@ -42,7 +40,6 @@ FOUNDATION_EXPORT const unsigned char SignalUtilitiesKitVersionString[];
#import <SignalUtilitiesKit/SignalAccount.h>
#import <SignalUtilitiesKit/SignalKeyingStorage.h>
#import <SignalUtilitiesKit/SSKAsserts.h>
#import <SignalUtilitiesKit/SSKMessageSenderJobRecord.h>
#import <SignalUtilitiesKit/Theme.h>
#import <SignalUtilitiesKit/ThreadUtil.h>
#import <SignalUtilitiesKit/TSConstants.h>

View File

@ -1,17 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSError (MessageSending)
@property (nonatomic) BOOL isRetryable;
@property (nonatomic) BOOL isFatal;
@property (nonatomic) BOOL shouldBeIgnoredForGroups;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,61 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "NSError+MessageSending.h"
#import <objc/runtime.h>
NS_ASSUME_NONNULL_BEGIN
static void *kNSError_MessageSender_IsRetryable = &kNSError_MessageSender_IsRetryable;
static void *kNSError_MessageSender_ShouldBeIgnoredForGroups = &kNSError_MessageSender_ShouldBeIgnoredForGroups;
static void *kNSError_MessageSender_IsFatal = &kNSError_MessageSender_IsFatal;
// isRetryable and isFatal are opposites but not redundant.
//
// If a group message send fails, the send will be retried if any of the errors were retryable UNLESS
// any of the errors were fatal. Fatal errors trump retryable errors.
@implementation NSError (MessageSending)
- (BOOL)isRetryable
{
NSNumber *value = objc_getAssociatedObject(self, kNSError_MessageSender_IsRetryable);
// This value should always be set for all errors by the time OWSSendMessageOperation
// queries it's value. If not, default to retrying in production.
return value ? [value boolValue] : YES;
}
- (void)setIsRetryable:(BOOL)value
{
objc_setAssociatedObject(self, kNSError_MessageSender_IsRetryable, @(value), OBJC_ASSOCIATION_COPY);
}
- (BOOL)shouldBeIgnoredForGroups
{
NSNumber *value = objc_getAssociatedObject(self, kNSError_MessageSender_ShouldBeIgnoredForGroups);
// This value will NOT always be set for all errors by the time we query it's value.
// Default to NOT ignoring.
return value ? [value boolValue] : NO;
}
- (void)setShouldBeIgnoredForGroups:(BOOL)value
{
objc_setAssociatedObject(self, kNSError_MessageSender_ShouldBeIgnoredForGroups, @(value), OBJC_ASSOCIATION_COPY);
}
- (BOOL)isFatal
{
NSNumber *value = objc_getAssociatedObject(self, kNSError_MessageSender_IsFatal);
// This value will NOT always be set for all errors by the time we query it's value.
// Default to NOT fatal.
return value ? [value boolValue] : NO;
}
- (void)setIsFatal:(BOOL)value
{
objc_setAssociatedObject(self, kNSError_MessageSender_IsFatal, @(value), OBJC_ASSOCIATION_COPY);
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,25 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface OWSChunkedOutputStream : NSObject
// Indicates whether any write failed.
@property (nonatomic, readonly) BOOL hasError;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithOutputStream:(NSOutputStream *)outputStream;
// Returns NO on error.
- (BOOL)writeData:(NSData *)data;
- (BOOL)writeUInt32:(UInt32)value;
- (BOOL)writeVariableLengthUInt32:(UInt32)value;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,97 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSChunkedOutputStream.h"
#import <SignalCoreKit/NSData+OWS.h>
#import <SessionProtocolKit/SessionProtocolKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface OWSChunkedOutputStream ()
@property (nonatomic, readonly) NSOutputStream *outputStream;
@property (nonatomic) BOOL hasError;
@end
#pragma mark -
@implementation OWSChunkedOutputStream
- (instancetype)initWithOutputStream:(NSOutputStream *)outputStream
{
if (self = [super init]) {
OWSAssertDebug(outputStream);
_outputStream = outputStream;
}
return self;
}
- (BOOL)writeByte:(uint8_t)value
{
NSInteger written = [self.outputStream write:&value maxLength:sizeof(value)];
if (written != sizeof(value)) {
OWSFailDebug(@"could not write to output stream.");
self.hasError = YES;
return NO;
}
return YES;
}
- (BOOL)writeData:(NSData *)data
{
OWSAssertDebug(data);
if (data.length < 1) {
return YES;
}
while (YES) {
NSInteger written = [self.outputStream write:data.bytes maxLength:data.length];
if (written < 1) {
OWSFailDebug(@"could not write to output stream.");
self.hasError = YES;
return NO;
}
if (written < data.length) {
data = [data subdataWithRange:NSMakeRange(written, data.length - written)];
} else {
return YES;
}
}
return YES;
}
- (BOOL)writeUInt32:(UInt32)value {
NSData *data = [[NSData alloc] initWithBytes:&value length:sizeof(value)];
// Both Android and desktop seem to like this better
const char *bytes = data.bytes;
char *reversedBytes = malloc(sizeof(char) * data.length);
int i = data.length - 1;
for (int j = 0; j < data.length; j++) {
reversedBytes[i] = bytes[j];
i = i - 1;
}
NSData *reversedData = [NSData dataWithBytes:reversedBytes length:data.length];
return [self writeData:reversedData];
}
- (BOOL)writeVariableLengthUInt32:(UInt32)value
{
while (YES) {
if (value <= 0x7F) {
return [self writeByte:value];
} else {
if (![self writeByte:((value & 0x7F) | 0x80)]) {
return NO;
}
value >>= 7;
}
}
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,27 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <SignalUtilitiesKit/OWSChunkedOutputStream.h>
NS_ASSUME_NONNULL_BEGIN
@class OWSDisappearingMessagesConfiguration;
@class OWSRecipientIdentity;
@class SignalAccount;
@protocol ContactsManagerProtocol;
@interface OWSContactsOutputStream : OWSChunkedOutputStream
- (void)writeSignalAccount:(SignalAccount *)signalAccount
recipientIdentity:(nullable OWSRecipientIdentity *)recipientIdentity
profileKeyData:(nullable NSData *)profileKeyData
contactsManager:(id<ContactsManagerProtocol>)contactsManager
conversationColorName:(NSString *)conversationColorName
disappearingMessagesConfiguration:(nullable OWSDisappearingMessagesConfiguration *)disappearingMessagesConfiguration;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,80 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSContactsOutputStream.h"
#import "MIMETypeUtil.h"
#import "NSData+keyVersionByte.h"
#import "OWSBlockingManager.h"
#import "OWSDisappearingMessagesConfiguration.h"
#import "OWSRecipientIdentity.h"
#import "SignalAccount.h"
#import "TSContactThread.h"
#import <SignalCoreKit/Cryptography.h>
#import <SignalCoreKit/NSData+OWS.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN
@implementation OWSContactsOutputStream
- (void)writeSignalAccount:(SignalAccount *)signalAccount
recipientIdentity:(nullable OWSRecipientIdentity *)recipientIdentity
profileKeyData:(nullable NSData *)profileKeyData
contactsManager:(id<ContactsManagerProtocol>)contactsManager
conversationColorName:(NSString *)conversationColorName
disappearingMessagesConfiguration:(nullable OWSDisappearingMessagesConfiguration *)disappearingMessagesConfiguration
{
OWSAssertDebug(signalAccount);
OWSAssertDebug(contactsManager);
SNProtoContactDetailsBuilder *contactBuilder =
[SNProtoContactDetails builderWithNumber:signalAccount.recipientId];
[contactBuilder setName:[LKUserDisplayNameUtilities getPrivateChatDisplayNameFor:signalAccount.recipientId] ?: signalAccount.recipientId];
[contactBuilder setColor:conversationColorName];
if (recipientIdentity != nil) {
SNProtoVerified *_Nullable verified = BuildVerifiedProtoWithRecipientId(recipientIdentity.recipientId,
[recipientIdentity.identityKey prependKeyType],
recipientIdentity.verificationState,
0);
if (!verified) {
OWSLogError(@"could not build protobuf.");
return;
}
contactBuilder.verified = verified;
}
if (profileKeyData) {
OWSAssertDebug(profileKeyData.length == kAES256_KeyByteLength);
[contactBuilder setProfileKey:profileKeyData];
}
// Always ensure the "expire timer" property is set so that desktop
// can easily distinguish between a modern client declaring "off" vs a
// legacy client "not specifying".
[contactBuilder setExpireTimer:0];
if (disappearingMessagesConfiguration && disappearingMessagesConfiguration.isEnabled) {
[contactBuilder setExpireTimer:disappearingMessagesConfiguration.durationSeconds];
}
if ([OWSBlockingManager.sharedManager isRecipientIdBlocked:signalAccount.recipientId]) {
[contactBuilder setBlocked:YES];
}
NSError *error;
NSData *_Nullable contactData = [contactBuilder buildSerializedDataAndReturnError:&error];
if (error || !contactData) {
OWSFailDebug(@"could not serialize protobuf: %@", error);
return;
}
uint32_t contactDataLength = (uint32_t)contactData.length;
[self writeUInt32:contactDataLength];
[self writeData:contactData];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,18 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <SignalUtilitiesKit/OWSChunkedOutputStream.h>
NS_ASSUME_NONNULL_BEGIN
@class TSGroupThread;
@class YapDatabaseReadTransaction;
@interface OWSGroupsOutputStream : OWSChunkedOutputStream
- (void)writeGroup:(TSGroupThread *)groupThread transaction:(YapDatabaseReadTransaction *)transaction;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,61 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSGroupsOutputStream.h"
#import "MIMETypeUtil.h"
#import "OWSBlockingManager.h"
#import "OWSDisappearingMessagesConfiguration.h"
#import "TSGroupModel.h"
#import "TSGroupThread.h"
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN
@implementation OWSGroupsOutputStream
- (void)writeGroup:(TSGroupThread *)groupThread transaction:(YapDatabaseReadTransaction *)transaction
{
OWSAssertDebug(groupThread);
OWSAssertDebug(transaction);
TSGroupModel *group = groupThread.groupModel;
OWSAssertDebug(group);
SNProtoGroupDetailsBuilder *groupBuilder = [SNProtoGroupDetails builderWithId:group.groupId];
[groupBuilder setName:group.groupName];
[groupBuilder setMembers:group.groupMemberIds];
[groupBuilder setAdmins:group.groupAdminIds];
if ([OWSBlockingManager.sharedManager isGroupIdBlocked:group.groupId]) {
[groupBuilder setBlocked:YES];
}
OWSDisappearingMessagesConfiguration *_Nullable disappearingMessagesConfiguration =
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:groupThread.uniqueId transaction:transaction];
if (disappearingMessagesConfiguration && disappearingMessagesConfiguration.isEnabled) {
[groupBuilder setExpireTimer:disappearingMessagesConfiguration.durationSeconds];
} else {
// Rather than *not* set the field, we expicitly set it to 0 so desktop
// can easily distinguish between a modern client declaring "off" vs a
// legacy client "not specifying".
[groupBuilder setExpireTimer:0];
}
NSError *error;
NSData *_Nullable groupData = [groupBuilder buildSerializedDataAndReturnError:&error];
if (error || !groupData) {
OWSFailDebug(@"could not serialize protobuf: %@", error);
return;
}
uint32_t groupDataLength = (uint32_t)groupData.length;
[self writeUInt32:groupDataLength];
[self writeData:groupData];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,17 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import <AFNetworking/AFSecurityPolicy.h>
NS_ASSUME_NONNULL_BEGIN
extern NSData *SSKTextSecureServiceCertificateData(void);
@interface OWSHTTPSecurityPolicy : AFSecurityPolicy
+ (instancetype)sharedPolicy;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,106 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import "OWSHTTPSecurityPolicy.h"
#import <AssertMacros.h>
#import <SessionProtocolKit/SessionProtocolKit.h>
NS_ASSUME_NONNULL_BEGIN
@implementation OWSHTTPSecurityPolicy
+ (instancetype)sharedPolicy {
static OWSHTTPSecurityPolicy *httpSecurityPolicy = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
httpSecurityPolicy = [[self alloc] initWithOWSPolicy];
});
return httpSecurityPolicy;
}
- (instancetype)initWithOWSPolicy {
self = [[super class] defaultPolicy];
if (self) {
self.pinnedCertificates = [NSSet setWithArray:@[
[self.class certificateDataForService:@"textsecure"]
]];
}
return self;
}
+ (NSData *)dataFromCertificateFileForService:(NSString *)service
{
NSBundle *bundle = [NSBundle bundleForClass:self.class];
NSString *path = [bundle pathForResource:service ofType:@"cer"];
if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
OWSFail(@"Missing signing certificate for service %@", service);
}
NSData *data = [NSData dataWithContentsOfFile:path];
OWSAssert(data.length > 0);
return data;
}
+ (NSData *)certificateDataForService:(NSString *)service {
SecCertificateRef certRef = [self certificateForService:service];
return (__bridge_transfer NSData *)SecCertificateCopyData(certRef);
}
+ (SecCertificateRef)certificateForService:(NSString *)service
{
NSData *certificateData = [self dataFromCertificateFileForService:service];
return SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(certificateData));
}
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(nullable NSString *)domain
{
NSMutableArray *policies = [NSMutableArray array];
[policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)];
if (SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies) != errSecSuccess) {
OWSLogError(@"The trust policy couldn't be set.");
return NO;
}
NSMutableArray *pinnedCertificates = [NSMutableArray array];
for (NSData *certificateData in self.pinnedCertificates) {
[pinnedCertificates
addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)];
}
if (SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates) != errSecSuccess) {
OWSLogError(@"The anchor certificates couldn't be set.");
return NO;
}
if (!AFServerTrustIsValid(serverTrust)) {
return NO;
}
return YES;
}
static BOOL AFServerTrustIsValid(SecTrustRef serverTrust) {
BOOL isValid = NO;
SecTrustResultType result;
__Require_noErr_Quiet(SecTrustEvaluate(serverTrust, &result), _out);
isValid = (result == kSecTrustResultUnspecified);
_out:
return isValid;
}
NSData *SSKTextSecureServiceCertificateData()
{
return [OWSHTTPSecurityPolicy dataFromCertificateFileForService:@"textsecure"];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -3,7 +3,6 @@
//
#import "OWSOperation.h"
#import "NSError+MessageSending.h"
#import "OWSBackgroundTask.h"
#import "OWSError.h"
#import <SessionProtocolKit/SessionProtocolKit.h>
@ -166,24 +165,8 @@ NSString *const OWSOperationKeyIsFinished = @"isFinished";
- (void)reportError:(NSError *)error
{
OWSLogDebug(@"reportError: %@, fatal?: %d, retryable?: %d, remainingRetries: %lu",
error,
error.isFatal,
error.isRetryable,
(unsigned long)self.remainingRetries);
[self didReportError:error];
if (error.isFatal) {
[self failOperationWithError:error];
return;
}
if (!error.isRetryable) {
[self failOperationWithError:error];
return;
}
if (self.remainingRetries == 0) {
[self failOperationWithError:error];
return;

View File

@ -1,27 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <SignalUtilitiesKit/OWSOperation.h>
NS_ASSUME_NONNULL_BEGIN
@class TSOutgoingMessage;
@class YapDatabaseConnection;
extern NSString *const kAttachmentUploadProgressNotification;
extern NSString *const kAttachmentUploadProgressKey;
extern NSString *const kAttachmentUploadAttachmentIDKey;
@interface OWSUploadOperation : OWSOperation
@property (nullable, readonly) NSError *lastError;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithAttachmentId:(NSString *)attachmentId
threadID:(NSString *)threadID
dbConnection:(YapDatabaseConnection *)dbConnection NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,110 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSUploadOperation.h"
#import "MIMETypeUtil.h"
#import "NSError+MessageSending.h"
#import "NSNotificationCenter+OWS.h"
#import "OWSDispatch.h"
#import "OWSError.h"
#import "OWSOperation.h"
#import <PromiseKit/PromiseKit.h>
#import "SSKEnvironment.h"
#import "TSAttachmentStream.h"
#import <SignalCoreKit/Cryptography.h>
#import <YapDatabase/YapDatabaseConnection.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN
NSString *const kAttachmentUploadProgressNotification = @"kAttachmentUploadProgressNotification";
NSString *const kAttachmentUploadProgressKey = @"kAttachmentUploadProgressKey";
NSString *const kAttachmentUploadAttachmentIDKey = @"kAttachmentUploadAttachmentIDKey";
// Use a slightly non-zero value to ensure that the progress
// indicator shows up as quickly as possible.
static const CGFloat kAttachmentUploadProgressTheta = 0.001f;
@interface OWSUploadOperation ()
@property (readonly, nonatomic) NSString *attachmentId;
@property (readonly, nonatomic) NSString *threadID;
@property (readonly, nonatomic) YapDatabaseConnection *dbConnection;
@end
#pragma mark -
@implementation OWSUploadOperation
- (instancetype)initWithAttachmentId:(NSString *)attachmentId
threadID:(NSString *)threadID
dbConnection:(YapDatabaseConnection *)dbConnection
{
self = [super init];
if (!self) {
return self;
}
self.remainingRetries = 4;
_attachmentId = attachmentId;
_threadID = threadID;
_dbConnection = dbConnection;
return self;
}
- (void)run
{
__block TSAttachmentStream *attachmentStream;
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
attachmentStream = [TSAttachmentStream fetchObjectWithUniqueID:self.attachmentId transaction:transaction];
}];
if (!attachmentStream) {
NSError *error = OWSErrorMakeFailedToSendOutgoingMessageError();
// Not finding a local attachment is a terminal failure
error.isRetryable = NO;
[self reportError:error];
return;
}
if (attachmentStream.isUploaded) {
OWSLogDebug(@"Attachment previously uploaded.");
[self reportSuccess];
return;
}
[self fireNotificationWithProgress:0];
SNOpenGroup *publicChat = [LKStorage.shared getOpenGroupForThreadID:self.threadID];
NSString *server = (publicChat != nil) ? publicChat.server : SNFileServerAPI.server;
[[SNFileServerAPI uploadAttachment:attachmentStream withID:self.attachmentId toServer:server]
.thenOn(dispatch_get_main_queue(), ^() {
[self reportSuccess];
})
.catchOn(dispatch_get_main_queue(), ^(NSError *error) {
[self reportError:error];
}) retainUntilComplete];
}
- (void)fireNotificationWithProgress:(CGFloat)aProgress
{
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
CGFloat progress = MAX(kAttachmentUploadProgressTheta, aProgress);
[notificationCenter postNotificationNameAsync:kAttachmentUploadProgressNotification
object:nil
userInfo:@{
kAttachmentUploadProgressKey : @(progress),
kAttachmentUploadAttachmentIDKey : self.attachmentId
}];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,29 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <SessionMessagingKit/SSKJobRecord.h>
NS_ASSUME_NONNULL_BEGIN
@class TSOutgoingMessage;
@interface SSKMessageSenderJobRecord : SSKJobRecord
@property (nonatomic, readonly, nullable) NSString *messageId;
@property (nonatomic, readonly, nullable) NSString *threadId;
@property (nonatomic, readonly, nullable) TSOutgoingMessage *invisibleMessage;
@property (nonatomic, readonly) BOOL removeMessageAfterSending;
- (nullable instancetype)initWithMessage:(TSOutgoingMessage *)message
removeMessageAfterSending:(BOOL)removeMessageAfterSending
label:(NSString *)label
error:(NSError **)outError NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithLabel:(nullable NSString *)label NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,51 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import "SSKMessageSenderJobRecord.h"
#import "TSOutgoingMessage.h"
NS_ASSUME_NONNULL_BEGIN
@implementation SSKMessageSenderJobRecord
#pragma mark
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
return [super initWithCoder:coder];
}
- (nullable instancetype)initWithMessage:(TSOutgoingMessage *)message
removeMessageAfterSending:(BOOL)removeMessageAfterSending
label:(NSString *)label
error:(NSError **)outError;
{
self = [super initWithLabel:label];
if (!self) {
return self;
}
if (message.shouldBeSaved) {
_messageId = message.uniqueId;
if (_messageId == nil) {
*outError = [NSError errorWithDomain:SSKJobRecordErrorDomain
code:JobRecordError_AssertionError
userInfo:@{ NSDebugDescriptionErrorKey : @"messageId wasn't set" }];
return nil;
}
_invisibleMessage = nil;
} else {
_messageId = nil;
_invisibleMessage = message;
}
_removeMessageAfterSending = removeMessageAfterSending;
_threadId = message.uniqueThreadId;
return self;
}
@end
NS_ASSUME_NONNULL_END

View File

@ -71,11 +71,6 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(attachmentUploadProgress:)
name:kAttachmentUploadProgressNotification
object:nil];
// Loki: Customize title
UILabel *titleLabel = [UILabel new];
@ -457,36 +452,6 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
}];
}
- (void)attachmentUploadProgress:(NSNotification *)notification
{
OWSLogDebug(@"upload progress.");
OWSAssertIsOnMainThread();
if (!self.outgoingMessage) {
OWSLogDebug(@"Ignoring upload progress until there is an outgoing message.");
return;
}
// TODO: Support multi-image messages.
NSString *_Nullable attachmentRecordId = self.outgoingMessage.attachmentIds.firstObject;
if (!attachmentRecordId) {
OWSLogDebug(@"Ignoring upload progress until outgoing message has an attachment record id");
return;
}
NSDictionary *userinfo = [notification userInfo];
float progress = [[userinfo objectForKey:kAttachmentUploadProgressKey] floatValue];
NSString *attachmentID = [userinfo objectForKey:kAttachmentUploadAttachmentIDKey];
if ([attachmentRecordId isEqual:attachmentID]) {
if (!isnan(progress)) {
// This is where we'd set progress if we could
} else {
OWSFailDebug(@"Invalid attachment progress.");
}
}
}
@end
NS_ASSUME_NONNULL_END