Skip to content

Commit

Permalink
Reply Content Type (#134)
Browse files Browse the repository at this point in the history
* add reply content type

* add the public init

* make content type id codable

* trying to make it codecable

* Get reply test passing

* format

* format

* remove codable of content type id

---------

Co-authored-by: Pat Nakajima <[email protected]>
  • Loading branch information
nplasterer and nakajima authored Aug 1, 2023
1 parent 996d707 commit 770dd3b
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 1 deletion.
10 changes: 10 additions & 0 deletions Sources/XMTP/CodecRegistry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,14 @@ struct CodecRegistry {

return TextCodec()
}

func find(for contentTypeString: String) -> any ContentCodec {
for (_, codec) in codecs {
if codec.description == contentTypeString {
return codec
}
}

return TextCodec()
}
}
4 changes: 4 additions & 0 deletions Sources/XMTP/Codecs/ContentCodec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,8 @@ public extension ContentCodec {
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}

var description: String {
contentType.description
}
}
4 changes: 4 additions & 0 deletions Sources/XMTP/Codecs/ContentTypeID.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ extension ContentTypeID {
var id: String {
"\(authorityID):\(typeID)"
}

var description: String {
"\(authorityID)/\(typeID):\(versionMajor).\(versionMinor)"
}
}
62 changes: 62 additions & 0 deletions Sources/XMTP/Codecs/ReplyCodec.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// ReplyCodec.swift
//
//
// Created by Naomi Plasterer on 7/26/23.
//

import Foundation

public let ContentTypeReply = ContentTypeID(authorityID: "xmtp.org", typeID: "reply", versionMajor: 1, versionMinor: 0)

public struct Reply {
public var reference: String
public var content: Any
public var contentType: ContentTypeID
}

public struct ReplyCodec: ContentCodec {
public var contentType = ContentTypeReply

public init() {}

public func encode(content reply: Reply) throws -> EncodedContent {
var encodedContent = EncodedContent()
let replyCodec = Client.codecRegistry.find(for: reply.contentType)

encodedContent.type = contentType
encodedContent.parameters["contentType"] = reply.contentType.description
encodedContent.parameters["reference"] = reply.reference
encodedContent.content = try encodeReply(codec: replyCodec, content: reply.content).serializedData()

return encodedContent
}

public func decode(content: EncodedContent) throws -> Reply {
guard let contentTypeString = content.parameters["contentType"] else {
throw CodecError.codecNotFound
}

guard let reference = content.parameters["reference"] else {
throw CodecError.invalidContent
}

let replyEncodedContent = try EncodedContent(serializedData: content.content)
let replyCodec = Client.codecRegistry.find(for: contentTypeString)
let replyContent = try replyCodec.decode(content: replyEncodedContent)

return Reply(
reference: reference,
content: replyContent,
contentType: replyCodec.contentType
)
}

func encodeReply<Codec: ContentCodec>(codec: Codec, content: Any) throws -> EncodedContent {
if let content = content as? Codec.T {
return try codec.encode(content: content)
} else {
throw CodecError.invalidContent
}
}
}
43 changes: 43 additions & 0 deletions Tests/XMTPTests/ReplyTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// ReplyTests.swift
//
//
// Created by Naomi Plasterer on 7/26/23.
//
import Foundation

import XCTest
@testable import XMTP

@available(iOS 15, *)
class ReplyTests: XCTestCase {
func testCanUseReplyCodec() async throws {
Client.register(codec: ReplyCodec())

let fixtures = await fixtures()
let conversation = try await fixtures.aliceClient.conversations.newConversation(with: fixtures.bobClient.address)

try await conversation.send(text: "hey alice 2 bob")

let messageToReply = try await conversation.messages()[0]

let reply = Reply(
reference: messageToReply.id,
content: "Hello",
contentType: ContentTypeText
)

try await conversation.send(
content: reply,
options: .init(contentType: ContentTypeReply)
)

let updatedMessages = try await conversation.messages()

let message = try await conversation.messages()[0]
let content: Reply = try message.content()
XCTAssertEqual("Hello", content.content as? String)
XCTAssertEqual(messageToReply.id, content.reference)
XCTAssertEqual(ContentTypeText, content.contentType)
}
}
2 changes: 1 addition & 1 deletion XMTP.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Pod::Spec.new do |spec|
#

spec.name = "XMTP"
spec.version = "0.4.3-alpha0"
spec.version = "0.4.4-alpha0"
spec.summary = "XMTP SDK Cocoapod"

# This description is used to generate tags and improve search results.
Expand Down

0 comments on commit 770dd3b

Please sign in to comment.