Play a Video When a Table View Cell is Tapped

Recently, a reader sent me an email asking me if I could create a tutorial explaining how to do this:

When the user tap a table view cell, play a video in a new view.

Now, this tutorial is a walk through of the construction of an iOS application that implement this requirement. At the end of the tutorial, it will look and function like the one shown in this QuickTime movie.

I got to work by launching Xcode 7 on my Mac created a Single View Application project called AV Player. You should download it so you can follow along.

download-excodeproj

Code presented on this page assume you are using Xcode 7.0 and Swift version 2.0. So if you are using a older or newer version of Swift, it may produce errors. Fix them by using Xcode’s Fix-it tool. Also, I assume you aren’t a newbie to the Swift Programming Language and you know your way around Xcode Integrated Development Editor.

Step 1: Create the app’s user interface

I created the project’s user interfaces by modifying the storyboard to look like Figure 1 below.  Next, I connected the View Controller scene’s table view cell to the AV Player View Controller scene by creating a segue. Next, in the Attribute inspector, I set the segue’s Identity property. I performed other standard task in Interface Builder for the View Controller scene, as shown in the image below. Next, I selected the View Controller scene’s object and clear constraints and add missing constraints to it.

Figure 1

Figure 1

Step 2: Add a Cocoa Touch Class in the project

I added a Cocoa Touch Class in the project with these options. Next, I configured the class so it contain only two string properties: title and url. Now, the Video class is for creating video objects, in the ViewController.swift class.

videoViewer-figure02

Step 3: Add code in the View Controller scene’s class

I entered code, in the ViewController.swift class file. It is the application’s workhorse. The code pretty much implemented tasks listed in the “App Response” section of these use case scenarios.

User Action App Response
The user launch the VideoViewer app on his device. The app create six video objects and display them in the View Controller’s  table view cells.
The user tap a cell on the Video List’s table view. The app initialize the AV Player by assigning it the selected video’s URL. The app tell the AV Player to play the selected video, once it finish loading itself on the user’s device.
The user tap the AV Player’s Done button. The app close the AV Player and display the View Controller’s view on the user’s device screen.

Here is a break down of what the class code does.

Above the class header, you’ll find these import statements. The second and third one is need for playing videos in the AV Player View Controller’s view.

import UIKit
import AVKit
import AVFoundation

Below the class header, you’ll find three statements. The first one declared an array variable for holding video objects. In the viewDidLoad() function, the array was initialized with six video objects. Further more, the array is the table view’s dataSource. The second statement declared variable for holding the URL of the video the user select, in the View Controller’s table view. The third variable is for holding the name of the video the user select, in the View Controller’s table view.

var tableDataSource = [Video]()
var selectedUrl = String()
var selectedTitle = String()

Code in the viewDidLoad() function created six video objects, set their title and url properties, then inserted them in the tableDataSource array.

let video1 = Video()
video1.title = "Big Buck Bunny movie trailer"
video1.url = "http://jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v"
tableDataSource.insert(video1, atIndex: 0)

let video2 = Video()
video2.title = "Kid Tobogganing"
video2.url = "http://www.ebookfrenzy.com/ios_book/movie/movie.mov"
tableDataSource.append(video2)

let video3 = Video()
video3.title = "Cat vs Snake"
video3.url = "https://theapplady.net/wp-content/uploads/2014/12/Cat-VS-Snake-Video-Clip-funny-and-amazing-videos-Joy-4all.mp4"
tableDataSource.append(video3)

let video4 = Video()
video4.title = "If I Were A Boy music video"
video4.url = "https://theapplady.net/wp-content/uploads/2014/12/Beyonce-If-I-Were-A-Boy.mp4"
tableDataSource.append(video4)

let video5 =  Video()
video5.title = "Beyonce Halo music video"
video5.url = "https://theapplady.net/wp-content/uploads/2014/12/Beyonce-halo.mp4"
tableDataSource.append(video5)

let video6 =  Video()
video6.title = "Crazy"
video6.url = "https://theapplady.net/wp-content/uploads/2014/12/Gnarls-Barkley-Crazy.mp4"
tableDataSource.append(video6)

You pretty much know what the table view data source functions does. Now, code in the prepareForSegue() function pretty much initialize the AV Player View by assigning it the selected video’s URL; and tell the AV Player object to play the URL’s video, once the AV Player View Controller class finish launching its player view on the user’s device screen.

if segue.identifier == "showVideoPlayer" {
  if let indexPath = self.tableView.indexPathForSelectedRow {
    let video = tableDataSource[indexPath.row]
    let destination = segue.destinationViewController as! AVPlayerViewController
    let url = NSURL(string: video.url)!
    destination.player = AVPlayer(URL: url)
    destination.player?.play()
  }
}
Problem: The video won’t play

Now, when you run the AV Player app on your real device or the Simulator and tap a table view cell, the app will display the AV Player View Controller’s view; however, the selected video won’t play.

videoViewer-figure03

The reason for this is because by default, iOS 9 enabled App Transport Security (ATS). Here’s what Apple have to say about it:

“App Transport Security is a feature that requires secure connections between an app and web services. The default connection requirements conform to the best practices for secure connections.
ATS will be enabled by default. This means all internet (HTTP) requests need to be made over SSL – all other requests will be blocked. Unencrypted HTTP requests will be canceled and the following error message will be output to Xcode’s output log:

App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app’s Info.plist file.”

To solve the App Transport Security issue, you will have to disable it by setting a couple of keys in the AV Player app’s Info.plist file.

In your app target, click on “Info” at the top, then right-click on the list and select “Add Row”.

avplayer-figure04a

In the row that appears, type “NSAppTransportSecurity”, and change the type to “Dictionary”.

avplayer-figure04b

Expand that new “NSAppTransportSecurity” key (arrow next to name should point down), right-click that key and select “Add Row”. A new row should be a child of the “NSAppTransportSecurity” key. Name that new child row “NSAllowsArbitraryLoads”; set the type to “Boolean”, and set it’s value to “YES”.

avplayer-figure04c

Afterwards, the keys should look like this:

avplayer-figure04d

Save the Info.plist, clean (shift + ⌘ + K), build (⌘ + B), and run (⌘ + R) the app again on your real device or the Simulator. When you tap the table view cell, the video is loaded in the AV Player View Controller’s view and start playing.

By the way, on the iPad Air and iPad Air 2, the user have the option to play one video in a full size AV Player and another one in a small AV Player. The user can drag the small video player’s screen to one of four corners of the larger player’s screen, while the video is play or in pause mode. Take a look at the QuickTime movie presented at the beginning of this tutorial, to see what I mean.

That’s a Wrap!

That’s it! I hope you guys find this tutorial and the Xcode project useful. Until next time, happy coding and please leave a comment! 🙂