diff --git a/Frameworks/Bindings.txt b/Frameworks/Bindings.txt index 827d2144f2f25551d697c3f86ce201b1d998c0e4..f419aae26b68fa13d5009d2ebb8b7af1038baf92 100644 --- a/Frameworks/Bindings.txt +++ b/Frameworks/Bindings.txt @@ -1,4 +1,4 @@ -https://git.xx.network/elixxir/client/-/commit/6011849a8bbd54218f28e82afa5139b2ea529859 +https://git.xx.network/elixxir/client/-/commit/b67054452c865d2fa101e39c7ed85cbd69a99a93 go version go1.17.13 darwin/arm64 Xcode 14.0 Build version 14A309 gomobile bind target: ios,iossimulator,macos diff --git a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Bindings b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Bindings index 498568650d32fba6f77f0bfc2d340ea37a405052..137ad1861f2e96ea04558855aea0d46b1880db75 100644 Binary files a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Bindings and b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Bindings differ diff --git a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Headers/Bindings.objc.h b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Headers/Bindings.objc.h index bcfdd5d849bc6350d895e8219f70780aa633588c..75e661bc7b2b7fe085392edaa986953ade073942 100644 --- a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Headers/Bindings.objc.h +++ b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Headers/Bindings.objc.h @@ -29,6 +29,7 @@ @class BindingsFileTransfer; @class BindingsGroup; @class BindingsGroupChat; +@class BindingsGroupChatMessage; @class BindingsGroupReport; @class BindingsGroupSendReport; @class BindingsMessage; @@ -1349,6 +1350,47 @@ Returns: - (NSData* _Nullable)send:(NSData* _Nullable)groupId message:(NSData* _Nullable)message tag:(NSString* _Nullable)tag error:(NSError* _Nullable* _Nullable)error; @end +/** + * GroupChatMessage is the bindings layer representation of the +[groupChat.MessageReceive]. + +GroupChatMessage Example JSON: + { + "GroupId": "AAAAAAAJlasAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE", + "SenderId": "AAAAAAAAB8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD", + "MessageId": "Zm9ydHkgZml2ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "Payload": "Zm9ydHkgZml2ZQ==", + "Timestamp": 1663009269474079000 + } + */ +@interface BindingsGroupChatMessage : NSObject <goSeqRefInterface> { +} +@property(strong, readonly) _Nonnull id _ref; + +- (nonnull instancetype)initWithRef:(_Nonnull id)ref; +- (nonnull instancetype)init; +/** + * GroupId is the ID of the group that this message was sent on. + */ +@property (nonatomic) NSData* _Nullable groupId; +/** + * SenderId is the ID of the sender of this message. + */ +@property (nonatomic) NSData* _Nullable senderId; +/** + * MessageId is the ID of this group message. + */ +@property (nonatomic) NSData* _Nullable messageId; +/** + * Payload is the content of the message. + */ +@property (nonatomic) NSData* _Nullable payload; +/** + * Timestamp is the time this message was sent on. + */ +@property (nonatomic) int64_t timestamp; +@end + /** * GroupReport is returned when creating a new group and contains the ID of the group, a list of rounds that the group requests were sent on, and the @@ -2501,6 +2543,7 @@ Parameters: /** * GroupChatProcessor manages the handling of received group chat messages. +The decryptedMessage field will be a JSON marshalled GroupChatMessage. */ @interface BindingsGroupChatProcessor : NSObject <goSeqRefInterface, BindingsGroupChatProcessor> { } diff --git a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Bindings b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Bindings index 1a7fda0206eb4c3501c5a61596306a99026504e2..989df75ac0f6314f2bd0ce85dc6d3bc9e16db562 100644 Binary files a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Bindings and b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Bindings differ diff --git a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Headers/Bindings.objc.h b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Headers/Bindings.objc.h index bcfdd5d849bc6350d895e8219f70780aa633588c..75e661bc7b2b7fe085392edaa986953ade073942 100644 --- a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Headers/Bindings.objc.h +++ b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Headers/Bindings.objc.h @@ -29,6 +29,7 @@ @class BindingsFileTransfer; @class BindingsGroup; @class BindingsGroupChat; +@class BindingsGroupChatMessage; @class BindingsGroupReport; @class BindingsGroupSendReport; @class BindingsMessage; @@ -1349,6 +1350,47 @@ Returns: - (NSData* _Nullable)send:(NSData* _Nullable)groupId message:(NSData* _Nullable)message tag:(NSString* _Nullable)tag error:(NSError* _Nullable* _Nullable)error; @end +/** + * GroupChatMessage is the bindings layer representation of the +[groupChat.MessageReceive]. + +GroupChatMessage Example JSON: + { + "GroupId": "AAAAAAAJlasAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE", + "SenderId": "AAAAAAAAB8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD", + "MessageId": "Zm9ydHkgZml2ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "Payload": "Zm9ydHkgZml2ZQ==", + "Timestamp": 1663009269474079000 + } + */ +@interface BindingsGroupChatMessage : NSObject <goSeqRefInterface> { +} +@property(strong, readonly) _Nonnull id _ref; + +- (nonnull instancetype)initWithRef:(_Nonnull id)ref; +- (nonnull instancetype)init; +/** + * GroupId is the ID of the group that this message was sent on. + */ +@property (nonatomic) NSData* _Nullable groupId; +/** + * SenderId is the ID of the sender of this message. + */ +@property (nonatomic) NSData* _Nullable senderId; +/** + * MessageId is the ID of this group message. + */ +@property (nonatomic) NSData* _Nullable messageId; +/** + * Payload is the content of the message. + */ +@property (nonatomic) NSData* _Nullable payload; +/** + * Timestamp is the time this message was sent on. + */ +@property (nonatomic) int64_t timestamp; +@end + /** * GroupReport is returned when creating a new group and contains the ID of the group, a list of rounds that the group requests were sent on, and the @@ -2501,6 +2543,7 @@ Parameters: /** * GroupChatProcessor manages the handling of received group chat messages. +The decryptedMessage field will be a JSON marshalled GroupChatMessage. */ @interface BindingsGroupChatProcessor : NSObject <goSeqRefInterface, BindingsGroupChatProcessor> { } diff --git a/Frameworks/Bindings.xcframework/macos-arm64_x86_64/Bindings.framework/Versions/A/Bindings b/Frameworks/Bindings.xcframework/macos-arm64_x86_64/Bindings.framework/Versions/A/Bindings index 2fca34f5940ad5b67a566f4df3a4b19616c8b52d..9546147463d929ca162bac115eb326e62efd3bbc 100644 Binary files a/Frameworks/Bindings.xcframework/macos-arm64_x86_64/Bindings.framework/Versions/A/Bindings and b/Frameworks/Bindings.xcframework/macos-arm64_x86_64/Bindings.framework/Versions/A/Bindings differ diff --git a/Frameworks/Bindings.xcframework/macos-arm64_x86_64/Bindings.framework/Versions/A/Headers/Bindings.objc.h b/Frameworks/Bindings.xcframework/macos-arm64_x86_64/Bindings.framework/Versions/A/Headers/Bindings.objc.h index bcfdd5d849bc6350d895e8219f70780aa633588c..75e661bc7b2b7fe085392edaa986953ade073942 100644 --- a/Frameworks/Bindings.xcframework/macos-arm64_x86_64/Bindings.framework/Versions/A/Headers/Bindings.objc.h +++ b/Frameworks/Bindings.xcframework/macos-arm64_x86_64/Bindings.framework/Versions/A/Headers/Bindings.objc.h @@ -29,6 +29,7 @@ @class BindingsFileTransfer; @class BindingsGroup; @class BindingsGroupChat; +@class BindingsGroupChatMessage; @class BindingsGroupReport; @class BindingsGroupSendReport; @class BindingsMessage; @@ -1349,6 +1350,47 @@ Returns: - (NSData* _Nullable)send:(NSData* _Nullable)groupId message:(NSData* _Nullable)message tag:(NSString* _Nullable)tag error:(NSError* _Nullable* _Nullable)error; @end +/** + * GroupChatMessage is the bindings layer representation of the +[groupChat.MessageReceive]. + +GroupChatMessage Example JSON: + { + "GroupId": "AAAAAAAJlasAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE", + "SenderId": "AAAAAAAAB8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD", + "MessageId": "Zm9ydHkgZml2ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "Payload": "Zm9ydHkgZml2ZQ==", + "Timestamp": 1663009269474079000 + } + */ +@interface BindingsGroupChatMessage : NSObject <goSeqRefInterface> { +} +@property(strong, readonly) _Nonnull id _ref; + +- (nonnull instancetype)initWithRef:(_Nonnull id)ref; +- (nonnull instancetype)init; +/** + * GroupId is the ID of the group that this message was sent on. + */ +@property (nonatomic) NSData* _Nullable groupId; +/** + * SenderId is the ID of the sender of this message. + */ +@property (nonatomic) NSData* _Nullable senderId; +/** + * MessageId is the ID of this group message. + */ +@property (nonatomic) NSData* _Nullable messageId; +/** + * Payload is the content of the message. + */ +@property (nonatomic) NSData* _Nullable payload; +/** + * Timestamp is the time this message was sent on. + */ +@property (nonatomic) int64_t timestamp; +@end + /** * GroupReport is returned when creating a new group and contains the ID of the group, a list of rounds that the group requests were sent on, and the @@ -2501,6 +2543,7 @@ Parameters: /** * GroupChatProcessor manages the handling of received group chat messages. +The decryptedMessage field will be a JSON marshalled GroupChatMessage. */ @interface BindingsGroupChatProcessor : NSObject <goSeqRefInterface, BindingsGroupChatProcessor> { } diff --git a/Sources/XXClient/Callbacks/GroupChatProcessor.swift b/Sources/XXClient/Callbacks/GroupChatProcessor.swift index b5edc9cbcc8361f12021d62980615054386c0ece..e6ab9ee4d8535a1fb8048e6713dc99d4730e512b 100644 --- a/Sources/XXClient/Callbacks/GroupChatProcessor.swift +++ b/Sources/XXClient/Callbacks/GroupChatProcessor.swift @@ -4,7 +4,7 @@ import XCTestDynamicOverlay public struct GroupChatProcessor { public struct Callback: Equatable { public init( - decryptedMessage: Result<Data, NSError>, + decryptedMessage: GroupChatMessage, msg: Data, receptionId: Data, ephemeralId: Int64, @@ -17,7 +17,7 @@ public struct GroupChatProcessor { self.roundId = roundId } - public var decryptedMessage: Result<Data, NSError> + public var decryptedMessage: GroupChatMessage public var msg: Data public var receptionId: Data public var ephemeralId: Int64 @@ -26,14 +26,14 @@ public struct GroupChatProcessor { public init( name: String = "GroupChatProcessor", - handle: @escaping (Callback) -> Void + handle: @escaping (Result<Callback, NSError>) -> Void ) { self.name = name self.handle = handle } public var name: String - public var handle: (Callback) -> Void + public var handle: (Result<Callback, NSError>) -> Void } extension GroupChatProcessor { @@ -60,27 +60,30 @@ extension GroupChatProcessor { roundId: Int64, err: Error? ) { + if let err = err { + callback.handle(.failure(err as NSError)) + return + } + guard let decryptedMessage = decryptedMessage else { + fatalError("BindingsGroupChatProcessor received `nil` decryptedMessage") + } guard let msg = msg else { fatalError("BindingsGroupChatProcessor received `nil` msg") } guard let receptionId = receptionId else { fatalError("BindingsGroupChatProcessor received `nil` receptionId") } - let decryptedMessageResult: Result<Data, NSError> - if let err = err { - decryptedMessageResult = .failure(err as NSError) - } else if let decryptedMessage = decryptedMessage { - decryptedMessageResult = .success(decryptedMessage) - } else { - fatalError("BindingsGroupChatProcessor received `nil` decryptedMessage and `nil` error") + do { + callback.handle(.success(.init( + decryptedMessage: try GroupChatMessage.decode(decryptedMessage), + msg: msg, + receptionId: receptionId, + ephemeralId: ephemeralId, + roundId: roundId + ))) + } catch { + callback.handle(.failure(error as NSError)) } - callback.handle(.init( - decryptedMessage: decryptedMessageResult, - msg: msg, - receptionId: receptionId, - ephemeralId: ephemeralId, - roundId: roundId - )) } func string() -> String { diff --git a/Sources/XXClient/Models/GroupChatMessage.swift b/Sources/XXClient/Models/GroupChatMessage.swift new file mode 100644 index 0000000000000000000000000000000000000000..8edeae042c5bd4a08612c6ce6310de54660d8dc1 --- /dev/null +++ b/Sources/XXClient/Models/GroupChatMessage.swift @@ -0,0 +1,41 @@ +import Foundation + +public struct GroupChatMessage: Equatable { + public init( + groupId: Data, + senderId: Data, + messageId: Data, + payload: Data, + timestamp: Int64 + ) { + self.groupId = groupId + self.senderId = senderId + self.messageId = messageId + self.payload = payload + self.timestamp = timestamp + } + + public var groupId: Data + public var senderId: Data + public var messageId: Data + public var payload: Data + public var timestamp: Int64 +} + +extension GroupChatMessage: Codable { + enum CodingKeys: String, CodingKey { + case groupId = "GroupId" + case senderId = "SenderId" + case messageId = "MessageId" + case payload = "Payload" + case timestamp = "Timestamp" + } + + public static func decode(_ data: Data) throws -> Self { + try JSONDecoder().decode(Self.self, from: data) + } + + public func encode() throws -> Data { + try JSONEncoder().encode(self) + } +} diff --git a/Tests/XXClientTests/Models/GroupChatMessageTests.swift b/Tests/XXClientTests/Models/GroupChatMessageTests.swift new file mode 100644 index 0000000000000000000000000000000000000000..dff05388f50dc7ed23aaa4c674af957ed3e41484 --- /dev/null +++ b/Tests/XXClientTests/Models/GroupChatMessageTests.swift @@ -0,0 +1,37 @@ +import CustomDump +import XCTest +@testable import XXClient + +final class GroupChatMessageTests: XCTestCase { + func testCoding() throws { + let groupIdB64 = "AAAAAAAJlasAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE" + let senderIdB64 = "AAAAAAAAB8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD" + let messageIdB64 = "Zm9ydHkgZml2ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" + let payloadB64 = "Zm9ydHkgZml2ZQ==" + let timestamp: Int64 = 1_663_009_269_474_079_000 + let jsonString = """ + { + "GroupId": "\(groupIdB64)", + "SenderId": "\(senderIdB64)", + "MessageId": "\(messageIdB64)", + "Payload": "\(payloadB64)", + "Timestamp": \(timestamp) + } + """ + let jsonData = jsonString.data(using: .utf8)! + let model = try GroupChatMessage.decode(jsonData) + + XCTAssertNoDifference(model, GroupChatMessage( + groupId: Data(base64Encoded: groupIdB64)!, + senderId: Data(base64Encoded: senderIdB64)!, + messageId: Data(base64Encoded: messageIdB64)!, + payload: Data(base64Encoded: payloadB64)!, + timestamp: timestamp + )) + + let encodedModel = try model.encode() + let decodedModel = try GroupChatMessage.decode(encodedModel) + + XCTAssertNoDifference(decodedModel, model) + } +}