Sign inGet Started

Swift SDK

BirdRealtime è il client Swift ufficiale per Bird Realtime: mantiene un WebSocket verso l'edge Bird, si iscrive ai canali e consegna gli eventi man mano che vengono pubblicati. È scritto a mano anziché generato, perché Realtime è un data plane WebSocket e non una superficie REST, e parla lo stesso dialetto wire del client browser.

Non ha dipendenze (URLSessionWebSocketTask per il trasporto, JSONSerialization per i frame) e gira su iOS 15+, macOS 12+, tvOS 15+, watchOS 8+ e Linux.

Questo client è il lato di ricezione. Pubblicare eventi, autorizzare canali e terminare connessioni sono operazioni lato server sulla Bird API; vedi pubblicare eventi.

Installazione

In Xcode, seleziona File > Add Package Dependencies e inserisci l'URL del repository. In un Package.swift:

Esempio di codice
dependencies: [
    .package(url: "https://github.com/messagebird/bird-sdk-swift.git", from: "0.1.0")
]

Poi aggiungi il prodotto al target che lo utilizza:

Esempio di codice
.target(
    name: "YourApp",
    dependencies: [.product(name: "BirdRealtime", package: "bird-sdk-swift")]
)

Costruire un client

Esempio di codice
import BirdRealtime

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

Solo appKey è obbligatorio, più region (us1 o eu1, che risolve l'host edge) oppure un wsHost esplicito. La app key è pubblica e viene distribuita nel codice client: identifica l'app, non autorizza nulla. Gli handler vengono eseguiti sulla coda principale, a meno che non passi un deliveryQueue.

Iscriversi a un canale

Esempio di codice
let orders = bird.subscribe("orders")
orders.bind("order-updated") { data in
    print("order changed:", data ?? "")
}

Un canale il cui nome non ha il prefisso private- o presence- è pubblico: qualsiasi client con la app key può iscriversi, quindi considera i suoi contenuti leggibili da chiunque possa aprire la tua app.

Canali privati e di presenza

I canali privati e di presenza sono autorizzati dal tuo backend, che possiede il secret dell'app. Punta il client al tuo endpoint: esegue un POST di {"connection_id", "channel_name"} e si aspetta in risposta {"auth", "member_data"?}.

Esempio di codice
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 ?? "")
}

Passa invece una closure authorizer per autenticare tramite il tuo stack di rete.

Un rifiuto dal server (una firma non valida, un'app oltre la capacità) arriva sulla connessione anziché sul canale, perché il wire non porta attribuzione di canale. Osserva questi errori con onError. Un errore all'interno del tuo authorizer emette invece bird:subscription_error sul canale.

Autenticare un membro

signin() comunica all'edge a quale membro appartiene questa connessione. Questa identità è ciò che consente alla API di indirizzare un membro o terminare le sue connessioni, ed è ciò che soddisfa un'app configurata per richiedere connessioni autorizzate.

Esempio di codice
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 ?? "")
}

Chiama signin() una sola volta. L'identità resta sulla connessione, quindi il client esegue di nuovo l'accesso automaticamente dopo una riconnessione. Un accesso automatico fallito non ha una chiamata attiva da cui lanciare un'eccezione, perciò compare su onSigninError. Questo evita che un endpoint membro non funzionante disturbi le iscrizioni ai canali.

Ciclo di vita della connessione

Esempio di codice
bird.onConnectionStateChange { previous, current in
    print("connection: \(previous) → \(current)")
}
bird.onError { error in
    if error.code == 4009 { print("session ended elsewhere") }
}

La riconnessione è automatica, con backoff esponenziale full-jitter da 1 s fino a un tetto di 30 s. I close code nell'intervallo 4000–4099 sono rifiuti e terminali: il client si ferma e riporta il codice, perché un rifiuto è una decisione e non un errore transitorio. I codici nell'intervallo 4200–4299 riconnettono immediatamente; tutti gli altri applicano il backoff. I canali si re-iscrivono con autorizzazione aggiornata a ogni riconnessione. Vedi ciclo di vita della connessione.

Il trasporto è TLS per ogni host non-loopback. allowInsecure consente ws:// solo per localhost, 127.0.0.1 e [::1], quindi una configurazione copiata da un target di sviluppo non può declassare silenziosamente il traffico di produzione.

Eventi client

Con l'impostazione client-events dell'app abilitata, un client iscritto a un canale privato o di presenza può pubblicare direttamente ai suoi peer:

Esempio di codice
try room.trigger("client-typing", data: ["on": true])

Vedi eventi client.

Sorgente

github.com/messagebird/bird-sdk-swift, licenza MIT. Segnala problemi lì.

Continua con la documentazione, le guide e gli esempi per questo argomento.