> ## Documentation Index
> Fetch the complete documentation index at: https://docs.quickblox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Setup

> Learn how to add and configure QuickBlox SDK for your app.

Follow the instructions below to ensure that QuickBlox iOS SDK runs smoothly with your app.

Visit [Key Concepts](/docs/key-concepts) page to learn the most important QuickBlox concepts.

## Get application credentials

QuickBlox application includes everything that brings messaging right into your application - chat, video calling, users, push notifications, etc. To create a QuickBlox application, follow the steps below:

1. Register a new account following [this link](https://admin.quickblox.com/signup). Type in your email and password to sign in. You can also sign in with your Google or GitHub accounts.
2. Create the app clicking **New app** button.
3. Configure the app. Type in the information about your organization into corresponding fields and click **Add** button.
4. Go to **Dashboard => *YOUR\_APP* => Overview**  section and copy your **Application ID**, **Authorization Key**, **Authorization Secret**, and **Account Key** .

## Requirements

The minimum requirements for QuickBlox iOS SDK are:

* iOS 12.0
* CocoaPods 1.1
* Xcode 11

## Install QuickBlox SDK into your app

You can install the QuickBlox iOS SDK using either SPM (Swift Package Manager) or CocoaPods.

### Swift Package Manager

<Warning>
  QuickBlox iOS SDK is available using the \[Swift Package Manager] ([https://www.swift.org/package-manager/](https://www.swift.org/package-manager/)) (SPM) since version 2.18.1 for QuickBlox and since version 2.8.1 for QuickbloxWebRTC.
</Warning>

To add QuickBlox iOS SDK to your project using SPM, you can follow these steps:

1. Open your Xcode project and navigate to File > Swift Packages > Add Package Dependency.
2. In the search bar, enter the QuickBlox repository URL: [https://github.com/QuickBlox/ios-quickblox-sdk.git](https://github.com/QuickBlox/ios-quickblox-sdk.git) or QuickbloxWebRTC repository URL: [https://github.com/QuickBlox/ios-quickblox-sdk-webrtc.git](https://github.com/QuickBlox/ios-quickblox-sdk-webrtc.git) and click Add Package.
3. Xcode will then fetch the SDK and you can add it to your project by clicking Add Package.
4. You can then import QuickBlox modules into your code and use its API.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    import Quickblox
    import QuickbloxWebRTC
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    @import Quickblox;
    @import QuickbloxWebRTC;
    ```
  </Tab>
</Tabs>

For more information on spm customization options, you can refer to the [Apple Documentation](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app).

### CocoaPods

<Note>
  [CocoaPods](https://cocoapods.org) must be installed.
</Note>

1. Create a `Podfile`. Project dependencies should be managed by CocoaPods. Create this file in the same directory with your project.

```Bash Bash theme={null}
pod init
touch Podfile
open -e Podfile
```

1. Open the created `Podfile` and enter the following code lines into it.

```Podfile Podfile theme={null}
platform :ios, "12.0"
use_frameworks!
target 'MyApp' do
    pod 'QuickBlox', '~> 2.17.10'
    pod 'Quickblox-WebRTC', '~> 2.7.6'
end
```

1. Install QuickBlox dependencies in your project.

```Bash Bash theme={null}
pod install
```

1. Import headers to start using QuickBlox frameworks.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    import Quickblox
    import QuickbloxWebRTC
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    #import <Quickblox/Quickblox.h>
    #import <QuickbloxWebRTC/QuickbloxWebRTC.h>
    ```
  </Tab>
</Tabs>

## Run script phase for archiving

Add a **Run Script Phase** to build phases of your project. Paste the following snippet into the script.

```Bash Bash theme={null}
bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/QuickbloxWebRTC.framework/strip-framework.sh"
```

This fixes the [known Apple bug](http://www.openradar.me/radar?id=6409498411401216) that does not allow to publish archives to the App store with dynamic frameworks that contain simulator platforms. Script is designed to work only for archiving.

## Add permissions

You can use our SDK in the background mode as well. If you want to receive push notifications when the app goes to background mode, this requires you to add specific app permissions. Under the app build settings, open the **Capabilities** tab and turn on **Remote notifications** checkbox only.

<img src="https://mintcdn.com/quickblox/-4CiPyZYUlxdCa4v/images/70b608b-ios_permissions_-_remote_notificaitons.png?fit=max&auto=format&n=-4CiPyZYUlxdCa4v&q=85&s=172a2d0940f9da7b21aef3b7adb3dd5d" alt="add permissions for remote notifications for iOS app" width="1400" height="443" data-path="images/70b608b-ios_permissions_-_remote_notificaitons.png" />

If you want to use video calling functionality in the background mode, set the **Audio, AirPlay, and Picture in Picture** checkboxes.

<img src="https://mintcdn.com/quickblox/4gw4x-2IrfN_sgat/images/109d08b-ios_audip_airplay.png?fit=max&auto=format&n=4gw4x-2IrfN_sgat&q=85&s=7e86777207a8863c66aa8cbad07bbcc0" alt="add permissions for Audio, AirPlay, and Picture in Picture for iOS app" width="1403" height="442" data-path="images/109d08b-ios_audip_airplay.png" />

<Note>
  Note that you need to request camera and microphone permissions at runtime.
</Note>

## Initialize QuickBlox SDK

Initialize the framework with your application credentials. Pass **Application ID**, **Authorization Key** and **Authorization Secret** via **AppDelegate** file located in the root directory of your project.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    Quickblox.initWithApplicationId(92, authKey: "wJHdOcQSxXQGWx5", authSecret: "BTFsj7Rtt27DAmT", accountKey: "7yvNe17TnjNUqDoPwfqp")
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    [Quickblox initWithApplicationId:92 authKey:@"wJHdOcQSxXQGWx5" authSecret:@"BTFsj7Rtt27DAmT" accountKey:@"7yvNe17TnjNUqDoPwfqp"];
    ```
  </Tab>
</Tabs>

<Warning>
  If you have version lower than 2.8.0, use the **QBSettings** class to set application credentials.

  *QBSettings.applicationID = 92*
  *QBSettings.authKey = "wJHdOcQSxXQGWx5"*
  *QBSettings.authSecret = "BTFsj7Rtt27DAmT"*
  *QBSettings.accountKey = "7yvNe17TnjNUqDoPwfqp"*
</Warning>

<Warning>
  **Security**

  It's not recommended to keep your **authKey** and **authSecret** inside an application in production mode, instead of this, the best approach will be to store them on your backend.
</Warning>

| Parameters    | Description                                                        |
| ------------- | ------------------------------------------------------------------ |
| applicationID | Application identifier.                                            |
| authKey       | Authorization key.                                                 |
| authSecret    | Authorization secret.                                              |
| accountKey    | Required to get actual Chat and APIendpoints for the right server. |

## Initialize QuickBlox SDK without Authorization Key and Secret

You may don't want to store **authKey** and **authSecret** inside an application for security reasons. In such case, you can initialize QuickBlox SDK with **applicationId** and **accountKey** only, and store your **authKey** and **authSecret** on your backend. But, if so, the implementation of [authentication with QuickBlox](https://docs.quickblox.com/reference/authentication) should be also moved to your backend.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    Quickblox.initWithApplicationId(92, accountKey: "7yvNe17TnjNUqDoPwfqp")
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    [Quickblox initWithApplicationId:92 accountKey:@"7yvNe17TnjNUqDoPwfqp"];
    ```
  </Tab>
</Tabs>

Then using your backend you can authorize a user in the QuickBlox system, send back the user session token, and set it to the QuickBlox SDK using `startSession(withToken:)` method. You can find out more about this in the [Set existing session](/sdks/ios-authentication#set-existing-session) section.

## Point SDK to enterprise server

To point QuickBlox SDK to the QuickBlox enterprise server, you should specify `apiEndpoint` and `chatEndpoint` in the **AppDelegate** file located in the root directory of your project.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    Quickblox.initWithApplicationId(92, authKey: "wJHdOcQSxXQGWx5", authSecret: "BTFsj7Rtt27DAmT", accountKey: "7yvNe17TnjNUqDoPwfqp")

    QBSettings.apiEndpoint = "https://yourApi.quickblox.com"
    QBSettings.chatEndpoint = "yourChat.quickblox.com"
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    [Quickblox initWithApplicationId:92 authKey:@"wJHdOcQSxXQGWx5" authSecret:@"BTFsj7Rtt27DAmT" accountKey:@"7yvNe17TnjNUqDoPwfqp"];

    [QBSettings setApiEndpoint:@"https://yourApi.quickblox.com"];
    [QBSettings setChatEndpoint:@"yourChat.quickblox.com"];
    ```
  </Tab>
</Tabs>

| Parameters    | Description                                                        |
| ------------- | ------------------------------------------------------------------ |
| applicationID | Application identifier.                                            |
| authKey       | Authorization key.                                                 |
| accountKey    | Required to get actual Chat and APIendpoints for the right server. |
| apiEndpoint   | API endpoint.                                                      |
| chatEndpoint  | Chat endpoint.                                                     |

<Note>
  [Contact our sales team](https://quickblox.com/enterprise/) to get **API endpoint** and **chat endpoint**.
</Note>

## Selection of the hashing algorithm

You can select a hash algorithm using `QBSettings.hashAlgorithm`, which supports **SHA1** and **SHA256** options starting from version 2.19.0. `QBHashAlgorithmSHA1` is set as the default option.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    QBSettings.hashAlgorithm = .SHA256
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    QBSettings.hashAlgorithm = QBHashAlgorithmSHA256;
    ```
  </Tab>
</Tabs>

SwiftObjective-C

## Enable logging

Logging functionality allows you to keep track of all events and activities while running your app. As a result, you can monitor the operation of the SDK and improve the debug efficiency. There are 3 logging use cases:

* **Server API** logging is used to monitor Server API calls.
* **Chat** logging is used to monitor chat issues.
* **WebRTC** logging is used to gather issues with video.

**Server API logging**

Enable Server API calls debug console output using the `setLogLevel()` method.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    QBSettings.setLogLevel(QBLogLevel.debug)
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    [QBSettings setLogLevel:QBLogLevelDebug];
    ```
  </Tab>
</Tabs>

A log level determines what information is written to the log. There can be set the following log levels:

| Parameters         | Description                          |
| ------------------ | ------------------------------------ |
| QBLogLevel.debug   | Write full logs (**default** value). |
| QBLogLevelNetwork  | Write network logs.                  |
| QBLogLevelInfo     | Write information logs.              |
| QBLogLevelWarnings | Write warning logs.                  |
| QBLogLevelErrors   | Write error logs.                    |
| QBLogLevelNothing  | Write nothing. Turn off logs.        |

**Chat logging**

Enable a detailed XMPP logging in the console output using the code snippet below.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    QBSettings.enableXMPPLogging()
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    [QBSettings enableXMPPLogging];
    ```
  </Tab>
</Tabs>

Disable XMPP logging using the code snippet below.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    QBSettings.disableXMPPLogging()
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    [QBSettings disableXMPPLogging];
    ```
  </Tab>
</Tabs>

**WebRTC logging**

Set WebRTC logs using the `setLogLevel()` method.

SwiftObjective-C

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    QBRTCConfig.setLogLevel(QBRTCLogLevel.verboseWithWebRTC)
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    QBRTCConfig.setLogLevel(QBRTCLogLevel.verboseWithWebRTC)
    ```
  </Tab>
</Tabs>

| Parameters                     | Description                                                                                                       |
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
| QBRTCLogLevelVerboseWithWebRTC | Write full QuickBlox WebRTC and WebRTC native logs. Can be helpful to debug some complicated problems with calls. |
| QBRTCLogLevelVerbose           | Write full QuickBlox WebRTC logs. Basic logs from our framework (**default** value).                              |
| QBRTCLogLevelInfo              | Write information logs.                                                                                           |
| QBRTCLogLevelWarnings          | Write warning logs.                                                                                               |
| QBRTCLogLevelErrors            | Write error logs.                                                                                                 |
| QBRTCLogLevelNothing           | Write nothing. Turn off logs.                                                                                     |

## Enable auto-reconnect to Chat

QuickBlox Chat runs over XMPP protocol. To receive messages in a real-time mode, the application should be connected to the Chat over XMPP protocol. To enable auto-reconnect to Chat, pass `autoReconnectEnabled()` as `true`.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    QBSettings.autoReconnectEnabled = true
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    QBSettings.autoReconnectEnabled = YES;
    ```
  </Tab>
</Tabs>

<Note>
  **By default**, the auto-reconnect functionality is disabled. Set the auto-reconnect before calling the `connect()` method so it could be applied in a current chat.
</Note>

## Message carbons

Message carbons functionality allows for multi-device support. Thus, all user messages get copied to all their devices so they could keep up with the current state of the conversation. For example, a User A has phone running conversations and desktop running conversations. User B has desktop running conversations. When User B sends a message to User A, the message shows on both the desktop and phone of User A.

**Enable message carbons**

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    QBSettings.carbonsEnabled = true
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    [QBSettings setCarbonsEnabled: YES];
    ```
  </Tab>
</Tabs>

**Disable message carbons**

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    QBSettings.carbonsEnabled = false
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    [QBSettings setCarbonsEnabled: NO];
    ```
  </Tab>
</Tabs>

\`

<Note>
  Since message carbons functionality works over XMPP connection, make sure to enable it after the `connect()` method is called.
</Note>

## Stream management

Stream management has two important features **Stanza Acknowledgements** and **Stream Resumption**:

* **Stanza Acknowledgements** is the ability to know if a stanza or series of stanzas has been received by one's peer. In other words, a reply is requested on every sent message. If the reply is received, the message is considered as delivered.
* **Stream Resumption** is the ability to quickly resume a stream that has been terminated. Once a connection is re-established, Stream Resumption is executed. By matching the sequence numbers assigned to each Stanza Acknowledgement a server and client can verify which messages are missing and request to resend missing messages.

Set message timeout to enable stream resumption. The preferred resumption time should be set in seconds. If this parameter is greater than `0`, then it is applied, otherwise, it is not applied.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    QBSettings.streamManagementSendMessageTimeout = 0
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    [QBSettings setStreamManagementSendMessageTimeout: 0];
    ```
  </Tab>
</Tabs>

<Note>
  Stream management gets enabled automatically once the `connect()` method is called and disabled once the `disconnect()` method is called.
</Note>

## Custom ICE servers

You can customize a list of ICE servers. **By default**, WebRTC module will use internal ICE servers that are usually enough, but you can always set your own. WebRTC engine will choose the TURN relay with the lowest round-trip time. Thus, setting multiple TURN servers allows your application to scale-up in terms of bandwidth and number of users. Set up ICE servers in `application(_:didFinishLaunchingWithOptions:)` method of `AppDelegate.m`.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    let username = "login"
    let password = "767565gfh865486h548k6586h5868"

    let urls = [
        "stun:turn.randomserver.example",
        "turn:turn.randomserver.example:5677?transport=udp",
        "turn:turn.randomserver.example:5677?transport=tcp"
    ]

    guard let server = QBRTCICEServer.init(urls: urls, username: username, password: password) else {
        return
    }
    QBRTCConfig.setICEServers([server])
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    NSString *userName = @"login";
    NSString *password = @"767565gfh865486h548k6586h5868";

    NSArray *urls = @[
        @"stun:turn.randomserver.example",
        @"turn:turn.randomserver.example:5677?transport=udp",
        @"turn:turn.randomserver.example:5677?transport=tcp"
    ];

    QBRTCICEServer *server = [QBRTCICEServer serverWithURLs:urls username:userName password:password];
    [QBRTCConfig setICEServers:@[server]];
    ```
  </Tab>
</Tabs>
