Come and work for Dabick! We are always looking for talented people. Entertainment. Together. Live.
Previous Next Button Button
iOSa Android

Android Platform Overview

Looking for your app users to watch their favorite videos or view their photos with friends and family, live with chat? Look no further!

DabKick's Media Call SDK enables your users to watch their favorite media (videos and photos) together with their friends and family, live with chat capabilities, either via text or live streaming. A WatchWithFriends (WWF) button, designed by DabKick or customized by the partner, and placed conveniently inside or in the vicinity of the content brings the power of the WWF experience right inside your app. Integration of the DabKick's Media Call SDK within your app is a snap.

To experience the awesome power of the WWF experience, please try our DabKick app, a free download from either the Android play store or the iOS app store.

The sections below describe the steps needed for integration of the Dabkick Media Call SDK into your application.

Our target audience for the below is developers who configure the code within their apps.

Prerequisites

  • The SDK requires a minimum Android API level of 17.
  • All major standard video formats are supported. For a full list, visit here.

Install SDK

Step 1: In your project-level build.gradle,
  • Add both maven blocks into the repositories block
  • Add the project.ext block and replace the key and id with your own.
                                
allprojects {
    project.ext {
        dabKickDeveloperId="your_dabkick_developer_id"
        dabKickDeveloperKey="your_dabkick_developer_key"
    }
    repositories {
       maven {
           url "https://jitpack.io/"
       }
       maven {
           url "http://dabkick.bitnamiapp.com/artifactory/android-dev-videosdk-local/"
       }
   }
}

                                
                            
Step 2: In your app-level build.gradle, add the following compile dependency
                                
dependencies {
  compile ('com.dabkick.videosdk:videosdk:1.0.1') { transitive = true}
}

                                
                            
In AndroidManifest.xml, Add the following permissions
                                
< uses-permission android:name="android.permission.RECORD_AUDIO"/>
< uses-permission android:name="android.permission.CAMERA"/>
< uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
                                
                            
If the Application class is not already extended, then include the “android:name” attribute for a custom Application class in AndroidManifest.xml.
                                
< manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.package.yourapp">
    < application
        android:name=".MyApplication" 
    < /application>
< /manifest>
                                
                            
Extend the SdkApp class from the class you created or already have in step 4. Then call DabKick.setVideoProvider().
                                
public class MyApplication extends SdkApp {
    @Override
    public void onCreate() {
        super.onCreate();
        DabKick.setVideoProvider(/* your video provider instance */);
    }
}
                                
                            
Watch with Friends You can call DabKick.watchWithFriends(context); at any point to start watching videos.

Configuration

Step 1: In AndroidManifest.xml, Add the following permissions. If the Application class is not already extended, then include the “android:name” attribute for a custom Application class in AndroidManifest.xml.
                                
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
                                
                            
                                
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.package.yourapp">
    <application
        android:name=".MyApplication" 
    </application>
</manifest>
                                
                            


Step 2: Have your new or existing Application class extend SdkApp.
                                
public class MyApplication extends SdkApp {
    @Override
    public void onCreate() {
        super.onCreate();
        DabKick.setVideoProvider(/* your video provider instance */);
    }
}
                                
                            


Step 3: Add Proguard rules to proguard-rules.pro. This prevents DabKick from being removed by ProGuard.
                                
-dontwarn com.squareup.okhttp.**
-dontwarn com.google.errorprone.annotations.*
-dontwarn retrofit2.Platform$Java8
-dontwarn okio.**
-keepattributes *Annotation*
-keepclassmembers class ** {
   @org.greenrobot.eventbus.Subscribe ;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keepattributes Signature
-keepclassmembers class com.dabkick.videosdk.livesession.models.** { *; }
-keep public class com.dabkick.videosdk.livesession.models.** { *; }
-keep class org.webrtc.** { *; }
-keep class com.twilio.video.** { *; }
-keepattributes InnerClasses
                                
                            
  1. provideCategories returns categories of videos which can be scrolled by the user
  2. provideVideos returns videos which are to be added to the specified category, from given video offset
  3. startDabKickWithVideos supplies optional video(s) to start a session with.
                                
private DabKickVideoProvider createDabKickVideoProvider() {

       DabKickVideoProvider dabKickVideoProvider = new DabKickVideoProvider() {
           @Override
           public ArrayList< DabKickVideoInfo> provideVideos(String category, int offset) {
               return new ArrayList< >(/* your list of DabKickVideoInfo items */);
           }

           @Override
           public ArrayList< String> provideCategories(int offset) {
               return new ArrayList< >(/* your list of category Strings */);
           }

           @Override
           public ArrayList< DabKickVideoInfo> startDabKickWithVideos() {
               return new ArrayList< >(/* your list of optional videos */);
           }
       };

       return dabKickVideoProvider;
}
                                
                            

Getting Started

To get started, please install and configure the SDK by following the steps below. You will need two pieces of information to identify your project uniquely (developer ID and developer Key), both of which are generated and displayed for your use when you click the section titled "Developer Keys" below.

Create the Button

DabKick supplies a View called DabKickVideoButton. This button allows the developer to use DabKick’s UI. No functionality is supplied; an onClickListener must be set to call DabKick.watchWithFriends(). See example below:
                            
// button which, upon click, starts DabKick session
DabKickVideoButton button = findViewById(R.id.dabkick_video_button);
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // Optionally add any videos which are to be shown to the user
        // inside DabKickVideoProvider.startDabKickWithVideos()
        DabKick.watchWithFriends(MainActivity.this);

        }
});
                            
                        

Starting a Live Media Session

Once the SDK is installed and configured, we are now ready to start what we call a Live Session. Live Sessions can be started with or without initializing media. If a set of videos or photos are initialized at the start, the media will be immediately staged and made ready to be watched together, upon entering the Live Session. Alternatively, we can start a session with no media, letting users rely on acquiring and selecting media from a media "shelf" from inside the live session. These methods of starting a live session are described in detail in the section below.
                            
DabKick.watchWithFriends(context);
                            
                        

Add Videos to Live Media Session

You can start the session with videos of your choice. See code below for implementation. This method is optional — if this method returns an empty ArrayList, then the live session will start without any videos. Videos can instead be added by the user by manually browsing for videos once in the session.

                            
private DabKickVideoProvider createDabKickVideoProvider() {

       return new DabKickVideoProvider() {

           ...other implemented methods

           @Override
           public ArrayList<DabKickVideoInfo> startDabKickWithVideos() {
               ArrayList<DabKickVideoInfo> list = new ArrayList<>();
               if (userSelectedVideoInfo != null) {
                   list.add(userSelectedVideoInfo);
               }
               return list;
           }
       };

}
                            
                        


Create Custom Categories in Live Session

