# Usage

### Initialization

The init method initializes the Bridgefy SDK with an API key. The delegate parameter is required and should be an object that conforms to the `BridgefyDelegate` protocol. The verboseLogging parameter is optional and enables more detailed logging if set to true.

The following code shows how to start the SDK (using your API key) and how to assign the delegate.

```swift
do {
      bridgefy = try Bridgefy(withApiKey: apiKey,
                              delegate: BridgefyDelegate,
                              verboseLogging: Bool)
} catch {
    // Handle the error
}
```

The string **apiKey** represents a valid API key. An Internet connection is needed, at least for the first time to validate the license. The **delegate** is the class that will implement all the delegate methods from the BridgefySDK.

### Start

After initializing the SDK, you should call the `start()` function to have the SDK's services running.

```swift
bridgefy.start(withUserId: UUID?,
               andPropagationProfile: PropagationProfile)
```

The optional UUID **userId** is the id that the SDK will use to identify the user. If a nil value is passed, the SDK will randomly assign a UUID. The **propagationProfile** value is the profile the SDK will use to propagate messages through the mesh.

Once the service is started, the following delegate function is called:

```swift
func bridgefyDidStart(with userId: UUID)
```

The **userId** is the id used to identify the current user/device in the BridgefySDK.

In the case an error occurs while starting the BridgefySDK, the following delegate function is called:

```swift
func bridgefyDidFailToStart(with error: BridgefyError)
```

### Propagation Profiles

```swift
enum PropagationProfile {
    case standard
    case highDensityNetwork
    case sparseNetwork
    case longReach
    case shortReach
}
```

<table data-header-hidden><thead><tr><th>Profile</th><th width="99">Hops limit</th><th width="149"></th><th width="110"></th><th width="135"></th><th></th></tr></thead><tbody><tr><td><strong>Profile</strong></td><td><strong>Hops limit</strong></td><td><strong>TTL(s)</strong></td><td><strong>Sharing Time</strong></td><td><strong>Maximum Propagation</strong></td><td><strong>Tracklist limit</strong></td></tr><tr><td>Standard</td><td>100</td><td>86400 (1 d)</td><td>15000</td><td>200</td><td>50</td></tr><tr><td>High Density Environment</td><td>50</td><td>3600 (1 h)</td><td>10000</td><td>50</td><td>50</td></tr><tr><td>Sparse Environment</td><td>100</td><td>302400 (3.5 d)</td><td>10000</td><td>250</td><td>50</td></tr><tr><td>Long Reach</td><td>250</td><td>604800 (7 d)</td><td>15000</td><td>1000</td><td>50</td></tr><tr><td>Short Reach</td><td>50</td><td>1800</td><td>10000</td><td>50</td><td>50</td></tr></tbody></table>

* **Hops limit:** The maximum number of hops a message can get. Each time a message is forwarded, is considered a hop.
* **TTL:** Time to live, is the maximum amount of time a message can be propagated since its creation.
* **Sharing time:** The maximum amount of time a message will be kept for forwarding.
* **Maximum propagation:** The maximum number of times a message will be forwarded from a device.
* **Tracklist limit:** The maximum number of UUID's stored in an array to prevent sending the message to a peer which already forwarded the message.

### Stop

To stop the SDK, use the following function:

```swift
  func stop()
```

After the service is stopped, the following delegate function is called:

```swift
func bridgefyDidStop()
```

### Destroy Session

Call this method when you want to terminate the current Bridgefy session and destroy all related data:

```swift
  func destroySession()
```

After the session is destroy, the following delegate function is called:

```swift
func bridgefyDidDestroySession()
```

### Nearby peer detection

The following method is invoked when a peer has established a connection:

```swift
func bridgefyDidConnect(with userId: UUID)
```

**userId**: Identifier of the user that has established a connection.

When a peer is disconnected(out of range), the following method will be invoked:

```swift
func bridgefyDidDisconnect(from userId: UUID)
```

**userId**: Identifier of the disconnected user.

### Sending data

The following method is used to send data using a transmission mode. This method returns a UUID to identify the message sent.

```swift
do {
    let messageID = try bridgefy.send(Data,
                                 using: TransmissionMode)
            
} catch {
    // Handle the error
}
```

**messageId**: Unique identifier related to the message.

If the message was successfully sent, the following delegate method is called:

```swift
func bridgefyDidSendMessage(with messageId: UUID)
```

**messageId**: The unique identifier of the message sent.

***Note:*** It Is important to notice that the call of this delegate method doesn't mean the message was delivered. This is due to the nature of how the messages travel through the mesh network created by the BridgefySDK. The ONLY scenario where you can assume that the message was delivered is when it was sent using the `p2p` transmission mode; otherwise, it only means that there's no pre-validation error, and the SDK will start propagating the message.

If an error occurs while sending a message, the following delegate method is called:

```swift
func bridgefyDidFailSendingMessage(with messageId: UUID,
                                   withError error: BridgefyError)
```

### Receiving Data

When a packet has been received, the following method will be invoked:

```swift
func bridgefyDidReceiveData(_ data: Data,
                            with messageId: UUID,
                            using transmissionMode: TransmissionMode)
```

**data**: Received data.

**messageId**: The id of the message that was received

**transmissionMode**: The transmission mode used to propagate a message

**Transmission Modes**:

```swift
public enum TransmissionMode {
    case p2p(userId: UUID)
    case mesh(userId: UUID)
    case broadcast(senderId: UUID)
}
```

The mode used to propagate a message through nearby devices:

**p2p(userId: UUID)**: Sends the message data only when the receiver is in range; otherwise an error is reported. **mesh(userId: UUID))**: Sends the message data using the mesh created by the SDK. It doesn’t need the receiver to be in range. **broadcast(senderId: UUID)**: Sends a packet using mesh without a defined receiver. The packet is broadcast to all nearby users that are or aren’t in range.

### Direct and mesh transmission

Direct transmission is a mechanism used to deliver packets to a user that is nearby or visible (a connection has been detected).

Mesh transmission is a mechanism used to deliver offline packets even when the receiving user isn’t nearby or visible. It can be achieved by taking advantage of other nearby peers; these receive the package, hold it, and forward it to other peers trying to find the receiver.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.bridgefy.me/sdk/ios/usage.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
