Advertise and Discover

Set up the Connection Manager

The connection manager handles all connection events and is the interface for transferring data between devices. It is a requirement for both advertisement and discovery.

First, A service ID should be chosen to uniquely identify your app. As a best practice, use the package name of your app (for example, com.example.app).

Next, choose a strategy for your use case. The strategy you select determines the connection topology for your app (.cluster, .star .pointToPoint).

Initialize the connection manager and implement its delegate methods:

Swift

import NearbyConnections

class Example {
  let connectionManager: ConnectionManager

  init() {
    connectionManager = ConnectionManager(serviceID: "com.example.app", strategy: .cluster)
    connectionManager.delegate = self
  }
}

extension Example: ConnectionManagerDelegate {
  func connectionManager(
    _ connectionManager: ConnectionManager, didReceive verificationCode: String,
    from endpointID: EndpointID, verificationHandler: @escaping (Bool) -> Void) {
    // Optionally show the user the verification code. Your app should call this handler
    // with a value of `true` if the nearby endpoint should be trusted, or `false`
    // otherwise.
    verificationHandler(true)
  }

  func connectionManager(
    _ connectionManager: ConnectionManager, didReceive data: Data,
    withID payloadID: PayloadID, from endpointID: EndpointID) {
    // A simple byte payload has been received. This will always include the full data.
  }

  func connectionManager(
    _ connectionManager: ConnectionManager, didReceive stream: InputStream,
    withID payloadID: PayloadID, from endpointID: EndpointID,
    cancellationToken token: CancellationToken) {
    // We have received a readable stream.
  }

  func connectionManager(
    _ connectionManager: ConnectionManager,
    didStartReceivingResourceWithID payloadID: PayloadID,
    from endpointID: EndpointID, at localURL: URL,
    withName name: String, cancellationToken token: CancellationToken) {
    // We have started receiving a file. We will receive a separate transfer update
    // event when complete.
  }

  func connectionManager(
    _ connectionManager: ConnectionManager,
    didReceiveTransferUpdate update: TransferUpdate,
    from endpointID: EndpointID, forPayload payloadID: PayloadID) {
    // A success, failure, cancelation or progress update.
  }

  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.
    }
  }
}

Start Advertising

To start advertising, initialize the advertiser, implement its delegate methods, and make a call to startAdvertising(using:).

Swift

import NearbyConnections

class Example {
  let connectionManager: ConnectionManager
  let advertiser: Advertiser

  init() {
    connectionManager = ConnectionManager(serviceID: "com.example.app", strategy: .cluster)
    connectionManager.delegate = self

    advertiser = Advertiser(connectionManager: connectionManager)
    advertiser.delegate = self

    // The endpoint info can be used to provide arbitrary information to the
    // discovering device (e.g. device name or type).
    advertiser.startAdvertising(using: "My Device".data(using: .utf8)!)
  }
}

extension Example: AdvertiserDelegate {
  func advertiser(
    _ advertiser: Advertiser, didReceiveConnectionRequestFrom endpointID: EndpointID,
    with context: Data, connectionRequestHandler: @escaping (Bool) -> Void) {
    // Accept or reject any incoming connection requests. The connection will still need to
    // be verified in the connection manager delegate.
    connectionRequestHandler(true)
  }
}

Start Discovery

To start discovering, initialize the discoverer, implement its delegate methods, and make a call to startDiscovery().

Swift

import NearbyConnections

class Example {
  let connectionManager: ConnectionManager
  let discoverer: Discoverer

  init() {
    connectionManager = ConnectionManager(serviceID: "com.example.app", strategy: .cluster)
    connectionManager.delegate = self

    discoverer = Discoverer(connectionManager: connectionManager)
    discoverer.delegate = self

    discoverer.startDiscovery()
  }
}

extension Example: DiscovererDelegate {
  func discoverer(
    _ discoverer: Discoverer, didFind endpointID: EndpointID, with context: Data) {
    // An endpoint was found.
  }

  func discoverer(_ discoverer: Discoverer, didLose endpointID: EndpointID) {
    // A previously discovered endpoint has gone away.
  }
}