iOS SDK implementation

Requirements

To get started with the Camment Mobile SDK for iOS you can set up the SDK and build a new project, or you can integrate the SDK in an existing project To use the SDK, install the following on your development machine: - Xcode 7 or later - iOS 8.1 or later - Cocoapods

Important: Use com.camment.sdkdemo bundle id if you are setting up demo app for CammentSDK. In other way login with Facebook account will not work

Add CammentSDK framework to your Xcode project

Open yout Podfile and add pod 'CammentSDK' there

platform :ios, '8.1'

target 'Your target' do
    use_frameworks!
    pod 'CammentSDK'
end

then run pod install

Configure CammentSDK in project's Info.plist

The SDK requires access to Camment server as well as access to Facebook API. Add following code to your Info.plist to prevent any restrictions from iOS:

<key>LSRequiresIPhoneOS</key>
    <true/>
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>cloudfront.net</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSThirdPartyExceptionMinimumTLSVersion</key>
                <string>TLSv1.0</string>
                <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
                <false/>
            </dict>
            <key>amazonaws.com</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSThirdPartyExceptionMinimumTLSVersion</key>
                <string>TLSv1.0</string>
                <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
                <false/>
            </dict>
            <key>amazonaws.com.cn</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSThirdPartyExceptionMinimumTLSVersion</key>
                <string>TLSv1.0</string>
                <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
                <false/>
            </dict>
        </dict>
        <key>NSAllowsArbitraryLoads</key>
        <false/>
    </dict>
    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>fbapi</string>
        <string>fb-messenger-api</string>
        <string>fbauth2</string>
        <string>fbshareextension</string>
    </array>
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>fb1630695620500234</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>camment</string>
            </array>
        </dict>
    </array>
    <key>NSCameraUsageDescription</key>
    <string>Camera is used to create camment chat and have discussions with short videos on your device</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>Microphone is used to create camment chat and have discussions with short videos on your device</string>

Set up the SDK in AppDelegate.m

Open AppDelegate.m and import CammentSDK header:

#import <CammentSDK/CammentSDK.h>

Add following lines to AppDelegate's methods

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[CammentSDK instance] application:application didFinishLaunchingWithOptions:launchOptions];
    ...
    return YES;
}

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

// Make sure you support iOS versions prior to 9.0
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
  sourceApplication:(nullable NSString *)sourceApplication
         annotation:(id)annotation
{
    return [[CammentSDK instance] openURL:url sourceApplication:sourceApplication annotation:annotation];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [[CammentSDK instance] applicationDidBecomeActive:application];
    ...
}

Configure CammentSDK with an API Key

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ...
    NSString *apiKey = @"YOUR_API_KEY";
    [[CammentSDK instance] configureWithApiKey:apiKey];
    ...
}

Now you are ready to use CammentSDK.

Add CammentSDK overlay on top of your video player

Open a View Controller where you would like to use CammentSDK and import header

#import <CammentSDK/CammentSDK.h>

Create a new property with CMCammentOverlayController class. This class is a container for all camment overlay internal logic

@property (nonatomic, strong) CMCammentOverlayController *cammentOverlayController;

Before creating Camment overlay we need to provide few configuration options. First of all, create show metadata object which holds identifier of your show:

CMShowMetadata *metadata = [CMShowMetadata new];
metadata.uuid = @"Any string unique identifier of your show";

Show identifier is any string which defines your show. Choose any uuid which is meaningfull for you. After that we need to create an object describing visual configuration for overlay layout.

CMCammentOverlayLayoutConfig *overlayLayoutConfig = [CMCammentOverlayLayoutConfig new];
// Let's display camment button at bottom right corner
overlayLayoutConfig.cammentButtonLayoutPosition = CMCammentOverlayLayoutPositionBottomRight;

Now instantiate controller and add it's subview on your view controller's view:

self.cammentOverlayController = [[CMCammentOverlayController alloc] initWithShowMetadata:metadata overlayLayoutConfig:overlayLayoutConfig];
[self.cammentOverlayController addToParentViewController:self];
[self.view addSubview:[_cammentOverlayController cammentView]];

Layout overlay subview properly:

-(void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    [[self.cammentOverlayController cammentView] setFrame:self.view.bounds];
}

Now add your player's view to camment overlay. Lets say that name of your player's variable is myPlayerView and it is subclass of UIView.

[self.cammentOverlayController setContentView:myPlayerView];

Check two important things: - myPlayerView doesn't have a superview, means you never add it like [view addSubview: myPlayerView] - you don't add myPlayerView on top of overlay view using default cocoa touch method addSubview. You should you setContentView instead.

Now we are almost done. There is one important thing left. For better user expierence we recommend to mute a video player when user starts recording camment and decrease volume at least by half when user plays camment. In order to do it - implement CMCammentOverlayControllerDelegate protocol:

self.cammentOverlayController.overlayDelegate = self;

The protocol provides four methods to notify your if camment is being recording or playing:

- (void)cammentOverlayDidStartRecording {
    // Mute your player here
}