When users browse for media to browse, they can do so by opening the media drawing shown in the screenshot above. They can browse media organized by categories, as shown in item 1 in the screenshot. Clicking on a category shows photos of that category in item 2. The following method provides the media drawer with the category names.
Category names are loaded asynchronously and can be paginated. When the user has scrolled past all the category names that have been set, the live session will request more category names from the delegate with offset equal to the number of category names already loaded. Sending back an empty ArrayList signifies that there are no more categories to load.

                            
private DabKickVideoProvider createDabKickVideoProvider() {

       return new DabKickVideoProvider() {
           
           ...other implemented methods

           @Override
           public ArrayList provideCategories(int offset) {
               if (offset == videoCategories.size()) {
                   // cannot provide any more video categories
                   return new ArrayList<>();
               }
               int endIndex = Math.min(videoCategories.size(), offset + 5);
               ArrayList categoryList = new ArrayList<>(videoCategories.subList(offset, endIndex)); 
               return categoryList;
           }
                            
                        


This method provides the images to show in item 2 of the screenshot. When the user opens a category in the media shelf, the live session will request content asynchronously and with an offset for pagination for a content type, similar to how category names are loaded. Sending back an empty ArrayList signifies that there is no more content to load for the specified category.

                            
private DabKickVideoProvider createDabKickVideoProvider() {
       return new DabKickVideoProvider() {
           @Override
           public ArrayList provideVideos(String category, int offset) {
               int totalSize = videoHolder.get(category).size();
               int endIndex = Math.min(totalSize, offset + 3);
               ArrayList list = new ArrayList<>(videoHolder.get(category).subList(offset, endIndex));
                return list;
           }

           ...other implemented methods

       };
}
                            
                        
This method provides the images to show in item 2 of the screenshot. When the user opens a category in the media shelf, the live session will request content asynchronously and with an offset for pagination for a content type, similar to how category names are loaded. Sending back an empty ArrayList signifies that there is no more content to load for the specified category.




Full Code Snippet

Step 1: Setup the DabKickVideoProvider in your Application class

                                
import com.dabkick.videosdk.publicsettings.DabKick;
import com.dabkick.videosdk.publicsettings.DabKickVideoButton;
import com.dabkick.videosdk.publicsettings.DabKickVideoInfo;
import com.dabkick.videosdk.publicsettings.DabKickVideoProvider;

public class PartnerApplication extends SdkApp {
    @Override
    public void onCreate() {
        super.onCreate();
        DabKickVideoProvider dabkickVideoProvider = createDabKickVideoProvider();
        DabKick.setVideoProvider(dabkickVideoProvider);
    }

    private DabKickVideoProvider createDabKickVideoProvider() {

        DabKickVideoProvider dabKickVideoProvider = new DabKickVideoProvider() {
            @Override
            public ArrayList<DabKickVideoInfo> provideVideos(String category, int offset) {
                return new ArrayList<>(/* your list of DabKickVideoInfo items */);
            }

            @Override
            public ArrayList<String> provideCategories(int offset) {
                return new ArrayList<>(/* your list of category Strings */);
            }

            @Override
            public ArrayList<DabKickVideoInfo> startDabKickWithVideos() {
                return new ArrayList<>(/* your list of optional videos */);
            }
        };
        return dabKickVideoProvider;
    }
}

                                
                            

Where createDabKickVideoProvider() returns an implementation of the DabKickVideoProvider interface, shown below:
  1. provideCategories returns categories of videos which can be scrolled by the user
  2. provideVideos return videos which are to be added to the specified category, from given video offset
  3. startDabKickWithVideos supplies optional video(s) to start a session with.

Sample Android App


https://github.com/DabKick/SampleAppsForAndroid

Live Media Session with Videos

You can start the session with videos of your choice. See code below for implementation. This method is optional — if this method returns an empty ArrayList, then the live session will start without any videos. Videos can instead be added by the user by manually browsing for videos once in the session.

                            
private DabKickVideoProvider createDabKickVideoProvider() {

       return new DabKickVideoProvider() {

           ...other implemented methods

           @Override
           public ArrayList<DabKickVideoInfo> startDabKickWithVideos() {
               ArrayList<DabKickVideoInfo> list = new ArrayList<>();
               if (userSelectedVideoInfo != null) {
                   list.add(userSelectedVideoInfo);
               }
               return list;
           }
       };

}
                            
                        


Provide Custom Content





aWhen users browse for media to browse, they can do so by opening the media drawing shown in the screenshot above. They can browse media organized by categories, as shown in item 1 in the screenshot. Clicking on a category shows photos of that category in item 1. The following method provides the media drawer with the category names. Category names are loaded asynchronously and can be paginated. When the user has scrolled past all the category names that have been set, the live session will request more category names from the delegate with offset equal to the number of category names already loaded. Sending back an empty ArrayList signifies that there are no more categories to load.
                                
private DabKickVideoProvider createDabKickVideoProvider() {

        return new DabKickVideoProvider() {
           
            ...other implemented methods

            @Override
            public ArrayList<String> provideCategories(int offset) {
                if (offset == videoCategories.size()) {
                    // cannot provide any more video categories
                    return new ArrayList<>();
                }
                int endIndex = Math.min(videoCategories.size(), offset + 5);
               ArrayList<String> categoryList = new ArrayList<>(videoCategories.subList(offset, endIndex)); 
               return categoryList;
            }
}

                                
                            


This method provides the images to show in item 2 of the screenshot. When the user opens a category in the media shelf, the live session will request content asynchronously and with an offset for pagination for a content type, similar to how category names are loaded. Sending back an empty ArrayList signifies that there is no more content to load for the specified category.
                                
private DabKickVideoProvider createDabKickVideoProvider() {
       return new DabKickVideoProvider() {
           @Override
           public ArrayList<DabKickVideoInfo> provideVideos(String category, int offset) {
               int totalSize = videoHolder.get(category).size();
               int endIndex = Math.min(totalSize, offset + 3);
               ArrayList<DabKickVideoInfo> list = new ArrayList<>(videoHolder.get(category).subList(offset, endIndex));
               return list;
           }

           ...other implemented methods

       };
}

                                
                            


Install SDK

Step 1: In your project-level build.gradle,
  • Add both maven blocks into the repositories block
  • Add the project.ext block and replace the key and id with your own.
                                
allprojects {
    project.ext {
        dabKickDeveloperId="your_dabkick_developer_id"
        dabKickDeveloperKey="your_dabkick_developer_key"
    }
    repositories {
       maven {
           url "https://jitpack.io/"
       }
       maven {
           url "http://dabkick.bitnamiapp.com/artifactory/android-dev-videosdk-local/"
       }
   }
}

                                
                            
Step 2: In your app-level build.gradle, add the following compile dependency
                                
dependencies {
  compile ('com.dabkick.videosdk:videosdk:1.0.1') { transitive = true}
}

                                
                            
In AndroidManifest.xml, Add the following permissions
                                
< uses-permission android:name="android.permission.RECORD_AUDIO"/>
< uses-permission android:name="android.permission.CAMERA"/>
< uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
                                
                            
If the Application class is not already extended, then include the “android:name” attribute for a custom Application class in AndroidManifest.xml.
                                
< manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.package.yourapp">
    < application
        android:name=".MyApplication" 
    < /application>
< /manifest>
                                
                            
Extend the SdkApp class from the class you created or already have in step 4. Then call DabKick.setVideoProvider().
                                
public class MyApplication extends SdkApp {
    @Override
    public void onCreate() {
        super.onCreate();
        DabKick.setVideoProvider(/* your video provider instance */);
    }
}
                                
                            
Watch with Friends You can call DabKick.watchWithFriends(context); at any point to start watching videos.

Configuration

Step 1: In AndroidManifest.xml, Add the following permissions. If the Application class is not already extended, then include the “android:name” attribute for a custom Application class in AndroidManifest.xml.
                                
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
                                
                            
                                
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.package.yourapp">
    <application
        android:name=".MyApplication" 
    </application>
</manifest>
                                
                            


Step 2: Have your new or existing Application class extend SdkApp.
                                
public class MyApplication extends SdkApp {
    @Override
    public void onCreate() {
        super.onCreate();
        DabKick.setVideoProvider(/* your video provider instance */);
    }
}
                                
                            


Step 3: Add Proguard rules to proguard-rules.pro. This prevents DabKick from being removed by ProGuard.
                                
-dontwarn com.squareup.okhttp.**
-dontwarn com.google.errorprone.annotations.*
-dontwarn retrofit2.Platform$Java8
-dontwarn okio.**
-keepattributes *Annotation*
-keepclassmembers class ** {
   @org.greenrobot.eventbus.Subscribe ;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keepattributes Signature
-keepclassmembers class com.dabkick.videosdk.livesession.models.** { *; }
-keep public class com.dabkick.videosdk.livesession.models.** { *; }
-keep class org.webrtc.** { *; }
-keep class com.twilio.video.** { *; }
-keepattributes InnerClasses
                                
                            
  1. provideCategories returns categories of videos which can be scrolled by the user
  2. provideVideos returns videos which are to be added to the specified category, from given video offset
  3. startDabKickWithVideos supplies optional video(s) to start a session with.
                                
private DabKickVideoProvider createDabKickVideoProvider() {

       DabKickVideoProvider dabKickVideoProvider = new DabKickVideoProvider() {
           @Override
           public ArrayList< DabKickVideoInfo> provideVideos(String category, int offset) {
               return new ArrayList< >(/* your list of DabKickVideoInfo items */);
           }

           @Override
           public ArrayList< String> provideCategories(int offset) {
               return new ArrayList< >(/* your list of category Strings */);
           }

           @Override
           public ArrayList< DabKickVideoInfo> startDabKickWithVideos() {
               return new ArrayList< >(/* your list of optional videos */);
           }
       };

       return dabKickVideoProvider;
}
                                
                            

Full Code Snippet

Step 1: Setup the DabKickVideoProvider in your Application class

                                
import com.dabkick.videosdk.publicsettings.DabKick;
import com.dabkick.videosdk.publicsettings.DabKickVideoButton;
import com.dabkick.videosdk.publicsettings.DabKickVideoInfo;
import com.dabkick.videosdk.publicsettings.DabKickVideoProvider;

public class PartnerApplication extends SdkApp {
    @Override
    public void onCreate() {
        super.onCreate();
        DabKickVideoProvider dabkickVideoProvider = createDabKickVideoProvider();
        DabKick.setVideoProvider(dabkickVideoProvider);
    }

    private DabKickVideoProvider createDabKickVideoProvider() {

        DabKickVideoProvider dabKickVideoProvider = new DabKickVideoProvider() {
            @Override
            public ArrayList<DabKickVideoInfo> provideVideos(String category, int offset) {
                return new ArrayList<>(/* your list of DabKickVideoInfo items */);
            }

            @Override
            public ArrayList<String> provideCategories(int offset) {
                return new ArrayList<>(/* your list of category Strings */);
            }

            @Override
            public ArrayList<DabKickVideoInfo> startDabKickWithVideos() {
                return new ArrayList<>(/* your list of optional videos */);
            }
        };
        return dabKickVideoProvider;
    }
}

                                
                            

Where createDabKickVideoProvider() returns an implementation of the DabKickVideoProvider interface, shown below:
  1. provideCategories returns categories of videos which can be scrolled by the user
  2. provideVideos return videos which are to be added to the specified category, from given video offset
  3. startDabKickWithVideos supplies optional video(s) to start a session with.

In your project-level build.gradle

Step 1.1 In your project-level build.gradle, Place the line starting with “url” into a maven block Add jcenter() to the repositories block

allprojects {
    project.ext {
        dabKickDeveloperId="your_dabkick_developer_id"
        dabKickDeveloperKey="your_dabkick_developer_key"
    }
   repositories {
       jcenter()
 
       maven {
           url "http://dabkick.bitnamiapp.com/artifactory/android-dev-videosdk-local/"
       }
   }
}
Step 1.2 In your app-level build.gradle, add the following compile dependency

dependencies {
  compile ('com.dabkick.videosdk:videosdk:1.0.1') { transitive = true}
}

Install Dabkick Android Video SDK

To install the latest Android SDK library add the following configuration steps:

2.1 Update your project-level build.gradle file with a path to the library:

allprojects {
repositories {
jcenter()

maven {
    url "http://dabkick.bitnamiapp.com/artifactory/android-dev-videosdk-local/"
      }
   }
}

                            

2.2 Specify SDK dependency on your app’s build.gradle file:

dependencies {
  // The Android Dabkick Video SDK resides here
  compile ('com.dabkick.videosdk:videosdk:1.0.1') { transitive = true}
}

                            

2.3 Verify you meet the required Android Minimum SDK Version:

The minimum supported Android SDK version is API Level: 17. Android 4.2 ( JELLY_BEAN_MR1 ).
Ensure your app is 17 or greater
                            

Edit AndroidManifest.xml file

3.1 Enable Microphone & Camera Permissions

The SDK comes with a Live Streaming feature which, if activated, requires access to the microphone and the camera. In order to target Android API level 23 or later, the SDK requests runtime permissions for microphone & camera access, along with a rationale at the time of request so users can decide to activate the access.

In addition, the SDK requires access to device’s storage for photos taken from the onboard camera.

Please add the following permissions to your AndroidManifest.xml file to enable this:

                                
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
                                
                            

4. Extend Application Class & set up a video provider

The partner app is required to set the DabKickVideoProvide in the Application class. This is how the SDK will acquire the videos and categories to be watched together.

Step 4a. Create an Application class extending SdkApp

public class MyApplication extends SdkApp {
    @Override
    public void onCreate() {
        super.onCreate();
        DabKick.setVideoProvider(/* your video provider */);
    }
}

                            

Step 4b. Edit your app’s build.gradle


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.package.yourapp">
<application
android:name=".MyApplication" <-- add this line to reference your MyApplication class
 ...
</application>
</manifest>


                            

4.1 Setting up a DabKickVideoProvider


This is accomplished as follows:
    - Create a videoprovider instance
    - Pass the video provider to SDK
            - By invoking the setVideoProvider interface and passing your videoprovider as its parameter.
            - Note: Null value not allowed in the parameter, as a video provider is an essential part of supplying the videos to watch together.

See example code below for how this is acomplished.

Usage Example:
...
import com.dabkick.videosdk.publicsettings.DabKick;
import com.dabkick.videosdk.publicsettings.DabKickVideoButton;
import com.dabkick.videosdk.publicsettings.DabKickVideoInfo;
import com.dabkick.videosdk.publicsettings.DabKickVideoProvider;
...
public class PartnerApplication extends SdkApp {
    @Override
    public void onCreate() {
        super.onCreate();

// Create a videoprovider instance
DabKickVideoProvider dabkickVideoProvider =  new createDabKickVideoProvider();

//  Pass the video provider to SDK
        DabKick.setVideoProvider(dabkickVideoProvider);
    }
}

Where:
createDabKickVideoProvider() is a simple set-up (see example code below) that which the three override methods that the video provider requires:

1) provideCategories  returns categories of videos which can be scrolled by the user
2) provideVideos  return videos which are to be added to the specified category, from given video offset
3) startDabKickWithVideos  supplies optional video(s) to start a session with.

private DabKickVideoProvider CreateDabKickVideoProvider() {

       DabKickVideoProvider dabKickVideoProvider = new DabKickVideoProvider() {
           @Override
           public ArrayList<DabKickVideoInfo> provideVideos(String category, int offset) {
               // return videos which are to be added to the specified category, from given video offset
               return new ArrayList<>(videosHolder.get(category).subList(offset, offset + 3));
           }

           @Override
           public ArrayList<String> provideCategories(int offset) {
               // return categories which can be scrolled by the user
               return new ArrayList<>(categories.subList(offset, offset+3));
           }

           @Override
           public ArrayList<DabKickVideoInfo> startDabKickWithVideos() {
    // supply optional videos to start a session with
               ArrayList<DabKickVideoInfo> smallerList = new ArrayList<>();
               smallerList.add(userSelectedVideo);
               return smallerList;
           }
       };

       return dabKickVideoProvider;


                            

5 Watch With Friends

This involves two API calls:

        - Register
        - WatchWithFriends
                            

5.1 Register

This optional API call authenticates the partner application to DabKick servers via the Developer id and Developer key (obtained in step-1). Additionally, it includes a callback function to handle the completion status of the register process. It should be used to test whether the developer ID and key are setup correctly. This call does not create a user or enter a live session.

Interface details:

register(<context>, <callback>);

Where:
<callback> is a required callback function defined by the partner app developer; it gets called when the register call completes..

Usage Example:
...
import com.dabkick.videosdk.publicsettings.DabKick;
...

//set up callback
DabKick.OnRegisterCallback onRegisterCallback = new DabKick.OnRegisterCallback() {
   @Override
   public void onFinishRegister(boolean success, String errorMsg) {
       if (success) {
           Log.d("TAG", "registered with DabKick");
       } else {
           Log.w("TAG", "failed to register with DabKick: " + errorMsg);
       }
   }
};

//register
DabKick.register(context, onRegisterCallback);


                            

5.2 WatchWithFriends

5.2.1 Setting up a WWF button

This clickable button, placed in or near the video screen, is the key entry point to the SDK’s main  functionality to watch videos with friends.
Application developers can use either a standard DabKick button provided with the SDK (available via the interface DabKickVideoButton - see example code below) or customize their own version to suit their application needs.
The button itself provides no functionality, so an OnClickListener should be used to call DabKick.watchWithFriends().
                            

5.2.2 Inside the OnClick() for the WWF button

When user clicks on the WWF button, two actions are required in the OnClick() method:
    1) Set up the video(s) to watch with friends NOW
    2) Call WatchWIthFriends API

