xmtp-ios

Test Lint Status

xmtp-ios 为 iOS 应用提供 XMTP 消息 API 客户端的 Swift 实现。

使用 xmtp-ios 构建 XMTP,以便在区块链账户之间发送消息,包括私信、通知、公告等。

要及时了解最新的 SDK 开发进展,请查看此仓库中的 Issues 选项卡

要了解有关 XMTP 的更多信息并获取常见问题的解答,请参阅 XMTP 文档

x-red-sm

使用 xmtp-ios 构建的示例应用

使用 XMTP iOS 快速入门应用 作为开始使用 XMTP 构建应用的工具。这个基本的消息应用具有有意保持中立的 UI,以帮助您更轻松地进行构建。

要了解示例应用推送通知,请参阅 启用快速入门应用以发送推送通知

参考文档

查看参考 访问 Swift 客户端 SDK 参考文档

从 Swift Package Manager 安装

您可以通过将 XMTP-iOS 添加到您的 Package.swift 文件或使用 Xcode 的 “Add Package Dependency” 功能,通过 Swift Package Manager 添加它。

使用概览

XMTP 消息 API 围绕消息 API 客户端(client)展开,该客户端允许检索消息并将其发送给其他 XMTP 网络参与者。客户端必须在启动时连接到钱包应用。如果这是首次创建客户端,客户端将生成一个身份,并使用加密的本地数据库来存储和检索消息。如果本地数据库不存在,则每次额外的登录都将创建一个新的安装。

// You'll want to replace this with a wallet from your application.
let account = PrivateKey()

// A key to encrypt the local database
let encryptionKey = SymmetricKey(size: .bits256)

// Application context for creating the local database
let context = UIApplication.shared.delegate

// The required client options
let clientOptions = ClientOptions(
    api: .init(env: .dev, isSecure: true),
    dbEncryptionKey: encryptionKey,
    appContext: context
)

// Create the client with your wallet. This will connect to the XMTP `dev` network by default.
// The account is anything that conforms to the `XMTP.SigningKey` protocol.
let client = try Client().create(account: account, options: clientOptions)

// Start a dm conversation
let conversation = try client.conversations.newConversation(with: "0x3F11b27F323b62B159D2642964fa27C46C841897")
// Or a group conversation
let groupConversation = try client.conversations.newGroup(with: ["0x3F11b27F323b62B159D2642964fa27C46C841897"])

// Load all messages in the conversations
let messages = try await conversation.messages()

// Send a message
try await conversation.send("gm")

// Listen for new messages in the conversation
Task {
    for await message in try await conversation.streamMessages() {
        print("\(message.senderInboxId): \(message.body)")
    }
}

创建客户端

客户端通过 Client().create(account: SigningKey, options: ClientOptions): Client 创建,这需要传入一个能够代表您创建签名的对象。客户端将为任何新安装请求签名。

注意 客户端默认连接到 XMTP dev 环境。 使用 ClientOptions 更改此设置以及网络连接的其他参数。

// Create the client with a `SigningKey` from your app
let options = ClientOptions(api: ClientOptions.Api(env: .production, isSecure: true), dbEncryptionKey: encryptionKey, appContext: context)
let client = try Client().create(account: account, options: options)

从已保存的 encryptionKey 创建客户端

您可以保存本地数据库的 encryptionKey,并通过地址构建客户端

// Create the client with a `SigningKey` from your app
let options = ClientOptions(api: ClientOptions.Api(env: .production, isSecure: true), dbEncryptionKey: encryptionKey, appContext: context)
let client = try Client().build(address: account.address, options: options)
``
### Configure the client

You can configure the client with these parameters of `Client.create`:

| Parameter  | Default     | Description                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ---------- |-------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| env        | `DEV`       | Connect to the specified XMTP network environment. Valid values include `DEV`, `.PRODUCTION`, or `LOCAL`. For important details about working with these environments, see [XMTP `production` and `dev` network environments](#xmtp-production-and-dev-network-environments).                                                                                                                                                            |
| appContext | `REQUIRED`  | The application context used to create and access the local database.                                                                                                                                                                                                                                                                                                                                                                    |
| dbEncryptionKey | `REQUIRED`  | A 32 ByteArray used to encrypt the local database.                                                                                                                                                                                                                                                                                                                                                                                       |
| historySyncUrl | `https://message-history.dev.ephemera.network/` | The history sync url used to specify where history can be synced from other devices on the network.                                                                                                                                                                                                                                                                                                                                      |
| appVersion | `undefined` | Add a client app version identifier that's included with API requests.<br/>For example, you can use the following format: `appVersion: APP_NAME + '/' + APP_VERSION`.<br/>Setting this value provides telemetry that shows which apps are using the XMTP client SDK. This information can help XMTP developers provide app support, especially around communicating important SDK updates, including deprecations and required upgrades. |

**Configure `env`**

## Handle conversations

Most of the time, when interacting with the network, you'll want to do it through `conversations`. Conversations are between two accounts.

### List all dm & group conversations

If your app would like to handle groups and dms differently you can check whether a conversation is a dm or group for the type
```swift
let conversations = try await client.conversations.list()

for conversation in conversations {
    switch conversation.type {
    case .group:
        // Handle group
    case .dm:
        // Handle DM
    }
}

列出所有群组

let groups = try await client.conversations.listGroups()

列出所有私信

let dms = try await client.conversations.listDms()

这些对话包括用户的所有对话,无论哪个应用创建了对话。 此功能提供了 可互操作收件箱 的概念,使用户可以在任何使用 XMTP 构建的应用中访问其所有对话。

监听新的对话

您还可以实时监听正在开始的新对话。这将允许应用显示来自新联系人的传入消息。

Task {
    for await conversation in try await client.conversations.stream() {
        print("New conversation started with \(conversation.peerAddress)")
        // Say hello to your new friend
        try await conversation.send("Hi there!")
    }
}

开始新的对话

您可以与 XMTP 网络上的任何以太坊地址创建新的对话。

let newDm = try client.conversations.newConversation(with: "0x3F11b27F323b62B159D2642964fa27C46C841897")
let newGroup = try client.conversations.newGroup(with: ["0x3F11b27F323b62B159D2642964fa27C46C841897"])

发送消息

为了能够发送消息,接收者必须至少创建过一次客户端。消息使用帐户地址寻址。在此示例中,消息负载是纯文本字符串。

let conversation = try client.conversations.newConversation(with: "0x3F11b27F323b62B159D2642964fa27C46C841897")
try await conversation.send("Hello world")

要了解如何发送其他类型的内容,请参阅 处理不同的内容类型

列出对话中的消息

您可以通过调用 conversation.messages() 接收对话中的完整消息历史记录

let messages = try await conversation.messages()
``
### List messages in a conversation with pagination

It may be helpful to retrieve and process the messages in a conversation page by page. You can do this by calling `conversation.messages(limit: Int, before: Date)` which will return the specified number of messages sent before that time.


```swift

let messages = try await conversation.messages(limit: 25)
let nextPage = try await conversation.messages(limit: 25, before: messages.first?.sentDate)

监听对话中的新消息

您可以通过调用 conversation.streamMessages() 监听对话中的任何新消息(传入或传出)。

成功接收的消息(通过解码和解密而没有抛出异常)可以被信任为真实的。真实意味着它是由 message.senderInboxId 帐户的所有者发送的,并且在传输过程中没有被修改。message.sent 时间戳可以被信任为由发送者设置。

stream 方法返回的流是异步数据流,它按顺序发出值,并正常完成或抛出异常。

Task {
    for await message in try await conversation.streamMessages() {
        if message.senderInboxId == client.address {
            // This message was sent from me
        }
        print("New message from \(message.senderInboxId): \(message.body)")
    }
}

请求并尊重用户同意

Feature status

用户同意功能使您的应用能够请求并尊重用户同意偏好。使用此功能,在 XMTP 网络上注册的另一个区块链帐户地址可以具有以下三个同意偏好值之一

要了解更多信息,请参阅 请求并尊重用户同意

处理不同的内容类型

所有发送函数都支持 SendOptions 作为可选参数。contentType 选项允许指定与默认简单字符串不同的内容类型,默认简单字符串使用内容类型标识符 ContentTypeText 标识。

要了解有关内容类型的更多信息,请参阅 XMTP 的内容类型

可以通过向客户端注册额外的 ContentCodec 来添加对其他内容类型的支持。每个编解码器都与内容类型标识符 ContentTypeId 相关联,该标识符用于向客户端发出信号,指示应使用哪个编解码器来处理正在发送或接收的内容。

// Assuming we've loaded a fictional NumberCodec that can be used to encode numbers,
// and is identified with ContentTypeNumber, we can use it as follows.
Client.register(codec: NumberCodec())

let options = SendOptions(contentType: .number, contentFallback: "sending you a pie")
try await aliceConversation.send(3.14, options: options)

如上面的示例所示,您必须提供 contentFallback 值。使用它来提供原始内容的类似 alt 文本的描述。提供 contentFallback 值使不支持内容类型的客户端仍然可以显示有意义的内容。

注意 如果您不提供 contentFallback 值,则不支持内容类型的客户端将显示空消息。这会导致糟糕的用户体验并破坏互操作性。

处理自定义内容类型

除此之外,自定义编解码器和内容类型可以通过 XRC 提案作为可互操作的标准。要了解有关自定义内容类型提案流程的更多信息,请参阅 XIP-5

🏗 破坏性修订

由于 xmtp-android 正在积极开发中,您应该预料到破坏性修订,这些修订可能需要您采用最新的 SDK 版本,以使您的应用能够继续按预期工作。

XMTP 在 XMTP Discord 社区 中沟通有关破坏性修订的信息,并尽可能提前通知。此外,xmtp-android 版本中的破坏性修订在 Releases 页面 上进行了描述。

弃用

旧版本的 SDK 最终将被弃用,这意味着

  1. 网络将不支持,并最终主动拒绝来自使用已弃用版本的客户端的连接。
  2. 将不会在已弃用的版本中修复错误。

下表提供了弃用时间表。

已宣布 生效 最低版本 理由
不再支持 V2 2025 年 3 月 1 日 3.0.0 为了更好地利用 MLS 提高安全性并实现去中心化,我们将关闭 V2 并完全转向 V3 MLS。您可以在此处查看旧版分支:https://github.com/xmtp/xmtp-android/tree/xmtp-legacy

欢迎根据这些 贡献指南 提交错误报告、功能请求和 PR。

XMTP productiondev 网络环境

XMTP 提供 productiondev 网络环境,以支持您项目的开发阶段。

productiondev 网络完全分离且不可互换。例如,对于给定的区块链帐户,其在 dev 网络上的 XMTP 身份与其在 production 网络上的 XMTP 身份完全不同,与这些身份关联的消息也是如此。此外,在 dev 网络上创建的 XMTP 身份和消息无法从 production 网络访问或移动到 production 网络,反之亦然。

注意 当您 创建客户端 时,它默认连接到 XMTP dev 环境。要了解如何使用 env 参数设置客户端的网络环境,请参阅 配置客户端

env 参数接受三个有效值之一:devproductionlocal。以下是关于何时使用每个环境的一些最佳实践

production 网络配置为无限期存储消息。XMTP 可能会偶尔从 dev 网络中删除消息和密钥,并将在 XMTP Discord 社区 中提前通知。