- (void)cammentOverlayDidFinishRecording {
    // Restore normal volume
}

- (void)cammentOverlayDidStartPlaying {
    // Decrease volume level
}

- (void)cammentOverlayDidFinishPlaying {
    // Restore normal volume
}

Setup CammentSDK UI Delegate

Camment SDK uses UIAlertController to present important messages, like invitations from other users. In order to make UIAlertController will be presented at correct place in view controllers hierarchy we need to handle UI delegate events. UI delegate has a method which will be called when SDK wants to present a notification:

- (void)cammentSDKWantsPresentViewController:(UIViewController * _Nonnull)viewController;

Place where to handle it properly depends on your app architecture, but at very basic setup you can handle this method at visible view controller:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [CammentSDK instance].sdkUIDelegate = self;
}

- (void)cammentSDKWantsPresentViewController:(UIViewController *_Nonnull)viewController {
    [self presentViewController:viewController animated:YES completion:nil];
}

Setup CammentSDK Delegate

When user accepts an invitation to any show SDK will notify you by CMCammentSDKDelegate delegate. This step is optional, but usefull if you want to open a proper show when someone invites user to a group chat. Implement CMCammentSDKDelegate wherever it works better for your app. General idea is implement the delegate in an object which can manage internal navigation between screens.

@interface YourRouterObject()<CMCammentSDKDelegate>
@end
- (void)didJoinToShow:(CMShowMetadata *)metadata {
  NSString *showUuid = metadata.uuid;
  // open video player for show with uuid
}

Android SDK implementation

CammentSDK for Android

current version: 1.0.2

To get started with the Camment Mobile SDK for Android you can set up the SDK and build a new project, or you can integrate the SDK in an existing project.

The instructions were written for the following configuration: - Android Studio 2.3.3 - Java 1.8.0_112 - Gradle 2.3.3 (distribution gradle-3.3-all.zip)

Technical specification

SDK version SDK is built with the following configuration:

minSdkVersion 19
targetSdkVersion 26
compileSdkVersion 26
buildToolsVersion "26.0.1"

Note: If your application supports also lower versions, you have to handle enabling/disabling of the CammentSDK by yourself.

Dependencies CammentSDK relies on following dependencies: - Amazon AWS SDK (v2.6.6) - Facebook SDK (v4.25.0) - Google Exoplayer (v2.5.4) - Glide library (v4.0.0) - EasyPermissions library (v0.4.2) - Greenrobot EventBus (v3.0.0) - Android Support v4 (v26.0.1) - Android Support AppCompat-v7 (v26.0.1) - Android Support Design Library (v26.0.1) - Android Support RecyclerView (v26.0.1) - Android Support ConstraintLayout (v1.0.2)

CammentSDK uses own Facebook app to enable sign in into Camment service. Make sure you don't specify your own Facebook application id in manifest. In order to enable Facebook login, you have to provide release (and development) key hashes to Camment company. Steps how to create those hashes are well known and are described here: https://developers.facebook.com/docs/android/getting-started/ (Running Sample Apps section).

Note: If you use some of these dependencies in your application too, you can remove them from your app gradle file. In case you want to override some dependencies, you can do it using gradle, e.g.:

configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        def requested = details.requested
        if (requested.group == 'com.android.support') {
            if (!requested.name.startsWith("multidex")) {
                details.useVersion '26.0.1'
            }
        }
    }
}

Add CammentSDK to your project

SDK is available on the github in a maven structure, containing 2 important files: - cammentsdk-<sdk_version>.aar - cammentsdk-<sdk_version>.pom

Add following repository url into your project level build.gradle file:

allprojects {
    repositories {
        ... // your other repositories
        maven {
            url 'https://raw.githubusercontent.com/camment/sdk-android/master/sdk/'
        }
    }
}

Add following dependency into your application level build.gradle file:

dependencies {
    ... //your other dependencies
    compile ('tv.camment.cammentsdk:cammentsdk:<sdk_version>@aar') {
        transitive true
    }
}

Note: transitive true means that gradle will download also the SDK dependencies

Now sync the project with your gradle files and clean the project.

Initialize CammentSDK

Open your application class extending Application and add following into the onCreate() method:

public class YourApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        ...
        CammentSDK.getInstance().init(this);
    }
}

Note: Make sure you specified this class also in the AndroidManifest.xml if you didn't use it before:

<application
        android:name=".YourApp"
        ...>

Modify AndroidManifest.xml

Open your application AndroidManifest.xml and add: 1. specify your API key (security of the API key you have to handle by yourself):

<application
    ...>

    <meta-data
        android:name="tv.camment.cammentsdk.ApiKey"
        android:value="YOUR API KEY" />

</application>            
  1. Specify ContentProvider used by CammentSDK as it has to have unique authority:
<application
    ...>

    <provider
            android:name="tv.camment.cammentsdk.data.DataProvider"
            android:authorities="${applicationId}.cammentsdk"
            android:enabled="true"
            android:exported="false" />