Interface details:

watchWithFriends(<context>);

Where:

<context> is the context of the partner application activity from where this API is called.

Usage Example:

...
import com.dabkick.videosdk.publicsettings.DabKick;
import com.dabkick.videosdk.publicsettings.DabKickVideoButton;
import com.dabkick.videosdk.publicsettings.DabKickVideoInfo;
import com.dabkick.videosdk.publicsettings.DabKickVideoProvider;


...


 // WWF button which, upon clicked, starts DabKick session
DabKickVideoButton button = findViewById(R.id.dabkick_video_button);
button.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {

// Setting up the video(s) to watch with friends
// make sure your DabKickVideoProvider.startDabKickWithVideos()
// adds any videos which are to be shown to the user

//Call WatchWIthFriends API
DabKick.watchWithFriends(MainActivity.this);
   }
});


                            

6.0 APPLICATION NOTES

  • Supported Video Formats: The Video SDK uses Exomedia which supports a wide range of video formats supported by Exoplayer. For a full list, visit here.
  • The SDK supports a Live Streaming feature. User permissions for camera and microphone will be requested, if needed, when this feature is used.
  • The SDK requires a minimum Android API level of 17.
  • The SDK is currently in Beta. We appreciate all comments from developers working with the SDK.

APPENDIX

Public classes and interfaces are listed below for use by the Application Developer.

