Please refer to [Nearby Connections](https://developers.google.com/nearby/connections/swift/get-started.md.txt) 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.
      }
    }