</application>            

${applicationId} has to be specified in the application level build.gradle file.

android {
    ...
    defaultConfig {
        applicationId "com.yourapp.yourapp" //replace with your package name
        ...
    }
}

Add CammentSDK overlay on top of your video player

CammentSDK overlay should be included in the activity which shows video streaming.

<tv.camment.cammentsdk.views.CammentOverlay
        android:id="@+id/camment_overlay"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

CammentSDK overlay should be on top of every other view in the layout (usually defined as last in the layout). Example of layout:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black"
    tools:context="tv.camment.cammentdemo.CammentMainActivity">

    <FrameLayout
        android:id="@+id/fl_parent"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <VideoView
            android:id="@+id/show_player"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center" />
    </FrameLayout>

    <android.support.v4.widget.ContentLoadingProgressBar
        android:id="@+id/cl_progressbar"
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:visibility="gone"
        android:layout_gravity="center" />

    <tv.camment.cammentsdk.views.CammentOverlay
        android:id="@+id/camment_overlay"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

As CammentSDK overlay intercepts all touch events, it has to know to which ViewGroup to pass the touch events in order not to disable underlying components. In the layout above VideoView is wrapped in FrameLayout to enable this. Then in the activity where CammentOverlay is used, call setParentViewGroup(ViewGroup parentViewGroup) method.

CammentSDK also needs to know unique identifier of the currently watched show. Use setShowMetadata(ShowMetadata showMetadata) method. The first parameter of ShowMetadata object is show uuid and the second one is custom invitation text which will be passed together with invitation deeplink (can be null or empty String, in such case default invitation text is used).

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.<your_layout>);
    ...
    CammentSDK.getInstance().setShowMetadata(new ShowMetadata("<Any unique String identifier of your show>", "<Any custom invitation text>"));

    FrameLayout parentViewGroup = (FrameLayout) findViewById(R.id.fl_parent);
    CammentOverlay cammentOverlay = (CammentOverlay) findViewById(R.id.camment_overlay);
    cammentOverlay.setParentViewGroup(parentViewGroup);
}

Pass onActivityResult and onRequestPermissionsResult to CammentSDK

CammentSDK handles permissions which it needs as well as Facebook Login. In order to complete the flow correctly, pass results of onActivityResult and onRequestPermissionsResult to CammentSDK.

onActivityResult should be overriden in all activities (use your BaseActivity or similar parent activity) where CammentSDK is used as Facebook Login may be performed e.g. when invitation request is received and there has to be an activity ready to receive onActivityResult from Facebook SDK.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    CammentSDK.getInstance().onActivityResult(requestCode, resultCode, data);
}

onRequestPermissionsResult should be overriden in the activity where CammentOverlay is used.

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    CammentSDK.getInstance().onRequestPermissionsResult(requestCode, permissions, grantResults);
}

React to Camment interactions

For better user experience we recommend muting a video player when a user starts recording camment and decrease the volume at least by half when a user plays camment. In order to do it - implement CammentAudioListener interface and set it using method setCammentAudioListener(CammentAudioListener cammentAudioListener). Again this should be done in the activity where CammentSDK Overlay is used.

public interface CammentAudioListener {

    void onCammentPlaybackStarted(); // Decrease player volume

    void onCammentPlaybackEnded(); // Restore normal volume

    void onCammentRecordingStarted(); // Mute your player here

    void onCammentRecordingEnded(); // Restore normal volume

}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.<your_layout>);
    ...
    CammentOverlay cammentOverlay = (CammentOverlay) findViewById(R.id.camment_overlay);
    cammentOverlay.setCammentAudioListener(this);
}

DeepLinking

CammentSDK takes care of the invitation deeplinking. It specifies in its manifest CammentDeeplinkActivity which takes care of the deeplinks starting with camment:// scheme. Deeplinks are currently used to join group after an invitation. After the deeplink is opened, dialog is opened and user can decide if he wants to join the group or not. According to your app's activities and flow, you can decide where not to show this dialog, e.g. in the splash screen. To ignore the dialog on given Activity you just need to implement DeeplinkIgnore interface.

public class SplashActivity extends AppCompatActivity 
        implements DeeplinkIgnore

In such case Activity (which doesn't implement DeeplinkIgnore interface) following the SplashActivity will present the invitation dialog.

Deeplinks contain information about a show (show uuid). User should be navigated to the show no matter if he was inviter or invitee. As CammentSDK can't do this for you, implement OnDeeplinkOpenShowListener interface where it is suitable for your code and pass the listener to CammentSDK (in your Application object):

public interface OnDeeplinkOpenShowListener {

    void onOpenShowWithUuid(String showUuid);

}
public class CammentApp extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        ...
        CammentSDK.getInstance().init(this);
        CammentSDK.getInstance().setOnDeeplinkOpenShowListener(new YourObject());
    }
}

onOpenShowWithUuid will be called by CammentSDK when user reacts positively to any invitation request. You should open your activity with video playback for the given showUuid.