Parse has OpenTok iOS SDK’s back(end), so you don’t have to

Developing an iOS App itself is a huge undertaking: you want your product to be beautiful, interactive, and functional. That’s why Parse makes so much sense, it helps you avoid writing a backend server to power your App by giving you a data store and providing the most basic web services. These days many web services are incredibly powerful and help developers do really amazing things, like OpenTok, but they are targeted at having a backend. That’s where Parse Cloud Code comes in: it gives developers the ability to leverage the best of a back-end server in the path of least resistance.

TL;DR: Upload the code from this repo into your Parse Cloud Code application. Include it into your own script (here’s an example). Now you can create Sessions, generate Tokens, and more right from your own iOS (or any Parse powered) App by calling your cloud functions right from your client code (another example).

A few words about Security

OpenTok uses an API Key/Secret mechanism to authenticate a developer’s server-side requests when performing actions like making a new Session. The Secret is also used to sign data that you want to store in a Token. What you don’t want to do is include that Secret in your client side App, whether it be Javascript for a web App or an iOS App. This is important because there are real costs that come from a stream being published in your sessions with your API Key, you wouldn’t want to be picking up a malicious person’s minutes tab.

Parse has built-in authentication and authorization mechanisms that really come in handy here. As a developer, you get to decide how to handle login (maybe you want to use Twitter or Facebook or just plain email/password) to authenticate your users. Then you can use ACLs (Access Control Lists) to define what users are allowed to do (read public data, write private data, identify as part of a group, etc); this is authorization. Or maybe your application isn’t as intense and you are cool with simple anonymous users with all of the data being publicly readable and writable. The choice is yours, you know your needs the best, and thats the important part. We can piggyback off of these mechanisms to help you describe exactly who can make OpenTok Sessions, and to choose what data (like the Role) goes into their Tokens. Poof! You now have a solid security story behind your App.

Our Example App: Broadcasts

I’m going to take you through building an example App called Broadcasts to help illustrate how to set up an integration for yourself. The goal for Broadcasts is pretty simple, we want an App that lets any user start a Broadcast and lets any of the other users of the App watch. When a certain user creates a Broadcast, only that user can Publish video to it, and the rest can subscribe (this adds a little bit of authorization logic to our example).

There still are two parts to Broadcasts, the iOS code and the server-side code. The main difference here is that the server code is easy to write and deploy because its just a few functions using the existing Parse objects in the App, and I’ll show you how to write them.

You need to have an OpenTok Account for an API Key and Secret, and a Parse Application (call it Broadcasts) for an Application ID and Client Key. Let’s get started.

Setting Up: Let’s first set up Cloud Code for your App by installing the command line tool and creating a new directory to hold the project (more detailed instructions):

Now parse/cloud/main.js is the file we will write our functions within. But before we do that we need to pull in the OpenTok library that I’ve provided. Copy the contents of this repository into a new directory called opentok so that you now have the directory layout as seen below:

Writing our Cloud Code: Now we’re going to create a few functions inside main.js. This code is customized to how we want Broadcasts to work. I’ve decided beforehand that the App contains objects of the class Broadcast that have two important properties: sessionId and owner. Note that I’m not calling it a Session; I’ve assigned it a name that is meaningful for the logic of this App (Broadcast) and then referenced an OpenTok Session with its sessionId property. The owner property is a Parse.User object and helps us figure out who is authorized to publish to the Broadcast. Use the code below and substitute your OpenTok API Key and Secret:

The comments in the code above should help you understand what’s going on. You are not limited to follow the exact same logic, all that I’ve done is use the Parse JavaScript API to describe how I want to handle creating my Sessions (before a Broadcast object is saved) and generating my Tokens (when I call the function). Lets deploy it:

Server-side, done.

Setting iOS Up: Now we just hook the backend up to the iOS App. I’ve already provided a shell of the Broadcasts App for you. Download it into the iOS directory so your directory structure is as below:

The first thing you need to do is to add your OpenTok API Key, Parse Application ID, and Parse Client Key to the iOS/Broadcasts/Constants-sample.h file and then rename it to Constants.h. Now open Broadcasts.xcodeproj in Xcode. If you run the App now, you will see that you can create a Broadcast by tapping the ‘+’ in the top right, naming it, and hitting done. If you then select that row, you will go into that Broadcast but nothing will happen, there is a Label at the bottom that says we are Disconnected from OpenTok.

Sessions: You may have not realized, but this part is already done. When a new Broadcast gets saved, the beforeSave function we created in the Cloud Code should run and attach a sessionId property to each Broadcast object. Use the Parse Data Explorer to confirm this.

Tokens: There are two pieces we need to correctly generate a token: owners and calling the getBroadcastToken Cloud function

Owners: In the shell, the Broadcast object has no concept of an owner. We will be creating anonymous users through Parse so that every user has some sort of identity, and then assign a Broadcast’s owner when a new one is saved. Then we will use that information to help display which Broadcasts can be published to by the current user in the Table View. Lastly, we will use that owner information to decide whether we should publish or subscribe when we have opened a particular Broadcast. Follow the code examples below.

