https://github.com/Pariette-Inc/signalbird.sdkSignalbird - Swift (iOS, macOS)
İki istemci taşır:
| Sınıf | Ne için | Anahtar | Nerede |
|---|---|---|---|
SignalbirdApp |
son kullanıcıya canlı sohbet + push kaydı | sb_public_live_… (açık) |
iOS uygulaması |
SignalbirdClient |
Telsiz - log ve olay yazma | sb_secret_live_… (gizli) |
sunucu tarafı Swift (Vapor, Hummingbird) |
Gizli anahtar iOS uygulamasına gömülmez: uygulama paketi çözülebilir ve anahtar herkesin eline geçer. Mobil taraf sohbeti ve push kaydını açık anahtarla yapar.
Kurulum
Swift Package Manager - Xcode → File → Add Package Dependencies:
https://github.com/Pariette-Inc/signalbird.sdkya da Package.swift:
dependencies: [
.package(url: "https://github.com/Pariette-Inc/signalbird.sdk", from: "1.2.0"),
],
targets: [
.target(name: "App", dependencies: [.product(name: "Signalbird", package: "signalbird.sdk")]),
]iOS 15+, macOS 12+. Bağımlılığı yoktur - yalnız Foundation/URLSession.
Canlı sohbet
import Signalbird
let client = try SignalbirdApp(config: .init(
publicKey: "sb_public_live_…",
chatKey: "destek",
pushKey: "mobil"
))chatKey sohbet kanalının, pushKey push kanalının modül anahtarıdır (panelde açtığınız kanal adları, gizli değildir). SDK cihaz ve push uçlarında (registerDevice, unregisterDevice, reportPushOpened) pushKey'i, sohbet uçlarında chatKey'i X-Signalbird-Module-Key başlığıyla gönderir; ilgili anahtar verilmezse API 400 MODULE_KEY_MISSING döner (2.10.0).
Uygulama anahtarını panelden (Gelen Kutusu → Ayarlar → Uygulamalar) ya da
Yönetim SDK'sıyla createApp çağırarak alırsınız.
Açılış
let boot = try await client.bootstrap()
guard let app = boot.dictionary?["app"] as? [String: Any],
app["chat_enabled"] as? Bool == true else {
return // Sohbet bu uygulamada kapalı - hiçbir şey çizmeyin
}bootstrap renk, karşılama metni, çalışma saatleri ve ön-form ayarlarını da
döner; arayüzünüzü panelden yönetilebilir kılmak isterseniz oradan okuyun.
Oturum ve konuşma
// Ziyaretçi oturumu - sır saklanır, sonraki açılışta geçmiş korunur
try await client.startSession(["name": "Ayşe", "email": "ayse@example.com"])
// İlk mesajla konuşma açılır. Kota burada harcanır: konuşma başına.
let started = try await client.startConversation(body: "Kargom nerede?")
let conversationID = (started.dictionary?["conversation"] as? [String: Any])?["id"] as? String ?? ""
try await client.sendMessage(conversationID: conversationID, body: "Sipariş no: 1234")Yeni mesajları çekme
// `after` imleci: yalnız bundan sonraki mesajlar döner
let updates = try await client.getConversation(conversationID, after: lastMessageID)WebSocket yoktur. Panel açıkken 3 saniyede bir, kapalıyken kademeli olarak seyrelen (20 → 60 → 180 sn) aralıklarla yoklayın; uygulama arka plandayken tur atlayın. Bu, bağlantı kopmasında kendi kendini toparlar ve pil yakmaz.
Etkileşimler
try await client.setTyping(conversationID: conversationID, isTyping: true)
try await client.markRead(conversationID: conversationID, lastMessageID: lastID)
try await client.reactToMessage(conversationID: conversationID, messageID: messageID, emoji: "👍")
// Yalnız kendi mesajı ve gönderimden sonraki 15 dakika içinde
try await client.editMessage(conversationID: conversationID, messageID: messageID, body: "Düzeltme")
try await client.deleteMessage(conversationID: conversationID, messageID: messageID)
try await client.rateConversation(conversationID, rating: 5, comment: "Teşekkürler")
try await client.closeConversation(conversationID)Kimlik
// Kullanıcı giriş yaptığında ziyaretçiyi kişi kaydına bağlar
try await client.identify([
"external_id": user.id,
"email": user.email,
"name": user.displayName,
"attributes": ["plan": "pro"],
])
// Çıkışta yerel kimliği silin; sunucudaki kayıt kalır
client.signOut()Push (APNs)
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = deviceToken.map { String(format: "%02x", $0) }.joined()
Task {
try? await client.registerDevice(
token: token,
externalID: currentUser?.id,
deviceName: UIDevice.current.name,
appVersion: Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
)
}
}Bildirim iznini istemek ve token'ı almak uygulamanın işidir: izni ne zaman soracağınız bir ürün kararıdır ve App Store bunu ciddiye alır. SDK yalnız token'ı iletir.
Çıkışta:
try await client.unregisterDevice(token: token) // kayıt silinmez, kapatılırZiyaretçi sırrının saklanması
Varsayılan UserDefaults'tur. Keychain isteyen kendi uyarlamasını verir:
struct KeychainStorage: SignalbirdStorage {
func get(_ key: String) -> String? { /* … */ }
func set(_ key: String, _ value: String) { /* … */ }
func remove(_ key: String) { /* … */ }
}
let client = try SignalbirdApp(config: .init(
publicKey: "sb_public_live_…",
chatKey: "destek",
pushKey: "mobil",
locale: "tr",
storage: KeychainStorage()
))Saklanan kayıt uygulama anahtarını da taşır: anahtarı yenilerseniz eski kimlik otomatik yok sayılır ve yeni oturum açılır. Aksi hâlde eski sırla yapılan her çağrı 401 alır ve sohbet sessizce ölürdü.
Telsiz (sunucu tarafı Swift)
let radio = try SignalbirdClient(config: .init(
domainKey: ProcessInfo.processInfo.environment["SIGNALBIRD_DOMAIN_KEY"] ?? "",
source: "api-01"
))
try await radio.critical("critical", "ödeme servisi yanıt vermiyor", [
"service": "iyzico",
])
try await radio.batch([
["channel": "deploy", "message": "v2.4.0 yayında", "level": "info"],
])Beş seviye: .debug, .info, .warn, .error, .critical.
Sonuç biçimi
public struct SbResult {
public let ok: Bool
public let status: Int
public let data: Any?
public let code: String?
public let message: String?
public var dictionary: [String: Any]? { get }
public var array: [[String: Any]]? { get }
public func decode<T: Decodable>(_ type: T.Type) -> T?
}Kendi modelinize çözmek için:
struct ConversationResponse: Decodable {
struct Conversation: Decodable { let id: String; let status: String }
let conversation: Conversation
}
let parsed = updates.decode(ConversationResponse.self)Sürüm bildirimi
SDK her istekte sürümünü bildirir: X-Signalbird-Sdk: swift/<sürüm>. Yeni bir
sürüm yayınlandığında API yanıtında Signalbird-Sdk-Status: outdated (ya da
artık desteklenmiyorsa unsupported) döner ve SDK süreç başına bir kez
uyarı yazar (print, yalnız DEBUG derlemede). Uyarı hata değildir: isteğin sonucu değişmez.
Panelde Domainler → [domain] → Anahtarlar her anahtarın hangi SDK sürümüyle kullanıldığını gösterir; eski sürümdeki anahtarlar için panelin tepesinde bir uyarı şeridi ve bildirim çıkar. Güncellemek için Xcode'da File → Packages → Update to Latest Package Versions.
Hata kodları
| Kod | Anlamı |
|---|---|
NO_KEY / WRONG_KEY_TYPE |
Kurucu fırlatır - yanlış aileden anahtar |
VISITOR_INVALID |
Sır geçersiz; yerel kimlik silinir, sonraki çağrı yeni oturum açar |
CHAT_UNAVAILABLE |
Kota doldu ya da sohbet kapalı |
MODULE_DISABLED |
Paketinizde chat ya da push modülü yok |
NETWORK_ERROR / TIMEOUT |
Ağ (status 0) |
Kurucudaki anahtar denetimi dışında hiçbir metot hata fırlatmaz; sonuç her zaman zarftır.