DabKickVideoInfo:


public class DabKickVideoInfo {

   private String videoUrl;
   private String thumbnailUrl;
   private String authorName;
   private String duration;
   private String title;

   public DabKickVideoInfo(String author, String title, String duration, String thumbnailUrl, String Url) {
       this.videoUrl = Url;
       this.authorName = author;
       this.title = title;
       this.duration = duration;
       this.thumbnailUrl = thumbnailUrl;
   }

   public String getVideoUrl() {
       return videoUrl;
   }

   public String getAuthorName() {
       return authorName;
   }

   public String getThumbnailUrl() {
       return thumbnailUrl;
   }

   public String getDuration() {
       return duration;
   }

   public String getTitle() {
       return title;
   }

}
-----------

DabKickVideoProvider:

public interface DabKickVideoProvider {
 
   /**
    * Called by the SDK when it needs more videos
    * @param offset the last index which was loaded
    * @param category the category to load from
    * @return list of new videos
    */
   ArrayList<DabKickVideoInfo> provideVideos(String category, int offset);
 
   /**
    * Called when more categories are needed
    * @param offset the last loaded index
    * @return list of new categories
    */
   ArrayList<String> provideCategories(int offset);

   /**
    * Starts a DabKick session with videos
    * @return a list of videos for the session
    */
   ArrayList<DabKickVideoInfo> startDabKickWithVideos();
}

-----------------------


                            

iOS Platform Overview

Looking for your app users to watch their favorite videos or view their photos with friends and family, live with chat? Look no further!

DabKick's Media Call SDK enables your users to watch their favorite media (videos and photos) together with their friends and family, live with chat capabilities, either via text or live streaming. A WatchWithFriends (WWF) button, designed by DabKick or customized by the partner, and placed conveniently inside or in the vicinity of the content brings the power of the WWF experience right inside your app. Integration of the DabKick's Media Call SDK within your app is a snap.

To experience the awesome power of the WWF experience, please try our DabKick app, a free download from either the Android play store or the iOS app store.

The sections below describe the steps needed for integration of the Dabkick Media Call SDK into your application.

Our target audience for the below is developers who configure the code within their apps.

See our tutorial video for more details

Prerequisites

  • Xcode 8.1+
  • Swift projects must use Swift 3.0 or higher
  • CocoaPods 1.0.0+
  • Support for iOS 8.1+

