# iOS - Swift/Objective-c

## Overview <a href="#overview" id="overview"></a>

Follow this step-by-step tutorial to implement the video playback Synchronization SDK.

While the client-side SDK will take care of most of the functionality, in order to make this sample application work, you will need to use the API\_KEY provided to you.

* Full code samples can be found here&#x20;
  * [Swift code samples](https://bitbucket.org/svmt/synch-ios-swift/src/master/)
  * [Objective-c adapter code samples](https://bitbucket.org/svmt/sample-synchsdk-ios-objc/src/master/)

## Requirements <a href="#requirements" id="requirements"></a>

To complete this guide successfully the following prerequisites are required:

* A Sceenic account
* [Xcode](https://itunes.apple.com/ua/app/xcode/id497799835?mt=12)
* Access key for Synch SDK
* iOS version 11 or higher

## Authentication <a href="#authentication" id="authentication"></a>

An `Access Token` is needed in order to allow a client to connect to a sync group.

{% hint style="danger" %}
**Note:** It is important that the client application does not request an Access Token directly from the backend. By doing that you risk exposing the API\_TOKEN and API\_SECRET.
{% endhint %}

### Acquiring an Access Token <a href="#acquiring-an-access-token" id="acquiring-an-access-token"></a>

{% tabs %}
{% tab title="cUrl(Bash)" %}

```bash
curl -iL --request GET --url https://YOUR_CAS_URL/sync/token --header 'auth-api-key: API_KEY'   --header 'auth-api-secret: API_SECRET'
```

{% endtab %}
{% endtabs %}

The `Access Token` is a JWT token - more about jwt you can read - [here](https://en.wikipedia.org/wiki/JSON_Web_Token).

A successful response will look like that:

```
{
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...."
}
```

{% hint style="info" %}
You can get your API\_KEY and API\_SECRET in your private area, [here](https://media.sceenic.co/).
{% endhint %}

{% hint style="warning" %}
**Note:** Every Sync Token corresponds to one specific sync group only. To allow two different clients to connect to the same group, the clients need to use the same `Access Token`.
{% endhint %}

## &#x20;Create a project <a href="#create-a-project" id="create-a-project"></a>

* Open Xcode and create a new project
* Choose a Single View application
* Configure your product organization, bundle, and team names
* Set the application location on your computer and press “create”

## Adding iOS SynchSDK library to the project

You can drag SynchSDK.framework to the project tree and use this library manually.

### Cocoapods <a href="#cocoapods" id="cocoapods"></a>

* Download library ([Private area](https://media.sceenic.co/)) package and unpack it
* Create a folder with the name "SynchSDK" at the root of the project
* Copy all files ("SynchSDK.framework","SynchSDK.podspec") to the folder
* You can use [Cocoapods](https://cocoapods.org/) to install SynchSDK by adding it to your Podfile\
  `pod 'SynchSDK', :path => './SynchSDK'`
* \[When using the Objective-c adapater] - do the following extra steps
  * Create a folder with the name "SynchSDK" at the root of the project
  * Copy all files ("SynchSDKAdapter.framework","SynchSDKAdapter.podspec") to the folder
  * You can use [Cocoapods](https://cocoapods.org/) to install SynchSDK by adding it to your Podfile\
    `pod 'SynchSDKAdapter', :path => './SynchSDKAdapter'`

## Instantiating the SDK

* Initialize SynchSDK object:

{% tabs %}
{% tab title="Swift" %}

```swift
let synchSDK = SyncSDK?

do {
    synchSDK = try SyncSDK(accessToken: token, userName: userName) //token - authorization token, username - name of user
    synchSDK.attachListener(self)// self - SynchListener object
} catch {
    print(error)// error is SynchTokenError
    //fallback logic
}
    
```

{% endtab %}

{% tab title="Objective-c adpater" %}

```objectivec
@interface YourViewController () <SynchListenerAdapter>
@property (nonatomic, strong) SynchSDKAdapter* synch;
end;

- (void)viewDidLoad {
    [super viewDidLoad];
    NSError* err = nil;
    _synch = [[SynchSDKAdapter alloc] initWithAccessToken: token username:@"userName" error: &err];
    if (err != NULL) {
        NSLog(@"%@", err);
        //fallbacklogic
    } 
    [_synch attachListener: self];
    
```

{% endtab %}
{% endtabs %}

* Start synchronization - To start using the SynchSDK object you will require a SynchSdk’s URL and a valid Access Token to be available before connecting.

{% tabs %}
{% tab title="Swift" %}

```swift
synchSDK.startSynchronize()
```

{% endtab %}

{% tab title="Objective-c adpater" %}

```objectivec
[synch startSynchronize];
```

{% endtab %}
{% endtabs %}

* Stop synchronization

{% tabs %}
{% tab title="Swift" %}

```swift
synchSDK.stopSynchronize()
```

{% endtab %}

{% tab title="Objective-c adpater" %}

```objectivec
[synch stopSynchronize];
```

{% endtab %}
{% endtabs %}

## Managing synchronization logic

To manage the synchronization logic we provided several callbacks and will allow you to customize the interactions you need.

* The SynchListener interface, which the StreamView implements in the sample application, will allow you to control the flow of logic of the Synchronization you are managing

{% tabs %}
{% tab title="Swift" %}

```swift

extension StreamView: SynchListener{
    func onClientList(clientList: [Client]) {
        // remote client joined to the group, update ui using adapter
    }
    
    func onSetPlaybackRate(rate: Float) {
        // setting playback rate
    }
    
    func onPlaybackFromPosition(position: Int, participantId: String) {
        // playback from position
    }
    
    func onGetPlayerPosition() -> Int {
        // getting player position
    }
    
    func onGetPlaybackRate() -> Float {
        // getting playback rate
    }
    
    func onSyncInfo(accuracy: Float, delta: Int) {
        // information about synchronization's accuracy and delta
    }
    func onResumePlay(participantId: String) { 
        player?.play()
    }
    
    func onPause(participantId: String) {
        player?.pause()
    }
    
}
```

{% endtab %}

{% tab title="Objective-c adapter" %}

```objectivec
- (void)onClientListWithClientList:(NSArray<ClientAdapter *> * _Nonnull)clientList {
    // remote client joined to the group, update ui using adapter
}

- (float)onGetPlaybackRate {
     // setting playback rate
}

- (NSInteger)onGetPlayerPosition {
        // getting player position
}

- (void)onPlaybackFromPositionWithPosition:(NSInteger)position participantId:(NSString*) participantId {
   // playback from position
}

- (void)onSetPlaybackRateWithRate:(float)rate {
     // getting playback rate
}

- (void)onSyncInfoWithAccuracy:(float)accuracy delta:(NSInteger)delta {
     // information about synchronization's accuracy and delta
}

- (void)onPauseWithParticipantId:(NSString *)participantId {
    [_player pause];
}

- (void)onResumePlayWithParticipantId:(NSString *)participantId{
    [_player play];
}
```

{% endtab %}
{% endtabs %}

## Support

Need technical support? contact us at <Support@sceenic.co>.


---

# 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://documentation.sceenic.co/synchronization-sdk/tutorials/ios/ios-swift.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.
