Say you have a bunch of music videos/movies stored on a remote server. Now, you want the user of your app to view them on their iPhone or iPad device. Well, you’d have to use an instance of the MPMoviePlayerController class in your iOS app, and this tutorial will show you how.
Overview Of The Project
In this tutorial we will create an iOS application called MoviePlayer. The app will have two scenes and corresponding view controller class files. Images below shows what they’ll look like on the iOS Simulator. When you launch the app, say on the iPhone 5 simulator, you’ll see the Movie Player View-see Figure 1 below. When you click the Selected Movie button, the app will display the Movie List view as a popover-see Figure 2 below.
Figure 1: Movie Player View | Figure 2: Movie List View |
Now, when you select a movie name in the Movie List View’s table view, the app will do the following:
- Dismiss the Movie List View.
- Display the selected movie name in the Movie View’s nav bar.
- Pass the selected movie url to the Movie View.
- Create a moviePlayer object and add it on the Movie Player View
- Play the passed url’s movie in the moviePlayer object-see Figure 3 below.
Figure 3 |
As for the app’s data model, it will consist of a custom class called Movie and an array variable called tableDataSource. The Movie class is for creating movie objects in the tableDataSource variable. The tableDataSource variable will serve as the table view’s datSource object.
That’s pretty much all you need to know about the MoviePlayer application you’ll build in this tutorial.
Create The Project
Fire up the latest version of Xcode; currently it is ver 6.1.1, and create a new iOS project by executing steps shown in Figure 4 below.
Figure 4: Project creation steps |
Configure The Project
What you have to do now is configure the MoviePlayer project. Start by deleting the ViewController.swift file from the Project Navigator. You have to add three class files in the project. Here are the steps to add the first one:
- Right-click the Project Navigator and select New File… from the pop-up menu.
- Select the Cocoa Touch Class template and click Next.
- Provide information shown in the image below for the class file, then click Next.
Figure 5 |
Repeat above steps to add two more class files in the project, with options shown in images below.
Figure 6 | Figure 7 |
Add the MediaPlayer framework in the project:
- Click the MoviePlayer project’s root folder
- Click the Build Phases tab (see Figure 8A below), expand the “Link Binary With Libraries” item, and click the + button.
- Enter “media” in the search box (see Figure 8B) below and select “MediaPlayer.framework” from the search results list, then click the Add button.
Figure 8A | Figure 8B |
Configure the Main.storyboard file:
- Click the file to load it in Interface Builder.
- Click the View Controller scene object then embed it in a Navigation Controller by selecting Navigation Controller from the Editor menu.
- Drag a Bar Button Item from the Object Library and drop it on the right side of the scene’s Navigation Bar.
- Set the Navigation Item’s Title attribute and the Bar Button Item’s Title attribute to values shown in the Figure 9 below.
Figure 9 |
- Declare this IBOutlet variable and IBAction function in the MoviePlayerViewController.swift file.
- Connect IBOutlet and the IBAction function to the scene’s Bar Button Item.
@IBOutlet weak var selectMovieButton: UIBarButtonItem! |
@IBAction func selectMovieButtonTapped(sender: AnyObject) { } |
Add a second scene on the storyboard canvas and configure it:
- Drag a Table View Controller from the Object library and drop it on the right side of the Movie Movie Player View Controller scene.
- Select the scene’s Table View Cell and set its Style, Identifier, and Accessory attribute fields in the Attributes inspector-see Figure 10A below.
Figure 10A |
- Select the Table View Controller scene object.
- Click the Identity inspector and enter “idPopover” in the Storyboard ID field-see Figure 10B below.
The reason why you set the scene’s Storyboard ID attribute is because you’ll be referencing the scene in code.
Figure 10B |
- Connect the storyboard scenes to their respective class files. Figure 11a and Figure 11B below shows what the connections should look like in the Interface Builder.
Figure 11A |
Figure 11B |
The Movie Player View’s Class Code
Ok, so you’ve configured the project. What you have to do now is add code shown below in the MoviePlayerViewController.swift file.
import UIKit import MediaPlayer class MoviePlayerViewController: UIViewController, UIPopoverPresentationControllerDelegate { @IBOutlet weak var selectMovieButton: UIBarButtonItem! var movieUrl = String() var moviePlayer: MPMoviePlayerController! override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } func unwindFromModalViewController(segue: UIStoryboardSegue) { if segue.identifier == "returnHome" { var sourceViewController: MovieListViewController = segue.sourceViewController as MovieListViewController self.navigationItem.title = sourceViewController.selectedTitle self.movieUrl = sourceViewController.selectedUrl playSelectedMovie() self.dismissViewControllerAnimated(false, completion: nil) } } func playSelectedMovie() { moviePlayer = MPMoviePlayerController(contentURL: NSURL(string: movieUrl)) moviePlayer.view.frame = CGRect(x: 20, y: 70, width: 250, height: 230) self.view.addSubview(moviePlayer.view) moviePlayer.controlStyle = MPMovieControlStyle.Embedded moviePlayer.play() } @IBAction func selectMovieButtonTapped(sender: AnyObject) { var viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("idPopover") as? MovieListViewController viewController?.modalPresentationStyle = UIModalPresentationStyle.Popover viewController?.popoverPresentationController?.delegate = self viewController?.popoverPresentationController?.barButtonItem = selectMovieButton viewController?.popoverPresentationController?.permittedArrowDirections = .Any viewController?.preferredContentSize = CGSizeMake(275.0, 375.0) self.presentViewController(viewController!, animated: true, completion: nil) } func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle { return UIModalPresentationStyle.None } }
How The Code Work
Le’s go over the code you entered in the MoviePlayerViewController.swift file’s functions. Let us start from the bottom and work our way up.
Code you entered in the selectMovieButtonTapped() function basically reconfigured the Movie List View so it is shown as a popover view. The final statement shows the re-configured Movie List View on the sim’s screen like this:
Figure 12 |
Code you entered in the playSelectedMovie() function basically create a moviePlayer object and add it as a subview in the Movie Player View, play the movie file that’s stored in the movieUrl variable. Now, the playSelectMovie() function is called in the unwindFromModalViewController() function. Here’s what the moviePlayer object looks like on the sim’s screen:
Figure 13 |
Code you entered in the unwindFromModalViewController() function basically:
- Put the MovieListViewController in a view controller object called sourceViewController.
- Set the Movie Player View’s navigation bar’s title property
- Initialize the movieUrl variable.
- Call the playSelectedMovie() function.
- Dismiss the Movie List View.
By the way, the unwindFromModalViewController() function is called via the MovieListViewController.swift file’s didSelectRowAtIndex() function like this:
self.performSegueWithIdentifier("return", sender: self)
You declared two variables: movieUrl and moviePlayer. You already know what they are for. Moving along, you conformed the MovieListViewController class to the UIPopoverPresentationControllerDelegate protocol. Failure to do this will result the app not running in the sim; instead the compiler will issue this fatal error message:
Type ‘MoviePlayerViewController’ does not conform to protocol ‘UIPopoverPresentationControllerDelegate’
Finally, you imported the MediaPlayer module. Again, failure to do this will result in the app not running in the sim and the compiler issuing a bunch of fatal error messages.
The Movie List View’s File Code
Now, here’s the source code to enter in the MovieListViewController.swift file.
import UIKit class MovieListViewController: UITableViewController { var tableDataSource = [Movie]() var selectedUrl = String() var selectedTitle = String() override func viewDidLoad() { super.viewDidLoad() var movie1 = Movie() movie1.title = "Big Buck Bunny movie trailer" movie1.url = "http://jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v" tableDataSource.insert(movie1, atIndex: 0) var movie2 = Movie() movie2.title = "Kid Tobogganing" movie2.url = "http://www.ebookfrenzy.com/ios_book/movie/movie.mov" tableDataSource.append(movie2) var movie3 = Movie() movie3.title = "Cat vs Snake" movie3.url = "https://theapplady.net/wp-content/uploads/2014/12/Cat-VS-Snake-Video-Clip-funny-and-amazing-videos-Joy-4all.mp4" tableDataSource.append(movie3) var movie4 = Movie() movie4.title = "If I Were A Boy music video" movie4.url = "https://theapplady.net/wp-content/uploads/2014/12/Beyonce-If-I-Were-A-Boy.mp4" tableDataSource.append(movie4) var movie5 = Movie() movie5.title = "Beyonce Halo music video" movie5.url = "https://theapplady.net/wp-content/uploads/2014/12/Beyonce-halo.mp4" tableDataSource.append(movie5) var movie6 = Movie() movie6.title = "Crazy" movie6.url = "https://theapplady.net/wp-content/uploads/2014/12/Gnarls-Barkley-Crazy.mp4" tableDataSource.append(movie6) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } // MARK: - Table view data source override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return tableDataSource.count } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell var movie: Movie = tableDataSource[indexPath.row] cell.textLabel!.text = movie.title return cell } override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)! selectedUrl = tableDataSource[indexPath.row].url selectedTitle = tableDataSource[indexPath.row].title self.performSegueWithIdentifier("returnHome", sender: self) } }
How The Code Work
Le’s go over the code you entered in the MovieListViewController.swift file’s function. Let us start from top and work our down.
You declared an object variable called tableDataSource for holding movie objects. Further more; it is the table view’s dataSource object. You declared a variable called selectedUrl for holding a movie url. You declared a variable called selectedTitle for holding the movie title you select in the table view.
You entered code in the viewDidLoad() function to create six Movie objects add them in the tableDataSource object. The final set of code you entered in the class file are the table view’s data source functions. The first function return the number of sections there are in the table view. The second function return the total number of objects there are in the tableDataSource object variable.
The third function loop through the tableDataSource object variable and populate the table view cells with movie titles. The last function set the selectedTitle variable with the movie title you select in the table view. The final statement in the function call the performSegueWithIdentifier() function. As you already know, that function call the MoviePlayerViewController.swift file’s unwindFromModalViewController() function.
Code Output
When you run the app in the sim, you will see output shown in Figure 14A below. When you click the Select Movie button, you will see output shown in Figure 14B. When you click the first cell in the table view, you’ll see output shown in Figure 14C.
Figure 14A | Figure 14B | Figure 14A |
This conclude the tutorial on “How to Play a Movie in A Swift App”. Feel free to download the final version of the MoviePlayer project and leave a comment or two! 🙂