Install SDK

  • Install Cocoapods on your machine
  • Run pod init
  • Add the line pod 'DabKickLiveSessionSdk' to your Podfile
  • Add the line use_frameworks! to your Podfile
  • Run pod install
  • Open your newly created *.xcworkspace project #IMPORTANT
  • If you don't want to use Cocoapods, you can download the framework directly here
    1. Download and unzip the DabKickLiveSessionSdk.framework file
    2. Drag the framework file into your XCode project navigator to add it to your project
    3. In your app target file, click on the "General" tab, and add DabKickLiveSessionSdk.framework into the "Embedded Binaries" and "Linked Frameworks and Libraries" section


  • Configuration

    Info.plist





    • Set up your project's Info.plist
      • Add your developer key and developer ID properties into your app’s Info.plist file. To get to the Info.plist page, search for the file with this format: YourProjectNameHere-Info.plist
      • Add permissions for photo library usage (to browse photos to stage), camera usage (to set up profile and live stream), and microphone usage (to live stream)
      • Add the following URL scheme to handle live session invitations
        • URL identifier: "com.dabkick.livesessionsdk"
        • URL Schemes: [" yourDeveloperId"]
                                
    /*
    Place the "Watch Together" button and set up the SDK delegate
    When the user clicks on the "Watch Together" button, it will call on the delegate method startDabKickLiveSessionWithContent:
    defined below to get images to start a live session with, and then the app open the Live Session UI
    */
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        DabKickWatchTogetherButton *dabKickWatchTogetherButton = [[DabKickLiveSessionSdk defaultInstance] getWatchTogetherButton];
        [dabKickWatchTogetherButton sizeToFit];
        [self.view addSubview:dabKickWatchTogetherButton];
        dabKickWatchTogetherButton.center = self.view.center;
    
        [DabKickLiveSessionSdk defaultInstance].delegate = self;
    }
    
    // Return images to start a live session with
    
    
    - (NSArray<id<DabKickContent>> *)startDabKickLiveSessionWithContent:(DabKickLiveSessionSdk *)liveSessionInstance {
        NSArray <UIImage *> *imagesToStart = @[
            /**
                * Replace images with images you would like to show when the live session starts
                */
            [UIImage imageNamed:@"smiley"],
            [UIImage imageNamed:@"angry"],
            [UIImage imageNamed:@"cool"]
        ];
    
        NSMutableArray<id <DabKickContent> > *contentArray = [[NSMutableArray alloc] initWithCapacity:imagesToStart.count];
        [imagesToStart enumerateObjectsUsingBlock:^(UIImage * _Nonnull image, NSUInteger idx, BOOL * _Nonnull stop) {
            imageContent.image = image;
    
            [contentArray addObject:imageContent];
        }];
    
        return contentArray;
    }
    
    // Get category names for images
    
    -(void)categoryNamesForDabKickLiveSession:(DabKickLiveSessionSdk *)liveSessionInstance offset:(NSUInteger)offset contentType:(DabKickContentType)contentType loader:(id<DabKickStringLoading>)loader {
        static NSArray *categories;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            categories = @[
                        @"Ahjumawi Lava Springs State Park",
                        @"Andrew Molera State Park",
                        @"Angel Island State Park",
                        @"Annadel State Park",
                        @"Ano Nuevo Island State Park",
                        @"Anza-Borrego Desert State Park",
                        @"Arthur B. Ripley Desert Woodland State Park",
                        @"Baker Beach State Park",
                        @"Beach State Park",
                        @"Bidwell-Sacramento River State Park",
                        @"Big Basin Redwoods State Park",
                        @"Bolsa Chica Beach State Park",
                        @"Border Field State Park"
                        ];
        });
    
        NSInteger nextLoadAmount = 5;
        NSInteger remainingCount = categories.count - offset;
        if (remainingCount < nextLoadAmount) {
            nextLoadAmount = remainingCount;
        }
    
        [loader send:[categories subarrayWithRange:NSMakeRange(offset, nextLoadAmount)]];
    }
    
    // Get content for a category
    
    
    - (void)dabKickLiveSession:(DabKickLiveSessionSdk *)liveSessionInstance contentForCategory:(NSString *)title offset:(NSUInteger)offset contentType:(DabKickContentType)contentType loader:
    (id<DabKickContentLoading>)loader {
        /**
         * Replace this line to return images from your application or service
         */
        NSArray <UIImage *> *imagesArray = [self getImagesForCategoryWithTitle:title offset:offset];
    
        NSMutableArray <id <DabKickContent>> *contentArray = [[NSMutableArray alloc] initWithCapacity:imagesArray.count];
        [imagesArray enumerateObjectsUsingBlock:^(id _Nonnull content, NSUInteger idx, BOOL * _Nonnull stop) {
            DabKickImageContent *imageContent = [[DabKickImageContent alloc] init];
            imageContent.image = content;
            [contentArray addObject:imageContent];
        }];
    
        [loader send:contentArray];
    }
                                        
  • Paste the following code into your AppDelegate.m file
                                        
    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { 
        return [[DabKickLiveSessionSdk defaultInstance] application:app openURL:url options:options]; 
    }
                                        
                                    
  • Start a Live Media Session

    ViewController with the Media Call Button

    In the ViewController where you will initiate a live session, include that following code

    #import <DabKickLiveSessionSdk/DabKickLiveSessionSdk.h>

    Once you have including the SDK Framework, create a @property in the private interface of the ViewController.m file like so...

                                
    @interface ViewController () <DabKickLiveSessionSdkDelegate>
    
    @property (nonatomic) DabKickWatchTogetherButton *aWatchButton;
    
    @end
                                
                            


    Then, add the following code to the ViewController's @implementation

                                
    
    - (DabKickWatchTogetherButton*)aWatchTogetherButton {
        if (!_aWatchTogetherButton) {
            _aWatchTogetherButton = [[DabKickLiveSessionSdk defaultInstance] getWatchTogetherButton];
            [_aWatchTogetherButton sizeToFit];
            [self.view addSubview:_aWatchTogetherButton];
            _aWatchTogetherButton.center = self.view.center;
            [DabKickLiveSessionSdk defaultInstance].delegate = self;
        }
        return _aWatchTogetherButton;
    }
                                
                            


    Furthermore, you will likely want to configure the look and feel of the SDK user interface to support the media content items you intend to support. You can configure the live session to support only photos, video, or both photos and videos.

    The following code illustrates how to configure your DabKick Live Session object.

                                
    - (void)configureLiveSession {
        DabKickLiveSessionSdkConfiguration *configuration = [[DabKickLiveSessionSdkConfiguration alloc] init];
        configuration.enableImages = YES;
        /* By default, the live session is configured to enable both photos and videos.
         * If, for example, you only want to support photos, then you need to explicitly disable videos like so
         */
        configuration.enableVideos = NO;
        [[DabKickLiveSessionSdk defaultInstance] configureWithConfiguration:configuration
                                                                completion:nil
                                                                   failure:nil];
    }
                                
                            
    Add the following code to the viewDidLoad function of your view controller.

                                
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        [self configureLiveSession];
        [self.view addSubview:self.aWatchTogetherButton]
    }
                                
                            
    Now that this code has been added, the end user can begin a new live media session by tapping the DabKick Live Media Session button that has been placed onscreen.

    ** If you would like to create your own custom button, you may do so by turning the alpha off on the stock button and sending a sendActionForControlEvent: message to the default button with the UIControlEventTouchUpInsideParameter

    In the following section, we will go over how to provide the desired media types to the live session, which gives the developer the ability to stage certain media content types within the live session for viewing.

    Begin a live session



    Now that you have added your "Watch Together" button as a subview to your view controller, you can start a live session by clicking on the button.

    Alternatively, you could create your own custom button, and in the @selector method of your button, call [[DabKickLiveSessionSdk defaultInstance] startLiveSession]

    Note that calling startLiveSession is the same as clicking on the "Watch Together" button. Both options are provided for your convenience

    Support Session Invitations

    Now that you have created a live session, you are going to want to invite friends to watch together. This is made possible by implementing the following methods in AppDelegate.m. Under the hood, we will be creating a deep link to the live session, but the details are less important so long as you include the following code.

                                
    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { 
        return [[DabKickLiveSessionSdk defaultInstance] application:app openURL:url options:options]; 
    }
                                
                            

    Once you have configured your live session object and enabled the required access points in your view controller, it is important to ensure that you are providing the SDK with the proper media content.

    The next section outlines how to implement the delegate methods that provide media content to the SDK.

    Add Photos to Live Media Session

    Start a live session with image content

    Of course, the live session is meaningless without providing media content that can be viewed together in this live setting. If you have photo support configued for your live session, you can start the session with photos of your choice. Otherwise, you can start a live session with video content instead. This is the same method to implement if you want to start a live session with videos, except you return DabKickImageContent instead of DabKickVideoContent.

    Once implemented, users can start watching the photos immediately upon joining.

                                
    - (NSArray<id<DabKickContent>> *)startDabKickLiveSessionWithContent:(DabKickLiveSessionSdk *)liveSessionInstance {
        NSArray* stageArray = @[];
        UIImage* imageToStage;
        if (self.anImageView.image) {
            imageToStage = self.anImageView.image;
        }
    
        if (imageToStage) {
            stageArray = @[imageToStage];
    
            NSArray <UIImage *> *imagesToStage = stageArray;
            NSMutableArray<id <DabKickContent> > *contentArray = [NSMutableArray alloc] initWithCapacity:imagesToStage.count];
    
            // Convert UIKit objects into DabKickContent 
            // items that can be rendered within the SDK
    
            for (UIImage* image in imagesToStage) {
                DabKickImageContent *imageContent = [[DabKickImageContent alloc] init];
                imageContent.image = image;
                [contentArray addObject:imageContent];
            }
        }
        
        return contentArray;
    }
                                
                            


    This delegate method is optional — if this method return an empty NSArray or nil, or if this method isn't implemented in the delegate, then the live session will start without any photos. Photos can instead be added by the user by manually browsing for photos once in the session.

    Add Videos to Live Media Session

    Start a live session with video content

    If you have video support configued for your live session, you can start the session with videos of your choice. This is the same method to implement if you want to start a live session with photos, except you return DabKickVideoContent instead of DabKickImageContent.

                                
    - (NSArray<id <DabKickContent>> * _Nullable)startDabKickLiveSessionWithContent:(DabKickLiveSessionSdk * _Nonnull)liveSessionInstance {
        UIImage* thumbnailImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.imageURLString]]];
        NSMutableArray<id <DabKickContent> > *contentArray = [[NSMutableArray alloc] initWithCapacity:1];
        DabKickVideoContent *content = [[DabKickVideoContent alloc] initWithAuthor:self.item.author
                                                                             title:self.item.title
                                                                          duration:self.item.duration.integerValue
                                                                         streamUrl:[NSURL URLWithString:self.videoURL]
                                                                    thumbnailImage:thumbnailImage];
        [contentArray addObject:content];
        return contentArray;
    }
                                
                            


    This delegate method is optional — if this method return an empty NSArray or nil, or if this method isn't implemented in the delegate, then the live session will start without any videos. Videos can instead be added by the user by manually browsing for videos once in the session.

    Create Custom Categories in Live Session





    aWhen users browse for media to browse, they can do so by opening the media drawing shown in the screenshot above. They can browse media organized by categories, as shown in item 1 in the screenshot. Clicking on a category shows photos of that category in item 2. The following method provides the media drawer with the category names.
    Category names are loaded asynchronously and can be paginated. When the user has scrolled past all the category names that have been set, the live session will request more category names from the delegate with offset equal to the number of category names already loaded, and contentType equal to the content type the user is looking at. Sending back an empty NSArray or nil signifies that there are no more categories to load.

                                
    - (void)categoryNamesForDabKickLiveSession:(DabKickLiveSessionSdk * _Nonnull)liveSessionInstance offset:(NSUInteger)offset contentType:(DabKickContentType)contentType loader:(id <DabKickStringLoading> _Nonnull)loader {
        if (contentType == DabKickContentTypeImage) {
            static NSArray* imageSample;
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                imageSample = @[
                                @"Mustache Pics",
                                @"Beard Pics"
                                ];
                
            });
            if (offset >= imageSample.count) {
                [loader send:nil];
            }
            [loader send:imageSample];
        }
    }
                                
                            


    This method provides the images to show in item 2 of the screenshot. When the user opens a category in the media shelf, the live session will request content asynchronously and with an offset for pagination for a content type, similar to how category names are loaded. Sending back an empty NSArray or nil signifies that there are no more content to load for the specified category.

                                
    - (void)dabKickLiveSession:(DabKickLiveSessionSdk * _Nonnull)liveSessionInstance contentForCategory:(NSString * _Nonnull)title offset:(NSUInteger)offset contentType:(DabKickContentType)contentType loader:(id <DabKickContentLoading> _Nonnull)loader {
        NSArray<UIImage*>* images = [[ImageStore sharedStore] getImages].copy;
        if ([title isEqualToString:@"Mustache Pics"]) {
            if (images.count) {
                NSMutableArray<id <DabKickContent> > *contentArray = [[NSMutableArray alloc] initWithCapacity:images.count];
                for (UIImage* image in images) {
                    DabKickImageContent *imageContent = [[DabKickImageContent alloc] init];
                    imageContent.image = image;
                    [contentArray addObject:imageContent];
                }
                [loader send:contentArray];
            }
        }
    }
                                
                            
    For videos, the same delegate methods are called, but you contentType will be DabKickContentTypeVideo, and you will send back an NSArray of DabKickVideoContent. The resulting media shelf will look like the screenshot below:




    The code snippet below uses generic typecasting to convert a non-mutable array of strings into content that the SDK understands.

                                
    - (void)categoryNamesForDabKickLiveSession:(DabKickLiveSessionSdk * _Nonnull)liveSessionInstance offset:(NSUInteger)offset contentType:(DabKickContentType)contentType loader:(id <DabKickStringLoading> _Nonnull)loader {
        NSArray<DabKickContent>* sample = (NSArray<DabKickContent>*)@[@"Mustache Pics"];
        [loader send:sample];
    }
                                
                            

    Full Code Snippet

    Here is yet another example of how you can easily load content into the live session.

                                
    - (NSArray< id< DabKickContent>> *)startDabKickLiveSessionWithContent:(DabKickLiveSessionSdk *)liveSessionInstance {
        NSMutableArray < id < DabKickContent>> *contentArray = [[NSMutableArray alloc] initWithCapacity:imagesArray.count];
        
        DabKickImageContent *imageContent = [[DabKickImageContent alloc] init];
        imageContent.image = [UIImage imageNamed:@"Thumbnail"];
        [contentArray addObject:imageContent];
        
        DabKickImageContent *imageContent = [[DabKickImageContent alloc] init];
        imageContent.image = [UIImage imageNamed:@"Thumbnail_2"];
        [contentArray addObject:imageContent];
        
        DabKickImageContent *imageContent = [[DabKickImageContent alloc] init];
        imageContent.imageUrl = [NSURL URLWithString:@"http://thumbnail.com/Thumbnail_3"];
        [contentArray addObject:imageContent];
    }
                                
                            

    Further, is an additional segment with all of the needed code

    Simply Copy and Paste the code below into your app code
    • Import the DabKickLiveSessionSdk.h header file into your view controller and AppDelegate.m file
      #import <DabKickLiveSessionSdk/DabKickLiveSessionSdk.h>
    • In your view controller, set your view controller to follow the DabKickLiveSessionSdkDelegate protocol and add the aWatchButton property
                                          
      @interface ViewController () <DabKickLiveSessionSdkDelegate>
      
      @property (nonatomic) DabKickWatchTogetherButton *aWatchButton;
      
      @end
                                          
                                      
    • Paste the following code into your view controller
      
      @implementation ViewController
      
      - (void)viewDidLoad {
          [super viewDidLoad];
      
          [self configureLiveSession];
          [self.view addSubview:self.aWatchTogetherButton]
      }
      
      - (void)configureLiveSession {
          DabKickLiveSessionSdkConfiguration *configuration = [[DabKickLiveSessionSdkConfiguration alloc] init];
          configuration.enableImages = YES;
          /* By default, the live session is configured to enable both photos and videos.
           * If, for example, you only want to support photos, then you need to explicitly disable videos like so
           */
          configuration.enableVideos = NO;
          [[DabKickLiveSessionSdk defaultInstance] configureWithConfiguration:configuration
                                                                      completion:nil
                                                                         failure:nil];
      }
      
      - (NSArray<id<DabKickContent>> *)startDabKickLiveSessionWithContent:(DabKickLiveSessionSdk *)liveSessionInstance {
          NSArray* stageArray = @[];
          UIImage* imageToStage;
          if (self.anImageView.image) {
              imageToStage = self.anImageView.image;
          }
      
          if (imageToStage) {
              stageArray = @[imageToStage];
      
              NSArray <UIImage *> *imagesToStage = stageArray;
              NSMutableArray<id <DabKickContent> > *contentArray = [[NSMutableArray alloc] initWithCapacity:imagesToStage.count];
      
              /* Convert UIKit objects into DabKickContent items that can be rendered within the SDK */
              for (UIImage* image in imagesToStage) {
                  DabKickImageContent *imageContent = [[DabKickImageContent alloc] init];
                  imageContent.image = image;
                  [contentArray addObject:imageContent];
              }
          }
          
          return contentArray;
      }
      
      - (void)categoryNamesForDabKickLiveSession:(DabKickLiveSessionSdk * _Nonnull)liveSessionInstance offset:(NSUInteger)offset contentType:(DabKickContentType)contentType loader:(id  _Nonnull)loader {
          if (contentType == DabKickContentTypeImage) {
              static NSArray* imageSample;
              static dispatch_once_t onceToken;
              dispatch_once(&onceToken, ^{
                  imageSample = @[
                                  @"Mustache Pics",
                                  @"Beard Pics"
                                  ];
                  
              });
              if (offset >= imageSample.count) {
                  [loader send:nil];
              }
              [loader send:imageSample];
          }
      }
      
      - (void)dabKickLiveSession:(DabKickLiveSessionSdk * _Nonnull)liveSessionInstance contentForCategory:(NSString * _Nonnull)title offset:(NSUInteger)offset contentType:(DabKickContentType)contentType loader:(id  _Nonnull)loader {
          NSArray* images = [[ImageStore sharedStore] getImages].copy;
          if ([title isEqualToString:@"Mustache Pics"]) {
              if (images.count) {
                  NSMutableArray > *contentArray = [[NSMutableArray alloc] initWithCapacity:images.count];
                  for (UIImage* image in images) {
                      DabKickImageContent *imageContent = [[DabKickImageContent alloc] init];
                      imageContent.image = image;
                      [contentArray addObject:imageContent];
                  }
                  [loader send:contentArray];
              }
          }
      }
      
      - (DabKickWatchTogetherButton*)aWatchTogetherButton {
          if (!_aWatchTogetherButton) {
              _aWatchTogetherButton = [[DabKickLiveSessionSdk defaultInstance] getWatchTogetherButton];
              [_aWatchTogetherButton sizeToFit];
              [self.view addSubview:_aWatchTogetherButton];
              _aWatchTogetherButton.center = self.view.center;
              [DabKickLiveSessionSdk defaultInstance].delegate = self;
          }
          return _aWatchTogetherButton;
      }
      
      @end
                                      
    • Paste the following code into your AppDelegate.m file
                                          
      - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
      {   
          return [[DabKickLiveSessionSdk defaultInstance] application:app openURL:url options:options]; 
      }
                                          
                                      

    Sample iOS App

    FaceMosh

    https://github.com/DabKick/SampleAppsForiOSPhotos

    VideoCookies

    https://github.com/DabKick/SampleAppsForiOSVideos

    Provide Custom Content





    When a users browse for media to browse, they can do so by opening the media drawing shown in the screenshot above. They can browse media organized by categories, as shown in item 1 in the screenshot. Clicking on a category shows photos of that category in item 2. The following method provides the media drawer with the category names.
    Category names are loaded asynchronously and can be paginated. When the user has scrolled past all the category names that have been set, the live session will request more category names from the delegate with offset equal to the number of category names already loaded, and contentType equal to the content type the user is looking at. Sending back an empty NSArray or nil signifies that there are no more categories to load.

                                
    - (void)categoryNamesForDabKickLiveSession:(DabKickLiveSessionSdk * _Nonnull)liveSessionInstance offset:(NSUInteger)offset contentType:(DabKickContentType)contentType loader:(id <DabKickStringLoading> _Nonnull)loader {
        if (contentType == DabKickContentTypeImage) {
            static NSArray* imageSample;
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                imageSample = @[
                                @"Mustache Pics",
                                @"Beard Pics"
                                ];
                
            });
            if (offset >= imageSample.count) {
                [loader send:nil];
            }
            [loader send:imageSample];
        }
    }
                                
                            


    This method provides the images to show in item 2 of the screenshot. When the user opens a category in the media shelf, the live session will request content asynchronously and with an offset for pagination for a content type, similar to how category names are loaded. Sending back an empty NSArray or nil signifies that there are no more content to load for the specified category.

                                
    - (void)dabKickLiveSession:(DabKickLiveSessionSdk * _Nonnull)liveSessionInstance contentForCategory:(NSString * _Nonnull)title offset:(NSUInteger)offset contentType:(DabKickContentType)contentType loader:(id <DabKickContentLoading> _Nonnull)loader {
        NSArray<UIImage*>* images = [[ImageStore sharedStore] getImages].copy;
        if ([title isEqualToString:@"Mustache Pics"]) {
            if (images.count) {
                NSMutableArray<id <DabKickContent> > *contentArray = [[NSMutableArray alloc] initWithCapacity:images.count];
                for (UIImage* image in images) {
                    DabKickImageContent *imageContent = [[DabKickImageContent alloc] init];
                    imageContent.image = image;
                    [contentArray addObject:imageContent];
                }
                [loader send:contentArray];
            }
        }
    }
                                
                            
    For videos, the same delegate methods are called, but you contentType will be DabKickContentTypeVideo, and you will send back an NSArray of DabKickVideoContent. The resulting media shelf will look like the screenshot below:




    The code snippet below uses generic typecasting to convert a non-mutable array of strings into content that the SDK understands.

                                
    - (void)categoryNamesForDabKickLiveSession:(DabKickLiveSessionSdk * _Nonnull)liveSessionInstance offset:(NSUInteger)offset contentType:(DabKickContentType)contentType loader:(id <DabKickStringLoading> _Nonnull)loader {
        NSArray<DabKickContent>* sample = (NSArray<DabKickContent>*)@[@"Mustache Pics"];
        [loader send:sample];
    }
                                
                            

    Live Media Session with Videos

    Start a live session with video content



    If you have video support configued for your live session, you can start the session with videos of your choice. This is the same method to implement if you want to start a live session with photos, except you return DabKickVideoContent instead of DabKickImageContent.

                                
    - (NSArray<id <DabKickContent>> * _Nullable)startDabKickLiveSessionWithContent:(DabKickLiveSessionSdk * _Nonnull)liveSessionInstance {
        UIImage* thumbnailImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.imageURLString]]];
        NSMutableArray<id <DabKickContent> > *contentArray = [[NSMutableArray alloc] initWithCapacity:1];
        DabKickVideoContent *content = [[DabKickVideoContent alloc] initWithAuthor:self.item.author
                                                                             title:self.item.title
                                                                          duration:self.item.duration.integerValue
                                                                         streamUrl:[NSURL URLWithString:self.videoURL]
                                                                    thumbnailImage:thumbnailImage];
        [contentArray addObject:content];
        return contentArray;
    }
                                
                            


    This delegate method is optional — if this method return an empty NSArray or nil, or if this method isn't implemented in the delegate, then the live session will start without any videos. Videos can instead be added by the user by manually browsing for videos once in the session.

    Full Code Snippet

    Here is yet another example of how you can easily load content into the live session.

                                
    - (NSArray< id< DabKickContent>> *)startDabKickLiveSessionWithContent:(DabKickLiveSessionSdk *)liveSessionInstance {
        NSMutableArray < id < DabKickContent>> *contentArray = [[NSMutableArray alloc] initWithCapacity:imagesArray.count];
        
        DabKickImageContent *imageContent = [[DabKickImageContent alloc] init];
        imageContent.image = [UIImage imageNamed:@"Thumbnail"];
        [contentArray addObject:imageContent];
        
        DabKickImageContent *imageContent = [[DabKickImageContent alloc] init];
        imageContent.image = [UIImage imageNamed:@"Thumbnail_2"];
        [contentArray addObject:imageContent];
        
        DabKickImageContent *imageContent = [[DabKickImageContent alloc] init];
        imageContent.imageUrl = [NSURL URLWithString:@"http://thumbnail.com/Thumbnail_3"];
        [contentArray addObject:imageContent];
    }
                                
                            

    Further, is an additional segment with all of the needed code

    Simply Copy and Paste the code below into your app code
    • Import the DabKickLiveSessionSdk.h header file into your view controller and AppDelegate.m file
      #import <DabKickLiveSessionSdk/DabKickLiveSessionSdk.h>
    • In your view controller, set your view controller to follow the DabKickLiveSessionSdkDelegate protocol and add the aWatchButton property
                                          
      @interface ViewController () <DabKickLiveSessionSdkDelegate>
      
      @property (nonatomic) DabKickWatchTogetherButton *aWatchButton;
      
      @end
                                          
                                      
    • Paste the following code into your view controller
      
      @implementation ViewController
      
      - (void)viewDidLoad {
          [super viewDidLoad];
      
          [self configureLiveSession];
          [self.view addSubview:self.aWatchTogetherButton]
      }
      
      - (void)configureLiveSession {
          DabKickLiveSessionSdkConfiguration *configuration = [[DabKickLiveSessionSdkConfiguration alloc] init];
          configuration.enableImages = YES;
          /* By default, the live session is configured to enable both photos and videos.
           * If, for example, you only want to support photos, then you need to explicitly disable videos like so
           */
          configuration.enableVideos = NO;
          [[DabKickLiveSessionSdk defaultInstance] configureWithConfiguration:configuration
                                                                      completion:nil
                                                                         failure:nil];
      }
      
      - (NSArray<id<DabKickContent>> *)startDabKickLiveSessionWithContent:(DabKickLiveSessionSdk *)liveSessionInstance {
          NSArray* stageArray = @[];
          UIImage* imageToStage;
          if (self.anImageView.image) {
              imageToStage = self.anImageView.image;
          }
      
          if (imageToStage) {
              stageArray = @[imageToStage];
      
              NSArray <UIImage *> *imagesToStage = stageArray;
              NSMutableArray<id <DabKickContent> > *contentArray = [[NSMutableArray alloc] initWithCapacity:imagesToStage.count];
      
              /* Convert UIKit objects into DabKickContent items that can be rendered within the SDK */
              for (UIImage* image in imagesToStage) {
                  DabKickImageContent *imageContent = [[DabKickImageContent alloc] init];
                  imageContent.image = image;
                  [contentArray addObject:imageContent];
              }
          }
          
          return contentArray;
      }
      
      - (void)categoryNamesForDabKickLiveSession:(DabKickLiveSessionSdk * _Nonnull)liveSessionInstance offset:(NSUInteger)offset contentType:(DabKickContentType)contentType loader:(id  _Nonnull)loader {
          if (contentType == DabKickContentTypeImage) {
              static NSArray* imageSample;
              static dispatch_once_t onceToken;
              dispatch_once(&onceToken, ^{
                  imageSample = @[
                                  @"Mustache Pics",
                                  @"Beard Pics"
                                  ];
                  
              });
              if (offset >= imageSample.count) {
                  [loader send:nil];
              }
              [loader send:imageSample];
          }
      }
      
      - (void)dabKickLiveSession:(DabKickLiveSessionSdk * _Nonnull)liveSessionInstance contentForCategory:(NSString * _Nonnull)title offset:(NSUInteger)offset contentType:(DabKickContentType)contentType loader:(id  _Nonnull)loader {
          NSArray* images = [[ImageStore sharedStore] getImages].copy;
          if ([title isEqualToString:@"Mustache Pics"]) {
              if (images.count) {
                  NSMutableArray > *contentArray = [[NSMutableArray alloc] initWithCapacity:images.count];
                  for (UIImage* image in images) {
                      DabKickImageContent *imageContent = [[DabKickImageContent alloc] init];
                      imageContent.image = image;
                      [contentArray addObject:imageContent];
                  }
                  [loader send:contentArray];
              }
          }
      }
      
      - (DabKickWatchTogetherButton*)aWatchTogetherButton {
          if (!_aWatchTogetherButton) {
              _aWatchTogetherButton = [[DabKickLiveSessionSdk defaultInstance] getWatchTogetherButton];
              [_aWatchTogetherButton sizeToFit];
              [self.view addSubview:_aWatchTogetherButton];
              _aWatchTogetherButton.center = self.view.center;
              [DabKickLiveSessionSdk defaultInstance].delegate = self;
          }
          return _aWatchTogetherButton;
      }
      
      @end
                                      
    • Paste the following code into your AppDelegate.m file
                                          
      - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
      {   
          return [[DabKickLiveSessionSdk defaultInstance] application:app openURL:url options:options]; 
      }