## 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](https://developers.google.com/nearby/connections/strategies) 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.
      }
    }

> [!NOTE]
> **Note:** After calling `stopDiscovery()`, the discoverer can still request connections to advertisers that were discovered; however, the discoverer will not discover any new advertisers until it starts discovery again.

> [!CAUTION]
> **Caution:** Since most forms of discovery entail heavy radio operations that increase the odds of established connections getting broken, a very common pattern is to invoke `stopDiscovery()` once you find all the peers you want to connect to and exchange data with.