xmtp-ios
为 iOS 应用提供 XMTP 消息 API 客户端的 Swift 实现。
使用 xmtp-ios
构建 XMTP,以便在区块链账户之间发送消息,包括私信、通知、公告等。
要及时了解最新的 SDK 开发进展,请查看此仓库中的 Issues 选项卡。
要了解有关 XMTP 的更多信息并获取常见问题的解答,请参阅 XMTP 文档。
使用 XMTP iOS 快速入门应用 作为开始使用 XMTP 构建应用的工具。这个基本的消息应用具有有意保持中立的 UI,以帮助您更轻松地进行构建。
要了解示例应用推送通知,请参阅 启用快速入门应用以发送推送通知。
查看参考 访问 Swift 客户端 SDK 参考文档。
您可以通过将 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,并通过地址构建客户端
// 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)")
}
}
用户同意功能使您的应用能够请求并尊重用户同意偏好。使用此功能,在 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 最终将被弃用,这意味着
下表提供了弃用时间表。
已宣布 | 生效 | 最低版本 | 理由 |
---|---|---|---|
不再支持 V2 | 2025 年 3 月 1 日 | 3.0.0 | 为了更好地利用 MLS 提高安全性并实现去中心化,我们将关闭 V2 并完全转向 V3 MLS。您可以在此处查看旧版分支:https://github.com/xmtp/xmtp-android/tree/xmtp-legacy |
欢迎根据这些 贡献指南 提交错误报告、功能请求和 PR。
XMTP 提供 production
和 dev
网络环境,以支持您项目的开发阶段。
production
和 dev
网络完全分离且不可互换。例如,对于给定的区块链帐户,其在 dev
网络上的 XMTP 身份与其在 production
网络上的 XMTP 身份完全不同,与这些身份关联的消息也是如此。此外,在 dev
网络上创建的 XMTP 身份和消息无法从 production
网络访问或移动到 production
网络,反之亦然。
注意 当您 创建客户端 时,它默认连接到 XMTP
dev
环境。要了解如何使用env
参数设置客户端的网络环境,请参阅 配置客户端。
env
参数接受三个有效值之一:dev
、production
或 local
。以下是关于何时使用每个环境的一些最佳实践
dev
: 用于使客户端与 dev
网络通信。作为最佳实践,在开发和测试您的应用时,将 env
设置为 dev
。遵循此最佳实践可以将测试消息隔离到 dev
收件箱。
production
: 用于使客户端与 production
网络通信。作为最佳实践,当您的应用为真实用户提供服务时,将 env
设置为 production
。遵循此最佳实践可以将真实用户之间的消息隔离到 production
收件箱。
local
: 用于使客户端与您在本地运行的 XMTP 节点通信。例如,XMTP 节点开发人员可以将 env
设置为 local
,以生成客户端流量来测试本地运行的节点。
production
网络配置为无限期存储消息。XMTP 可能会偶尔从 dev
网络中删除消息和密钥,并将在 XMTP Discord 社区 中提前通知。