Page Summary
-
Nearby Connections enables communication between nearby devices using Bluetooth, Wi-Fi, and peer-to-peer connections.
-
Short messages (under 131 bytes) can be sent without establishing a connection, ideal for lightweight data exchange.
-
Long messages (over 131 bytes) require a connection for reliable transfer, supporting various data types and sizes.
-
Both publishers and subscribers need a shared service ID for successful discovery and connection establishment.
-
Connection lifecycle includes advertising, discovery, connection request, data transfer, and disconnection states.
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
.
}
}

