Sign inGet Started

Swift SDK

BirdRealtime é o cliente Swift oficial do Bird Realtime: ele mantém um WebSocket com a borda Bird, inscreve-se em canais e entrega eventos conforme são publicados. É escrito à mão, não gerado, porque o Realtime é um data plane WebSocket e não uma superfície REST, e fala o mesmo dialeto de protocolo que o cliente de navegador.

Não possui dependências (URLSessionWebSocketTask para transporte, JSONSerialization para frames) e roda em iOS 15+, macOS 12+, tvOS 15+, watchOS 8+ e Linux.

Este cliente é o lado de recebimento. Publicar eventos, autorizar canais e encerrar conexões são operações do lado do servidor na Bird API; veja publicação de eventos.

Instalação

No Xcode, selecione File > Add Package Dependencies e insira a URL do repositório. Em um Package.swift:

Exemplo de código
dependencies: [
    .package(url: "https://github.com/messagebird/bird-sdk-swift.git", from: "0.1.0")
]

Em seguida, adicione o produto ao target que o utiliza:

Exemplo de código
.target(
    name: "YourApp",
    dependencies: [.product(name: "BirdRealtime", package: "bird-sdk-swift")]
)

Construir um cliente

Exemplo de código
import BirdRealtime

let bird = BirdRealtime(options: .init(
    appKey: "your-app-key",
    region: "us1"
))

Apenas appKey é obrigatório, mais region (us1 ou eu1, que resolve o host de borda) ou um wsHost explícito. A app key é pública e vai no código do cliente: ela identifica o app, não autoriza nada. Os handlers rodam na fila principal, a menos que você passe um deliveryQueue.

Inscrever-se em um canal

Exemplo de código
let orders = bird.subscribe("orders")
orders.bind("order-updated") { data in
    print("order changed:", data ?? "")
}

Um canal cujo nome não tem o prefixo private- ou presence- é público: qualquer cliente com a app key pode se inscrever, então trate seu conteúdo como legível por qualquer pessoa que consiga abrir seu app.

Canais privados e de presença

Canais privados e de presença são autorizados pelo seu backend, que possui o app secret. Aponte o cliente para o seu endpoint: ele envia um POST com {"connection_id", "channel_name"} e espera {"auth", "member_data"?} de volta.

Exemplo de código
let bird = BirdRealtime(options: .init(
    appKey: "your-app-key",
    region: "us1",
    authEndpoint: URL(string: "https://your-backend.example.com/bird/auth")!,
    authHeaders: ["authorization": "Bearer <session token>"]
))

guard let room = bird.subscribe("presence-room-42") as? PresenceChannel else { return }
room.bind(BirdProtocol.Event.subscriptionSucceeded) { _ in
    print("me:", room.myId ?? "?", "members:", Array(room.members.keys))
}
room.bind(BirdProtocol.Event.memberAdded) { member in
    print("joined:", member ?? "")
}

Passe uma closure authorizer para autenticar pela sua própria stack de rede.

Uma rejeição do servidor (assinatura inválida, app acima da capacidade) chega na conexão e não no canal, porque o protocolo não inclui atribuição de canal. Observe essas rejeições com onError. Uma falha dentro do seu autorizador emite bird:subscription_error no canal.

Autenticar um membro

signin() informa à borda a qual membro esta conexão pertence. Essa identidade é o que permite ao API endereçar um membro ou encerrar suas conexões, e é o que satisfaz um app configurado para exigir conexões autorizadas.

Exemplo de código
let bird = BirdRealtime(options: .init(
    appKey: "your-app-key",
    region: "us1",
    memberAuthEndpoint: URL(string: "https://your-backend.example.com/bird/auth/member")!
))

let me = try await bird.signin()
print("signed in as", me.memberId)

bird.member.bind("order.shipped") { data in
    print("addressed to me:", data ?? "")
}

Chame signin() uma vez. A identidade permanece na conexão, então o cliente faz login novamente de forma automática após uma reconexão. Um login automático que falha não tem uma chamada ativa da qual lançar exceção, então aparece em onSigninError. Isso evita que um endpoint de membro com falha atrapalhe as inscrições em canais.

Ciclo de vida da conexão

Exemplo de código
bird.onConnectionStateChange { previous, current in
    print("connection: \(previous) → \(current)")
}
bird.onError { error in
    if error.code == 4009 { print("session ended elsewhere") }
}

A reconexão é automática, com backoff exponencial com jitter completo de 1 s até um teto de 30 s. Códigos de fechamento entre 4000–4099 são recusas e terminais: o cliente para e reporta o código, porque uma recusa é uma decisão e não uma falha transitória. Códigos entre 4200–4299 reconectam imediatamente; qualquer outro aplica backoff. Os canais se reinscrevem com autorização nova a cada reconexão. Veja ciclo de vida da conexão.

O transporte é TLS para todo host que não seja loopback. allowInsecure permite ws:// apenas para localhost, 127.0.0.1 e [::1], então uma configuração copiada de um ambiente de desenvolvimento não pode rebaixar silenciosamente o tráfego de produção.

Eventos do cliente

Com a configuração de eventos do cliente habilitada no app, um cliente inscrito em um canal privado ou de presença pode publicar diretamente para seus pares:

Exemplo de código
try room.trigger("client-typing", data: ["on": true])

Veja eventos do cliente.

Código-fonte

github.com/messagebird/bird-sdk-swift, licença MIT. Reporte problemas lá.