Add Line 9 above to make sure an anonymous user is created.

Add Lines 9-14 above to add an owner property to new Broadcasts before they are saved, and specify that they are publicly readable but only writable by the owner.

Edit the line matching line 8 to enable a ★ icon next to the Broadcasts in the Table that is owned by the current user.

Create the method on lines 3-5 as a helper to find out of the current Broadcast is owned by the current user. Then use that method in the if statements that wrap the code on lines 12-15 and 23-25.

Calling getBroadcastToken in the Cloud: The last part is to call our Cloud Code function, which returns asynchronously, and then we use the result to finally connect to the OpenTok session.

Add the method call on lines 11-18 which contains a block that connects to the Session.

Build and Run: If all went well, you should be able to Run and play with the completed Broadcasts App. If you have any problems you can compare with the completed version of the App.

But wait, there’s more…

Why limit ourselves to using Parse for iOS Apps? You can also use their JavaScript API to save you the trouble of writing a backend for your web Apps, too. With the security model benefits I highlighted before, that might not be such a bad idea after all.

  • Johann

    Hi! Great tutorial. I have two questions:

    When I try to build this for my iPhone, I get this error:

    No such file or directory (/Users/myusername/projects/Broadcasts/iOS/build/Debug-iphoneos/Broadcasts.app/Broadcasts)

    Any idea what might be happening? Something in the build settings?

    Also, I’m not sure how to take this code to the next step of allowing users to connect to my session through the web browesr. IS there any example out there showing how to connect this Parse + iOS example and accessing the session through the browser? Any help on this would be much appreciated!

    Thanks in advance,

    Johann

    • http://aoberoi.me Ankur Oberoi

      Hey Johann,

      Glad you liked the tutorial. Stay tuned, this may get even simpler to implement in the near future. We are talking to Parse about including OpenTok as an official Cloud Module.

      The error seems related to the build location you have set in Xcode. Which version of Xcode are you using? Can you send me the full build logs? The easiest way to do this is to open the command line and go into your project directory (/Users/myusername/projects/Broadcasts/iOS) and type `xcodebuild`. Email the output to me (ankur@tokbox.com) and I’ll be happy to help find the issue with you.

      – Ankur

  • vividcode

    Great tutorial Ajay. However I still feel this could be very generic in terms of opentok-parse integration. Instead it addresses a specific usecase of broadcasts. Besides, imagine someone familiar with just iOS or simply iOS + Parse, which I believe is the majority audience for your blog. For them it would quite serve if you could point out what different / additional things they would have to do in order to integrate opentok. Maybe you are already doing it, but it’s not reaching me – maybe a generic writeup for ANY sort of iOS project would be needed. A list of to-dos to integrate opentok, and so on, irrespective of Broadcasts or not. To see why I am talking sense, see my query here(but no one has cared to answer): http://stackoverflow.com/questions/15267806/integrate-opentok-video-conferencing-into-ios-app – from this I take it up that there is a vast array of potential opentok integrators who are not confident to take their next step, simply because of the lack of abundant documentation and tutorials. You will do them great help by posting more relevant material.

  • http://www.facebook.com/tomas.harris.796 Tomas Harris

    Hi Ajay,

    I tried to implement this on parse a couple of days ago and it’s failing out when I call Opentok. I looked on the parse forums and another guy is having a similar problem although his was working and has recently stopped.

    When I call Opentok via curl with my api credentials it returns fine. I sent Parse an email asking them if it was a problem on there end and they said everything looks to be fine. It seems that when called via parse your service is returning nothing.

    Cheers,

    Jake

    • http://aoberoi.me Ankur Oberoi

      Hey Jake,

      I just tested to make sure the code still works, and I’m not having any problems.

      Can you point me to where you found another person on the forums with an OpenTok issue?

      If you want, I can take a look at your cloud code implementation and see if there’s any errors I can spot. Email me at ankur@tokbox.com

      PS. My name is Ankur, I’m not sure why a couple people on this post think its Ajay, where did you see that? Its weird because your name shows as Tomas Haris but you signed off as Jake, lol.

  • Pingback: iPhone video chatIPhoneGameZone

  • MacShah

    HI,

    i had implement application Hello world its working great to two stream in iPad(2/3/4) but i am tray to connect with third i pad i am not getting three streaming in all three ipads ,

    how to get third streaming in iPad,

    • http://aoberoi.me Ankur Oberoi

      Hey there,

      This tutorial is pretty different from Hello World on iOS (which we have for Objective-C, Titanium, and PhoneGap). If you have a specific issue with that tutorial, send me an email and I’ll try to help you out there. ankur@tokbox.com

  • konradholubek

    Hi Ankur,

    Very interesting tutorial! However, I do not use parse, but StackMob and Amazon EC2. What would then be my configuration, especially for the Cloud part?

    Thank you in advance.

    Konrad

  • Mohit Sharma

    Hi Ankur,

    I getting a problem to create session. session:didfailWithError delegate function called everytime. error is
    Authorization Failure – Invalid credentials were provided