| name | mobile-p2p-sync-ios | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| summary | Couchbase Lite peer-to-peer sync for iOS/macOS (Swift) — URLEndpointListener, passive/active peer setup, TLS modes (anonymous, self-signed, CA cert), basic auth, certificate pinning, delta sync, local database-to-database replication | ||||||||||||||||||||||||
| description | Couchbase Lite peer-to-peer sync for iOS/macOS (Swift) — URLEndpointListener, passive/active peer setup, TLS modes (anonymous, self-signed, CA cert), basic auth, certificate pinning, delta sync, local database-to-database replication | ||||||||||||||||||||||||
| compatibility | Couchbase Lite iOS/macOS 4.x Enterprise Edition (Swift). P2P requires EE; local DB replication is available in CE. | ||||||||||||||||||||||||
| metadata |
|
Platform-agnostic concepts: shared/mobile/p2p-sync-concepts.md
P2P sync runs directly between devices over a local network — no Sync Gateway required. Requires Enterprise Edition.
Device A (passive — listener) Device B (active — initiator)
URLEndpointListener Replicator
└── listens on TCP port └── connects to Device A's URL
↕ WebSocket (ws:// or wss://)
import CouchbaseLiteSwift
var listenerConfig = URLEndpointListenerConfiguration(collections: [collection])
listenerConfig.port = 4984
listenerConfig.disableTLS = true
listenerConfig.authenticator = ListenerPasswordAuthenticator { username, password in
username == "device-b" && password == "secret"
}
let listener = URLEndpointListener(config: listenerConfig)
try listener.start()
let listenerURL = "ws://\(getLocalIPAddress()):\(listener.port!)/db"let target = URLEndpoint(url: URL(string: "ws://192.168.1.10:4984/db")!)
var replConfig = ReplicatorConfiguration(target: target)
replConfig.addCollection(collection)
replConfig.replicatorType = .pushAndPull
replConfig.continuous = false
replConfig.authenticator = BasicAuthenticator(username: "device-b", password: "secret")
let replicator = Replicator(config: replConfig)
let token = replicator.addChangeListener { change in
if change.status.activity == .stopped {
print("Sync complete: \(change.status.error?.localizedDescription ?? "ok")")
}
}
replicator.start()// Passive peer — generate a self-signed cert
let attrs = [certAttrCommonName: "MyDevice"]
let identity = try TLSIdentity.createIdentity(
forServer: true, attributes: attrs, expiration: nil, label: "my-listener-cert")
var listenerConfig = URLEndpointListenerConfiguration(collections: [collection])
listenerConfig.tlsIdentity = identity
listenerConfig.disableTLS = false// Active peer — pin the listener's certificate
let listenerCert: SecCertificate = /* retrieve out-of-band */
var replConfig = ReplicatorConfiguration(target: target)
replConfig.pinnedServerCertificate = listenerCertDelta sync is enabled by default in EE when both peers support it. No configuration required.
let sourceDB = try Database(name: "source", config: dbConfig)
let targetDB = try Database(name: "target", config: dbConfig)
let target = DatabaseEndpoint(database: targetDB)
var replConfig = ReplicatorConfiguration(target: target)
try replConfig.addCollection(sourceDB.defaultCollection())
replConfig.replicatorType = .push
replConfig.continuous = false
let replicator = Replicator(config: replConfig)
replicator.start()- Connection refused: verify both devices are on the same network; check firewall/ATS settings.
- TLS handshake failed: ensure the active peer has the correct pinned certificate.
- 401 Unauthorized: check
ListenerPasswordAuthenticatorcredentials matchBasicAuthenticator. - Enable
.networkand.replicatorlog domains at.debuglevel to diagnose issues (seemobile-logging-ios).