From 4b63588f1a4a7d428741fe0715823a0c3242254a Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Sun, 8 Nov 2020 09:00:10 +1100 Subject: [PATCH] Create MessageSendJob & MessageReceiveJob Also implement message sending notifications & custom TTL for typing indicators --- SessionMessagingKit/Jobs/Job.swift | 2 + .../Jobs/MessageReceiveJob.swift | 51 ++++++++++++++ SessionMessagingKit/Jobs/MessageSendJob.swift | 57 +++++++++++++++ .../Control Message/TypingIndicator.swift | 2 + .../Messages/Message+Destination.swift | 9 +++ SessionMessagingKit/Messages/Message.swift | 4 +- .../Notification+SendingPipeline.swift | 9 --- .../MessageReceiver+Decryption.swift} | 2 +- .../MessageReceiver.swift} | 12 ++-- .../MessageSender+Encryption.swift} | 2 +- .../MessageSender.swift} | 43 +++++++++--- .../Notification+MessageSender.swift | 9 +++ .../ClosedGroupRatchet.swift | 2 +- .../ClosedGroupSenderKey.swift | 2 +- SessionSnodeKit/OnionRequestAPI.swift | 1 - SessionSnodeKit/Snode.swift | 2 +- Signal.xcodeproj/project.pbxproj | 70 +++++++++++++------ 17 files changed, 225 insertions(+), 54 deletions(-) create mode 100644 SessionMessagingKit/Jobs/Job.swift create mode 100644 SessionMessagingKit/Jobs/MessageReceiveJob.swift create mode 100644 SessionMessagingKit/Jobs/MessageSendJob.swift create mode 100644 SessionMessagingKit/Messages/Message+Destination.swift delete mode 100644 SessionMessagingKit/Pipelines/Notification+SendingPipeline.swift rename SessionMessagingKit/{Pipelines/ReceivingPipeline+Decryption.swift => Sending & Receiving/MessageReceiver+Decryption.swift} (98%) rename SessionMessagingKit/{Pipelines/ReceivingPipeline.swift => Sending & Receiving/MessageReceiver.swift} (85%) rename SessionMessagingKit/{Pipelines/SendingPipeline+Encryption.swift => Sending & Receiving/MessageSender+Encryption.swift} (97%) rename SessionMessagingKit/{Pipelines/SendingPipeline.swift => Sending & Receiving/MessageSender.swift} (68%) create mode 100644 SessionMessagingKit/Sending & Receiving/Notification+MessageSender.swift diff --git a/SessionMessagingKit/Jobs/Job.swift b/SessionMessagingKit/Jobs/Job.swift new file mode 100644 index 000000000..ebede2ecc --- /dev/null +++ b/SessionMessagingKit/Jobs/Job.swift @@ -0,0 +1,2 @@ + +public protocol Job { } diff --git a/SessionMessagingKit/Jobs/MessageReceiveJob.swift b/SessionMessagingKit/Jobs/MessageReceiveJob.swift new file mode 100644 index 000000000..15289800a --- /dev/null +++ b/SessionMessagingKit/Jobs/MessageReceiveJob.swift @@ -0,0 +1,51 @@ +import SessionUtilities + +public final class MessageReceiveJob : NSObject, Job, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility + private let data: Data + private var failureCount: UInt + + // MARK: Settings + private static let maxRetryCount: UInt = 20 + + // MARK: Initialization + init(data: Data) { + self.data = data + self.failureCount = 0 + } + + // MARK: Coding + public init?(coder: NSCoder) { + guard let data = coder.decodeObject(forKey: "data") as! Data? else { return nil } + self.data = data + self.failureCount = coder.decodeObject(forKey: "failureCount") as! UInt? ?? 0 + } + + public func encode(with coder: NSCoder) { + coder.encode(data, forKey: "data") + coder.encode(failureCount, forKey: "failureCount") + } + + // MARK: Running + public func execute() { + Configuration.shared.storage.with { transaction in // Intentionally capture self + Threading.workQueue.async { + do { + let _ = try MessageReceiver.parse(self.data) + self.handleSuccess() + } catch { + SNLog("Couldn't parse message due to error: \(error).") + self.handleFailure(error: error) + } + } + } + } + + private func handleSuccess() { + + } + + private func handleFailure(error: Error) { + self.failureCount += 1 + } +} + diff --git a/SessionMessagingKit/Jobs/MessageSendJob.swift b/SessionMessagingKit/Jobs/MessageSendJob.swift new file mode 100644 index 000000000..f4e0fba2c --- /dev/null +++ b/SessionMessagingKit/Jobs/MessageSendJob.swift @@ -0,0 +1,57 @@ +import SessionUtilities + +// TODO: Destination encoding & decoding + +public final class MessageSendJob : NSObject, Job, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility + private let message: Message + private let destination: Message.Destination + private var failureCount: UInt + + // MARK: Settings + private static let maxRetryCount: UInt = 20 + + // MARK: Initialization + init(message: Message, destination: Message.Destination) { + self.message = message + self.destination = destination + self.failureCount = 0 + } + + // MARK: Coding + public init?(coder: NSCoder) { + guard let message = coder.decodeObject(forKey: "message") as! Message?, + let destination = coder.decodeObject(forKey: "destination") as! Message.Destination? else { return nil } + self.message = message + self.destination = destination + self.failureCount = coder.decodeObject(forKey: "failureCount") as! UInt? ?? 0 + } + + public func encode(with coder: NSCoder) { + coder.encode(message, forKey: "message") + coder.encode(destination, forKey: "destination") + coder.encode(failureCount, forKey: "failureCount") + } + + // MARK: Running + public func execute() { + Configuration.shared.storage.with { transaction in // Intentionally capture self + Threading.workQueue.async { + MessageSender.send(self.message, to: self.destination, using: transaction).done(on: Threading.workQueue) { + self.handleSuccess() + }.catch(on: Threading.workQueue) { error in + SNLog("Couldn't send message due to error: \(error).") + self.handleFailure(error: error) + } + } + } + } + + private func handleSuccess() { + + } + + private func handleFailure(error: Error) { + self.failureCount += 1 + } +} + diff --git a/SessionMessagingKit/Messages/Control Message/TypingIndicator.swift b/SessionMessagingKit/Messages/Control Message/TypingIndicator.swift index 0fdec4952..3bd072032 100644 --- a/SessionMessagingKit/Messages/Control Message/TypingIndicator.swift +++ b/SessionMessagingKit/Messages/Control Message/TypingIndicator.swift @@ -4,6 +4,8 @@ import SessionUtilities public final class TypingIndicator : ControlMessage { public var kind: Kind? + public override class var ttl: UInt64 { 30 * 1000 } + // MARK: Kind public enum Kind : String { case started, stopped diff --git a/SessionMessagingKit/Messages/Message+Destination.swift b/SessionMessagingKit/Messages/Message+Destination.swift new file mode 100644 index 000000000..f35a2181c --- /dev/null +++ b/SessionMessagingKit/Messages/Message+Destination.swift @@ -0,0 +1,9 @@ + +public extension Message { + + enum Destination { + case contact(publicKey: String) + case closedGroup(groupPublicKey: String) + case openGroup(channel: UInt64, server: String) + } +} diff --git a/SessionMessagingKit/Messages/Message.swift b/SessionMessagingKit/Messages/Message.swift index c0d1f240f..05d1981a9 100644 --- a/SessionMessagingKit/Messages/Message.swift +++ b/SessionMessagingKit/Messages/Message.swift @@ -1,13 +1,15 @@ /// Abstract base class for `VisibleMessage` and `ControlMessage`. @objc(SNMessage) -public class Message : NSObject, NSCoding { // Not a protocol for YapDatabase compatibility +public class Message : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility public var id: String? public var threadID: String? public var sentTimestamp: UInt64? public var receivedTimestamp: UInt64? public var recipient: String? + public class var ttl: UInt64 { 2 * 24 * 60 * 60 * 1000 } + public override init() { } // MARK: Validation diff --git a/SessionMessagingKit/Pipelines/Notification+SendingPipeline.swift b/SessionMessagingKit/Pipelines/Notification+SendingPipeline.swift deleted file mode 100644 index e17cfe518..000000000 --- a/SessionMessagingKit/Pipelines/Notification+SendingPipeline.swift +++ /dev/null @@ -1,9 +0,0 @@ - -public extension Notification.Name { - - static let calculatingPoW = Notification.Name("calculatingPoW") - static let routing = Notification.Name("routing") - static let messageSending = Notification.Name("messageSending") - static let messageSent = Notification.Name("messageSent") - static let messageFailed = Notification.Name("messageFailed") -} diff --git a/SessionMessagingKit/Pipelines/ReceivingPipeline+Decryption.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Decryption.swift similarity index 98% rename from SessionMessagingKit/Pipelines/ReceivingPipeline+Decryption.swift rename to SessionMessagingKit/Sending & Receiving/MessageReceiver+Decryption.swift index 328cfc964..f93b5779a 100644 --- a/SessionMessagingKit/Pipelines/ReceivingPipeline+Decryption.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Decryption.swift @@ -2,7 +2,7 @@ import CryptoSwift import SessionProtocolKit import SessionUtilities -public extension ReceivingPipeline { +public extension MessageReceiver { static func decryptWithSharedSenderKeys(envelope: SNProtoEnvelope, using transaction: Any) throws -> (plaintext: Data, senderPublicKey: String) { // 1. ) Check preconditions diff --git a/SessionMessagingKit/Pipelines/ReceivingPipeline.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift similarity index 85% rename from SessionMessagingKit/Pipelines/ReceivingPipeline.swift rename to SessionMessagingKit/Sending & Receiving/MessageReceiver.swift index 5a13280d1..62b1ea6b8 100644 --- a/SessionMessagingKit/Pipelines/ReceivingPipeline.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift @@ -1,9 +1,10 @@ import SessionUtilities -public enum ReceivingPipeline { +public enum MessageReceiver { public enum Error : LocalizedError { case invalidMessage + case unknownMessage // Shared sender keys case invalidGroupPublicKey case noData @@ -14,6 +15,7 @@ public enum ReceivingPipeline { public var errorDescription: String? { switch self { case .invalidMessage: return "Invalid message." + case .unknownMessage: return "Unknown message type." // Shared sender keys case .invalidGroupPublicKey: return "Invalid group public key." case .noData: return "Received an empty envelope." @@ -24,14 +26,14 @@ public enum ReceivingPipeline { } } - public static func parse(_ ciphertext: Data) -> Message? { + public static func parse(_ ciphertext: Data) throws -> Message { let plaintext = ciphertext // TODO: Decryption let proto: SNProtoContent do { proto = try SNProtoContent.parseData(plaintext) } catch { SNLog("Couldn't parse proto due to error: \(error).") - return nil + throw error } let message: Message? = { if let readReceipt = ReadReceipt.fromProto(proto) { return readReceipt } @@ -43,10 +45,10 @@ public enum ReceivingPipeline { return nil }() if let message = message { - guard message.isValid else { return nil } + guard message.isValid else { throw Error.invalidMessage } return message } else { - return nil + return Error.unknownMessage } } } diff --git a/SessionMessagingKit/Pipelines/SendingPipeline+Encryption.swift b/SessionMessagingKit/Sending & Receiving/MessageSender+Encryption.swift similarity index 97% rename from SessionMessagingKit/Pipelines/SendingPipeline+Encryption.swift rename to SessionMessagingKit/Sending & Receiving/MessageSender+Encryption.swift index 3631ba808..950c006d6 100644 --- a/SessionMessagingKit/Pipelines/SendingPipeline+Encryption.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender+Encryption.swift @@ -1,7 +1,7 @@ import SessionProtocolKit import SessionUtilities -public extension SendingPipeline { +public extension MessageSender { static func encryptWithSignalProtocol(_ plaintext: Data, for publicKey: String, using transaction: Any) throws -> Data { return Data() diff --git a/SessionMessagingKit/Pipelines/SendingPipeline.swift b/SessionMessagingKit/Sending & Receiving/MessageSender.swift similarity index 68% rename from SessionMessagingKit/Pipelines/SendingPipeline.swift rename to SessionMessagingKit/Sending & Receiving/MessageSender.swift index 4094be66d..3b71266ae 100644 --- a/SessionMessagingKit/Pipelines/SendingPipeline.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender.swift @@ -2,17 +2,9 @@ import PromiseKit import SessionSnodeKit import SessionUtilities -// TODO: Notifications // TODO: Notify PN server -public enum SendingPipeline { - private static let ttl: UInt64 = 2 * 24 * 60 * 60 * 1000 - - public enum Destination { - case contact(publicKey: String) - case closedGroup(groupPublicKey: String) - case openGroup(channel: UInt64, server: String) - } +public enum MessageSender { public enum Error : LocalizedError { case invalidMessage @@ -30,9 +22,12 @@ public enum SendingPipeline { } } - public static func send(_ message: Message, to destination: Destination, using transaction: Any) -> Promise { + public static func send(_ message: Message, to destination: Message.Destination, using transaction: Any) -> Promise { + // Validate the message guard message.isValid else { return Promise(error: Error.invalidMessage) } + // Convert it to protobuf guard let proto = message.toProto() else { return Promise(error: Error.protoConversionFailed) } + // Serialize the protobuf let plaintext: Data do { plaintext = try proto.serializedData() @@ -40,6 +35,12 @@ public enum SendingPipeline { SNLog("Couldn't serialize proto due to error: \(error).") return Promise(error: error) } + // Encrypt the serialized protobuf + if case .contact(_) = destination { + DispatchQueue.main.async { + NotificationCenter.default.post(name: .encryptingMessage, object: NSNumber(value: message.sentTimestamp!)) + } + } let ciphertext: Data do { switch destination { @@ -51,12 +52,24 @@ public enum SendingPipeline { SNLog("Couldn't encrypt message for destination: \(destination) due to error: \(error).") return Promise(error: error) } + // Calculate proof of work + if case .contact(_) = destination { + DispatchQueue.main.async { + NotificationCenter.default.post(name: .calculatingMessagePoW, object: NSNumber(value: message.sentTimestamp!)) + } + } let recipient = message.recipient! let base64EncodedData = ciphertext.base64EncodedString() guard let (timestamp, nonce) = ProofOfWork.calculate(ttl: ttl, publicKey: recipient, data: base64EncodedData) else { SNLog("Proof of work calculation failed.") return Promise(error: Error.proofOfWorkCalculationFailed) } + // Send the result + if case .contact(_) = destination { + DispatchQueue.main.async { + NotificationCenter.default.post(name: .messageSending, object: NSNumber(value: message.sentTimestamp!)) + } + } let snodeMessage = SnodeMessage(recipient: recipient, data: base64EncodedData, ttl: ttl, timestamp: timestamp, nonce: nonce) let (promise, seal) = Promise.pending() SnodeAPI.sendMessage(snodeMessage).done(on: Threading.workQueue) { promises in @@ -79,6 +92,16 @@ public enum SendingPipeline { SNLog("Couldn't send message due to error: \(error).") seal.reject(error) } + let _ = promise.done(on: DispatchQueue.main) { + if case .contact(_) = destination { + NotificationCenter.default.post(name: .messageSent, object: NSNumber(value: message.sentTimestamp!)) + } + } + let _ = promise.catch(on: DispatchQueue.main) { _ in + if case .contact(_) = destination { + NotificationCenter.default.post(name: .messageSendingFailed, object: NSNumber(value: message.sentTimestamp!)) + } + } return promise } } diff --git a/SessionMessagingKit/Sending & Receiving/Notification+MessageSender.swift b/SessionMessagingKit/Sending & Receiving/Notification+MessageSender.swift new file mode 100644 index 000000000..b5f9d68b2 --- /dev/null +++ b/SessionMessagingKit/Sending & Receiving/Notification+MessageSender.swift @@ -0,0 +1,9 @@ + +public extension Notification.Name { + + static let encryptingMessage = Notification.Name("encryptingMessage") + static let calculatingMessagePoW = Notification.Name("calculatingPoW") + static let messageSending = Notification.Name("messageSending") + static let messageSent = Notification.Name("messageSent") + static let messageSendingFailed = Notification.Name("messageSendingFailed") +} diff --git a/SessionProtocolKit/Shared Sender Keys/ClosedGroupRatchet.swift b/SessionProtocolKit/Shared Sender Keys/ClosedGroupRatchet.swift index 17af7e5f3..d6575022d 100644 --- a/SessionProtocolKit/Shared Sender Keys/ClosedGroupRatchet.swift +++ b/SessionProtocolKit/Shared Sender Keys/ClosedGroupRatchet.swift @@ -1,6 +1,6 @@ import SessionUtilities -public final class ClosedGroupRatchet : NSObject, NSCoding { // Not a struct for YapDatabase compatibility +public final class ClosedGroupRatchet : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility public let chainKey: String public let keyIndex: UInt public let messageKeys: [String] diff --git a/SessionProtocolKit/Shared Sender Keys/ClosedGroupSenderKey.swift b/SessionProtocolKit/Shared Sender Keys/ClosedGroupSenderKey.swift index c028ec8b1..05e81f3f0 100644 --- a/SessionProtocolKit/Shared Sender Keys/ClosedGroupSenderKey.swift +++ b/SessionProtocolKit/Shared Sender Keys/ClosedGroupSenderKey.swift @@ -1,5 +1,5 @@ -public final class ClosedGroupSenderKey : NSObject, NSCoding { // Not a struct for YapDatabase compatibility +public final class ClosedGroupSenderKey : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility public let chainKey: Data public let keyIndex: UInt public let publicKey: Data diff --git a/SessionSnodeKit/OnionRequestAPI.swift b/SessionSnodeKit/OnionRequestAPI.swift index 18755a5e1..9e37de9ff 100644 --- a/SessionSnodeKit/OnionRequestAPI.swift +++ b/SessionSnodeKit/OnionRequestAPI.swift @@ -137,7 +137,6 @@ public enum OnionRequestAPI { } }.map2 { paths in OnionRequestAPI.paths = paths + reusablePaths - Configuration.shared.storage.with { transaction in SNLog("Persisting onion request paths to database.") Configuration.shared.storage.setOnionRequestPaths(to: paths, using: transaction) diff --git a/SessionSnodeKit/Snode.swift b/SessionSnodeKit/Snode.swift index 08aa61c28..31e639737 100644 --- a/SessionSnodeKit/Snode.swift +++ b/SessionSnodeKit/Snode.swift @@ -1,6 +1,6 @@ import Foundation -public final class Snode : NSObject, NSCoding { // Not a struct for YapDatabase compatibility +public final class Snode : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility public let address: String public let port: UInt16 internal let publicKeySet: KeySet diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index f9acf1ca6..78e5c8c3a 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -573,8 +573,8 @@ C300A5D32554B05A00555489 /* TypingIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5D22554B05A00555489 /* TypingIndicator.swift */; }; C300A5DD2554B06600555489 /* ClosedGroupUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5DC2554B06600555489 /* ClosedGroupUpdate.swift */; }; C300A5E72554B07300555489 /* ExpirationTimerUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5E62554B07300555489 /* ExpirationTimerUpdate.swift */; }; - C300A5F22554B09800555489 /* SendingPipeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5F12554B09800555489 /* SendingPipeline.swift */; }; - C300A5FC2554B0A000555489 /* ReceivingPipeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5FB2554B0A000555489 /* ReceivingPipeline.swift */; }; + C300A5F22554B09800555489 /* MessageSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5F12554B09800555489 /* MessageSender.swift */; }; + C300A5FC2554B0A000555489 /* MessageReceiver.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5FB2554B0A000555489 /* MessageReceiver.swift */; }; C300A60D2554B31900555489 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A5CE2553860700C340D1 /* Logging.swift */; }; C300A6322554B6D100555489 /* NSDate+Timestamp.mm in Sources */ = {isa = PBXBuildFile; fileRef = C300A6312554B6D100555489 /* NSDate+Timestamp.mm */; }; C300A63B2554B72200555489 /* NSDate+Timestamp.h in Headers */ = {isa = PBXBuildFile; fileRef = C300A6302554B68200555489 /* NSDate+Timestamp.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -588,14 +588,18 @@ C31FFE57254A5FFE00F19441 /* KeyPairUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31FFE56254A5FFE00F19441 /* KeyPairUtilities.swift */; }; C329FEEC24F7277900B1C64C /* LightModeSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C329FEEB24F7277900B1C64C /* LightModeSheet.swift */; }; C329FEEF24F7743F00B1C64C /* UIViewController+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C329FEED24F7742E00B1C64C /* UIViewController+Utilities.swift */; }; - C3471ECB2555356A00297E91 /* SendingPipeline+Encryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471ECA2555356A00297E91 /* SendingPipeline+Encryption.swift */; }; + C3471ECB2555356A00297E91 /* MessageSender+Encryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471ECA2555356A00297E91 /* MessageSender+Encryption.swift */; }; C3471ED42555386B00297E91 /* AESGCM.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A5D72553860B00C340D1 /* AESGCM.swift */; }; C3471F4225553A4D00297E91 /* Threading.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471F4125553A4D00297E91 /* Threading.swift */; }; - C3471F4C25553AB000297E91 /* ReceivingPipeline+Decryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471F4B25553AB000297E91 /* ReceivingPipeline+Decryption.swift */; }; + C3471F4C25553AB000297E91 /* MessageReceiver+Decryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471F4B25553AB000297E91 /* MessageReceiver+Decryption.swift */; }; C3471F5625553E1100297E91 /* ECKeyPair+Utilities.h in Headers */ = {isa = PBXBuildFile; fileRef = C3471F5525553DA000297E91 /* ECKeyPair+Utilities.h */; settings = {ATTRIBUTES = (Public, ); }; }; C3471F6825553E7600297E91 /* ECKeyPair+Utilities.m in Sources */ = {isa = PBXBuildFile; fileRef = C3471F6725553E7600297E91 /* ECKeyPair+Utilities.m */; }; - C3471FA42555439E00297E91 /* Notification+SendingPipeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471FA32555439E00297E91 /* Notification+SendingPipeline.swift */; }; + C3471FA42555439E00297E91 /* Notification+MessageSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471FA32555439E00297E91 /* Notification+MessageSender.swift */; }; C34C8F7423A7830B00D82669 /* SpaceMono-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C34C8F7323A7830A00D82669 /* SpaceMono-Bold.ttf */; }; + C352A2F525574B4700338F3E /* Job.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352A2F425574B4700338F3E /* Job.swift */; }; + C352A2FF25574B6300338F3E /* MessageSendJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352A2FE25574B6300338F3E /* MessageSendJob.swift */; }; + C352A30925574D8500338F3E /* Message+Destination.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352A30825574D8400338F3E /* Message+Destination.swift */; }; + C352A31325574F5200338F3E /* MessageReceiveJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352A31225574F5200338F3E /* MessageReceiveJob.swift */; }; C353F8F9244809150011121A /* PNOptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C353F8F8244809150011121A /* PNOptionView.swift */; }; C3548F0624456447009433A8 /* PNModeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3548F0524456447009433A8 /* PNModeVC.swift */; }; C3548F0824456AB6009433A8 /* UIView+Wrapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3548F0724456AB6009433A8 /* UIView+Wrapping.swift */; }; @@ -1574,8 +1578,8 @@ C300A5D22554B05A00555489 /* TypingIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypingIndicator.swift; sourceTree = ""; }; C300A5DC2554B06600555489 /* ClosedGroupUpdate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClosedGroupUpdate.swift; sourceTree = ""; }; C300A5E62554B07300555489 /* ExpirationTimerUpdate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpirationTimerUpdate.swift; sourceTree = ""; }; - C300A5F12554B09800555489 /* SendingPipeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendingPipeline.swift; sourceTree = ""; }; - C300A5FB2554B0A000555489 /* ReceivingPipeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReceivingPipeline.swift; sourceTree = ""; }; + C300A5F12554B09800555489 /* MessageSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageSender.swift; sourceTree = ""; }; + C300A5FB2554B0A000555489 /* MessageReceiver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageReceiver.swift; sourceTree = ""; }; C300A6302554B68200555489 /* NSDate+Timestamp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDate+Timestamp.h"; sourceTree = ""; }; C300A6312554B6D100555489 /* NSDate+Timestamp.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDate+Timestamp.mm"; sourceTree = ""; }; C31A6C59247F214E001123EF /* UIView+Glow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Glow.swift"; sourceTree = ""; }; @@ -1588,13 +1592,17 @@ C31FFE56254A5FFE00F19441 /* KeyPairUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPairUtilities.swift; sourceTree = ""; }; C329FEEB24F7277900B1C64C /* LightModeSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LightModeSheet.swift; sourceTree = ""; }; C329FEED24F7742E00B1C64C /* UIViewController+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Utilities.swift"; sourceTree = ""; }; - C3471ECA2555356A00297E91 /* SendingPipeline+Encryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SendingPipeline+Encryption.swift"; sourceTree = ""; }; + C3471ECA2555356A00297E91 /* MessageSender+Encryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageSender+Encryption.swift"; sourceTree = ""; }; C3471F4125553A4D00297E91 /* Threading.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Threading.swift; sourceTree = ""; }; - C3471F4B25553AB000297E91 /* ReceivingPipeline+Decryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ReceivingPipeline+Decryption.swift"; sourceTree = ""; }; + C3471F4B25553AB000297E91 /* MessageReceiver+Decryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageReceiver+Decryption.swift"; sourceTree = ""; }; C3471F5525553DA000297E91 /* ECKeyPair+Utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ECKeyPair+Utilities.h"; sourceTree = ""; }; C3471F6725553E7600297E91 /* ECKeyPair+Utilities.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "ECKeyPair+Utilities.m"; sourceTree = ""; }; - C3471FA32555439E00297E91 /* Notification+SendingPipeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+SendingPipeline.swift"; sourceTree = ""; }; + C3471FA32555439E00297E91 /* Notification+MessageSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+MessageSender.swift"; sourceTree = ""; }; C34C8F7323A7830A00D82669 /* SpaceMono-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SpaceMono-Bold.ttf"; sourceTree = ""; }; + C352A2F425574B4700338F3E /* Job.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Job.swift; sourceTree = ""; }; + C352A2FE25574B6300338F3E /* MessageSendJob.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageSendJob.swift; sourceTree = ""; }; + C352A30825574D8400338F3E /* Message+Destination.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Message+Destination.swift"; sourceTree = ""; }; + C352A31225574F5200338F3E /* MessageReceiveJob.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageReceiveJob.swift; sourceTree = ""; }; C353F8F8244809150011121A /* PNOptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PNOptionView.swift; sourceTree = ""; }; C3548F0524456447009433A8 /* PNModeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PNModeVC.swift; sourceTree = ""; }; C3548F0724456AB6009433A8 /* UIView+Wrapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Wrapping.swift"; sourceTree = ""; }; @@ -3171,6 +3179,7 @@ isa = PBXGroup; children = ( C3C2A74325539EB700C340D1 /* Message.swift */, + C352A30825574D8400338F3E /* Message+Destination.swift */, C300A5C62554B02D00555489 /* Visible Message */, C300A5C72554B03900555489 /* Control Message */, ); @@ -3202,16 +3211,16 @@ path = "Control Message"; sourceTree = ""; }; - C300A5F02554B08500555489 /* Pipelines */ = { + C300A5F02554B08500555489 /* Sending & Receiving */ = { isa = PBXGroup; children = ( - C3471FA32555439E00297E91 /* Notification+SendingPipeline.swift */, - C300A5F12554B09800555489 /* SendingPipeline.swift */, - C3471ECA2555356A00297E91 /* SendingPipeline+Encryption.swift */, - C300A5FB2554B0A000555489 /* ReceivingPipeline.swift */, - C3471F4B25553AB000297E91 /* ReceivingPipeline+Decryption.swift */, + C3471FA32555439E00297E91 /* Notification+MessageSender.swift */, + C300A5F12554B09800555489 /* MessageSender.swift */, + C3471ECA2555356A00297E91 /* MessageSender+Encryption.swift */, + C300A5FB2554B0A000555489 /* MessageReceiver.swift */, + C3471F4B25553AB000297E91 /* MessageReceiver+Decryption.swift */, ); - path = Pipelines; + path = "Sending & Receiving"; sourceTree = ""; }; C31F812425258F9C00DD9FD9 /* Database */ = { @@ -3231,6 +3240,16 @@ path = Dependencies; sourceTree = ""; }; + C352A2F325574B3300338F3E /* Jobs */ = { + isa = PBXGroup; + children = ( + C352A2F425574B4700338F3E /* Job.swift */, + C352A2FE25574B6300338F3E /* MessageSendJob.swift */, + C352A31225574F5200338F3E /* MessageReceiveJob.swift */, + ); + path = Jobs; + sourceTree = ""; + }; C35E8AA42485C83B00ACB629 /* CSV */ = { isa = PBXGroup; children = ( @@ -3349,7 +3368,8 @@ C3BBE0752554CDA60050F1E3 /* Configuration.swift */, C3BBE07F2554CDD70050F1E3 /* Storage.swift */, C300A5BB2554AFFB00555489 /* Messages */, - C300A5F02554B08500555489 /* Pipelines */, + C300A5F02554B08500555489 /* Sending & Receiving */, + C352A2F325574B3300338F3E /* Jobs */, C3BBE0B32554F0D30050F1E3 /* Utilities */, ); path = SessionMessagingKit; @@ -4907,13 +4927,14 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C3471F4C25553AB000297E91 /* ReceivingPipeline+Decryption.swift in Sources */, + C3471F4C25553AB000297E91 /* MessageReceiver+Decryption.swift in Sources */, C300A5D32554B05A00555489 /* TypingIndicator.swift in Sources */, - C3471ECB2555356A00297E91 /* SendingPipeline+Encryption.swift in Sources */, - C300A5F22554B09800555489 /* SendingPipeline.swift in Sources */, + C3471ECB2555356A00297E91 /* MessageSender+Encryption.swift in Sources */, + C300A5F22554B09800555489 /* MessageSender.swift in Sources */, C3C2A74D2553A39700C340D1 /* VisibleMessage.swift in Sources */, + C352A31325574F5200338F3E /* MessageReceiveJob.swift in Sources */, C3C2A7562553A3AB00C340D1 /* VisibleMessage+Quote.swift in Sources */, - C300A5FC2554B0A000555489 /* ReceivingPipeline.swift in Sources */, + C300A5FC2554B0A000555489 /* MessageReceiver.swift in Sources */, C3BBE0B52554F0E10050F1E3 /* ProofOfWork.swift in Sources */, C3BBE0802554CDD70050F1E3 /* Storage.swift in Sources */, C3C2A7842553AAF300C340D1 /* SNProto.swift in Sources */, @@ -4924,13 +4945,16 @@ C3BBE0762554CDA60050F1E3 /* Configuration.swift in Sources */, C3471F4225553A4D00297E91 /* Threading.swift in Sources */, C300A5DD2554B06600555489 /* ClosedGroupUpdate.swift in Sources */, - C3471FA42555439E00297E91 /* Notification+SendingPipeline.swift in Sources */, + C3471FA42555439E00297E91 /* Notification+MessageSender.swift in Sources */, + C352A30925574D8500338F3E /* Message+Destination.swift in Sources */, C300A5E72554B07300555489 /* ExpirationTimerUpdate.swift in Sources */, + C352A2FF25574B6300338F3E /* MessageSendJob.swift in Sources */, C3C2A75F2553A3C500C340D1 /* VisibleMessage+LinkPreview.swift in Sources */, C3C2A74425539EB700C340D1 /* Message.swift in Sources */, C300A5C92554B04E00555489 /* SessionRequest.swift in Sources */, C3BBE0C72554F1570050F1E3 /* FixedWidthInteger+BigEndian.swift in Sources */, C300A5B22554AF9800555489 /* VisibleMessage+Profile.swift in Sources */, + C352A2F525574B4700338F3E /* Job.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };