Please refer to Nearby Connections about how to setup Nearby Connections.
Short Messages
Nearby Connections allows its clients to send data within 131 bytes without establishing a connection to the remote device. Please refer to the flow below as how to transfer messages within 131 bytes.
Publisher
class Publisher {
let connectionManager: ConnectionManager
let advertiser: Advertiser
init() {
connectionManager = ConnectionManager(serviceID: <SERVICE_ID>, strategy: .pointToPoint)
advertiser = Advertiser(connectionManager: connectionManager)
}
func startPublishing() {
advertiser.startAdvertising(using: <MESSAGE_DATA>)
}
func stopPublishing() {
advertiser.stopAdvertising()
}
}
Subscriber
class Subscriber {
let connectionManager: ConnectionManager
let discoverer: Discoverer
init() {
connectionManager = ConnectionManager(serviceID: <SERVICE_ID>, strategy: .pointToPoint)
discoverer = Discoverer(connectionManager: connectionManager)
discoverer.delegate = self
}
func startSubscription() {
discoverer.startDiscovery()
}
func stopSubscription() {
discoverer.stopDiscovery()
}
}
extension Subscriber: DiscovererDelegate {
func discoverer(_ discoverer: Discoverer, didFind endpointID: EndpointID, with context: Data) {
// A remote advertising endpoint is found.
print(context) // `context` is the published message data.
}
func discoverer(_ discoverer: Discoverer, didLose endpointID: EndpointID) {
// A previously discovered endpoint has gone away.
}
}
Long Messages
For messages which are larger than 131 bytes, a connection between the devices needs to be established to transfer the message. Please refer to the flow below as how to transfer large data using Nearby Connections.
Publisher
class Publisher {
let connectionManager: ConnectionManager
let advertiser: Advertiser
init() {
connectionManager = ConnectionManager(serviceID: <SERVICE_ID>, strategy: .pointToPoint)
connectionManager.delegate = self
advertiser = Advertiser(connectionManager: connectionManager)
advertiser.delegate = self
}
func startPublishing() {
advertiser.startAdvertising(using: <ENDPOINT_INFO>)
}
func stopPublishing() {
advertiser.stopAdvertising()
}
}
extension Publisher: ConnectionManagerDelegate {
func connectionManager(
_ connectionManager: ConnectionManager, didReceive data: Data, withID payloadID: PayloadID,
from endpointID: EndpointID) {
// We can ignore implementation, because we are the publisher.
}
func connectionManager(
_ connectionManager: ConnectionManager, didReceive stream: InputStream,
withID payloadID: PayloadID,
from endpointID: EndpointID, cancellationToken token: CancellationToken) {
// We can ignore implementation, because we are the publisher.
}
func connectionManager(
_ connectionManager: ConnectionManager, didStartReceivingResourceWithID payloadID: PayloadID,
from endpointID: EndpointID, at localURL: URL, withName name: String,
cancellationToken token: CancellationToken) {
// We can ignore implementation, because we are the publisher.
}
func connectionManager(
_ connectionManager: ConnectionManager, didReceiveTransferUpdate update: TransferUpdate,
from endpointID: EndpointID, forPayload payloadID: PayloadID) {
// We can ignore implementation, because we are the publisher.
}
func connectionManager(
_ connectionManager: ConnectionManager, didChangeTo state: ConnectionState,
for endpointID: EndpointID) {
switch state {
case .connecting:
// A connection to the remote endpoint is currently being established.
case .connected:
// We're connected! Can now start sending and receiving data.
connectionManager.send(<MESSAGE_DATA>, to: [endpointID])
case .disconnected:
// We've been disconnected from this endpoint. No more data can be sent or received.
case .rejected:
// The connection was rejected by one or both sides.
}
}
}
extension Publisher: AdvertiserDelegate {
func advertiser(
_ advertiser: Advertiser, didReceiveConnectionRequestFrom endpointID: EndpointID,
with context: Data, connectionRequestHandler: @escaping (Bool) -> Void) {
// Automatically accept any incoming connection requests.
connectionRequestHandler(true)
}
}
Subscriber
class Subscriber {
let connectionManager: ConnectionManager
let discoverer: Discoverer
init() {
connectionManager = ConnectionManager(serviceID: <SERVICE_ID>, strategy: .pointToPoint)
connectionManager.delegate = self
discoverer = Discoverer(connectionManager: connectionManager)
discoverer.delegate = self
}
func startSubscription() {
discoverer.startDiscovery()
}
func stopSubscription() {
discoverer.stopDiscovery()
}
}
extension Subscriber: ConnectionManagerDelegate {
func connectionManager(
_ connectionManager: ConnectionManager, didReceive data: Data, withID payloadID: PayloadID,
from endpointID: EndpointID) {
// This always gets the full data of the payload.
print(data)
}
func connectionManager(
_ connectionManager: ConnectionManager, didReceive stream: InputStream,
withID payloadID: PayloadID,
from endpointID: EndpointID, cancellationToken token: CancellationToken) {
// We can ignore implementation because we only care about bytes payloads.
}
func connectionManager(
_ connectionManager: ConnectionManager, didStartReceivingResourceWithID payloadID: PayloadID,
from endpointID: EndpointID, at localURL: URL, withName name: String,
cancellationToken token: CancellationToken) {
// We can ignore implementation because we only care about bytes payloads.
}
func connectionManager(
_ connectionManager: ConnectionManager, didReceiveTransferUpdate update: TransferUpdate,
from endpointID: EndpointID, forPayload payloadID: PayloadID) {
// Bytes payloads are sent as a single chunk, so you'll receive TransferUpdate.success
// immediately.
}
func connectionManager(
_ connectionManager: ConnectionManager, didChangeTo state: ConnectionState,
for endpointID: EndpointID) {
switch state {
case .connecting:
// A connection to the remote endpoint is currently being established.
case .connected:
// We're connected! Can now start sending and receiving data.
case .disconnected:
// We've been disconnected from this endpoint. No more data can be sent or received.
case .rejected:
// The connection was rejected by one or both sides.
}
}
}
extension Subscriber: DiscovererDelegate {
func discoverer(_ discoverer: Discoverer, didFind endpointID: EndpointID, with context: Data) {
// An endpoint was found. We request a connection to it.
discoverer.requestConnection(to: endpointID, using: <ENDPOINT_INFO>)
}
func discoverer(_ discoverer: Discoverer, didLose endpointID: EndpointID) {
// A previously discovered endpoint has gone away.
}
}