diff --git a/SessionMessagingKit/Jobs/MessageSendJob.swift b/SessionMessagingKit/Jobs/MessageSendJob.swift index 59a592b08..5f886803d 100644 --- a/SessionMessagingKit/Jobs/MessageSendJob.swift +++ b/SessionMessagingKit/Jobs/MessageSendJob.swift @@ -1,7 +1,5 @@ import SessionUtilities -// TODO: Destination encoding & decoding - public final class MessageSendJob : NSObject, Job, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility public var delegate: JobDelegate? private let message: Message @@ -20,15 +18,35 @@ public final class MessageSendJob : NSObject, Job, NSCoding { // NSObject/NSCodi // 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 } + var rawDestination = coder.decodeObject(forKey: "destination") as! String? else { return nil } self.message = message - self.destination = destination + if rawDestination.removePrefix("contact(") { + guard rawDestination.removeSuffix(")") else { return nil } + let publicKey = rawDestination + destination = .contact(publicKey: publicKey) + } else if rawDestination.removePrefix("closedGroup") { + guard rawDestination.removeSuffix(")") else { return nil } + let groupPublicKey = rawDestination + destination = .closedGroup(groupPublicKey: groupPublicKey) + } else if rawDestination.removePrefix("openGroup") { + guard rawDestination.removeSuffix(")") else { return nil } + let components = rawDestination.split(separator: ",").map { String($0).trimmingCharacters(in: .whitespacesAndNewlines) } + guard components.count == 2, let channel = UInt64(components[0]) else { return nil } + let server = components[1] + destination = .openGroup(channel: channel, server: server) + } else { + return nil + } 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") + switch destination { + case .contact(let publicKey): coder.encode("contact(\(publicKey))", forKey: "destination") + case .closedGroup(let groupPublicKey): coder.encode("closedGroup(\(groupPublicKey))", forKey: "destination") + case .openGroup(let channel, let server): coder.encode("openGroup(\(channel), \(server))") + } coder.encode(failureCount, forKey: "failureCount") } @@ -55,3 +73,21 @@ public final class MessageSendJob : NSObject, Job, NSCoding { // NSObject/NSCodi } } +// MARK: Convenience +private extension String { + + @discardableResult + mutating func removePrefix(_ prefix: T) -> Bool { + guard hasPrefix(prefix) else { return false } + removeFirst(prefix.count) + return true + } + + @discardableResult + mutating func removeSuffix(_ suffix: T) -> Bool { + guard hasSuffix(suffix) else { return false } + removeLast(suffix.count) + return true + } +} + diff --git a/SessionSnodeKit/OnionRequestAPI.swift b/SessionSnodeKit/OnionRequestAPI.swift index fe8e08fbd..76ba81159 100644 --- a/SessionSnodeKit/OnionRequestAPI.swift +++ b/SessionSnodeKit/OnionRequestAPI.swift @@ -302,11 +302,24 @@ public enum OnionRequestAPI { endpoint = String(url[endpointStartIndex.. #import #import -#import +#import diff --git a/SessionUtilities/NSTimer+Proxying.m b/SessionUtilities/NSTimer+Proxying.m index d70d86ef8..daa3aff6a 100644 --- a/SessionUtilities/NSTimer+Proxying.m +++ b/SessionUtilities/NSTimer+Proxying.m @@ -37,7 +37,6 @@ static void *kNSTimer_SN_Proxy = &kNSTimer_SN_Proxy; #if DEBUG assert(proxy != nil); #endif - objc_setAssociatedObject(self, kNSTimer_SN_Proxy, proxy, OBJC_ASSOCIATION_RETAIN); } diff --git a/SessionUtilities/TSRequest.h b/SessionUtilities/TSRequest.h new file mode 100644 index 000000000..5c4f75d01 --- /dev/null +++ b/SessionUtilities/TSRequest.h @@ -0,0 +1,29 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +#define textSecureHTTPTimeOut 10 + +@interface TSRequest : NSMutableURLRequest + +@property (nonatomic, readonly) NSDictionary *parameters; + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithURL:(NSURL *)URL; + +- (instancetype)initWithURL:(NSURL *)URL + cachePolicy:(NSURLRequestCachePolicy)cachePolicy + timeoutInterval:(NSTimeInterval)timeoutInterval NS_UNAVAILABLE; + +- (instancetype)initWithURL:(NSURL *)URL + method:(NSString *)method + parameters:(nullable NSDictionary *)parameters; + ++ (instancetype)requestWithUrl:(NSURL *)url + method:(NSString *)method + parameters:(nullable NSDictionary *)parameters; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SessionUtilities/TSRequest.m b/SessionUtilities/TSRequest.m new file mode 100644 index 000000000..3d3fc9257 --- /dev/null +++ b/SessionUtilities/TSRequest.m @@ -0,0 +1,63 @@ +#import "TSRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation TSRequest + +- (id)initWithURL:(NSURL *)URL { + self = [super initWithURL:URL + cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData + timeoutInterval:textSecureHTTPTimeOut]; + + if (!self) { + return nil; + } + + _parameters = @{}; + + return self; +} + +- (instancetype)init +{ + return nil; +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-designated-initializers" + +- (instancetype)initWithURL:(NSURL *)URL + cachePolicy:(NSURLRequestCachePolicy)cachePolicy + timeoutInterval:(NSTimeInterval)timeoutInterval +{ + return nil; +} + +- (instancetype)initWithURL:(NSURL *)URL + method:(NSString *)method + parameters:(nullable NSDictionary *)parameters +{ + self = [super initWithURL:URL + cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData + timeoutInterval:textSecureHTTPTimeOut]; + + if (!self) { + return nil; + } + + _parameters = parameters ?: @{}; + [self setHTTPMethod:method]; + + return self; +} + ++ (instancetype)requestWithUrl:(NSURL *)url + method:(NSString *)method + parameters:(nullable NSDictionary *)parameters +{ + return [[TSRequest alloc] initWithURL:url method:method parameters:parameters]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 404d6a852..b6602c157 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -607,6 +607,8 @@ C352A3772557864000338F3E /* NSTimer+Proxying.h in Headers */ = {isa = PBXBuildFile; fileRef = C352A3762557859C00338F3E /* NSTimer+Proxying.h */; settings = {ATTRIBUTES = (Public, ); }; }; C352A3892557876500338F3E /* JobQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352A3882557876500338F3E /* JobQueue.swift */; }; C352A3932557883D00338F3E /* JobDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352A3922557883D00338F3E /* JobDelegate.swift */; }; + C352A3A62557B60D00338F3E /* TSRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = C352A3A52557B60D00338F3E /* TSRequest.m */; }; + C352A3B72557B6ED00338F3E /* TSRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = C352A3A42557B5F000338F3E /* TSRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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 */; }; @@ -1617,6 +1619,8 @@ C352A3762557859C00338F3E /* NSTimer+Proxying.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSTimer+Proxying.h"; sourceTree = ""; }; C352A3882557876500338F3E /* JobQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JobQueue.swift; sourceTree = ""; }; C352A3922557883D00338F3E /* JobDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JobDelegate.swift; sourceTree = ""; }; + C352A3A42557B5F000338F3E /* TSRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TSRequest.h; sourceTree = ""; }; + C352A3A52557B60D00338F3E /* TSRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TSRequest.m; 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 = ""; }; @@ -3368,6 +3372,8 @@ C352A36C2557858D00338F3E /* NSTimer+Proxying.m */, C3C2A5D62553860B00C340D1 /* Promise+Retrying.swift */, C3C2AC2D2553CBEB00C340D1 /* String+Trimming.swift */, + C352A3A42557B5F000338F3E /* TSRequest.h */, + C352A3A52557B60D00338F3E /* TSRequest.m */, ); path = SessionUtilities; sourceTree = ""; @@ -3821,6 +3827,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + C352A3B72557B6ED00338F3E /* TSRequest.h in Headers */, C300A63B2554B72200555489 /* NSDate+Timestamp.h in Headers */, C352A3772557864000338F3E /* NSTimer+Proxying.h in Headers */, C3471F5625553E1100297E91 /* ECKeyPair+Utilities.h in Headers */, @@ -4938,6 +4945,7 @@ C3471F6825553E7600297E91 /* ECKeyPair+Utilities.m in Sources */, C3BBE0AA2554D4DE0050F1E3 /* Dictionary+Description.swift in Sources */, C3C2AC2E2553CBEB00C340D1 /* String+Trimming.swift in Sources */, + C352A3A62557B60D00338F3E /* TSRequest.m in Sources */, C3471ED42555386B00297E91 /* AESGCM.swift in Sources */, C3BBE0A72554D4DE0050F1E3 /* Promise+Retrying.swift in Sources */, C3BBE0A92554D4DE0050F1E3 /* HTTP.swift in Sources */,