Sunday, December 21, 2014

Make your first Swift Video App

Want to know how to play a simple video in Swift?

Create your application:

XCode->File->New->Project


Select Single View Application.

Give a suitable name to your project.  Select language as Swift.  For right now, we select the device as iPhone.  We won't be using Core Data for this application.


You will be displayed the project properties page and under the targets ->build phases tab ->Copy Resources sub menu ->insert your video



Add your video here .. mine is called cat.mp4.

Then go to your ViewController.swift

Import the MediaPlayer package to get all video playing functions.  The bolded lines below is what you need to add:

 //  
 // ViewController.swift  
 // SampleVideo  
 //  
 // Created by APARNA SRIDHAR on 12/22/14.  
 // Copyright (c) 2014 APARNA SRIDHAR. All rights reserved.  
 //  
   
 import UIKit  
 import MediaPlayer  
   
 class ViewController: UIViewController {  
     
   var moviePlayer : MPMoviePlayerController?  
   override func viewDidLoad() {  
     super.viewDidLoad()  
     playVideo()  
   }  
   
   override func didReceiveMemoryWarning() {  
     super.didReceiveMemoryWarning()  
     // Dispose of any resources that can be recreated.  
   }  
   
   func playVideo() {  
       
     //Get the Video Path  
     //You need to put this in Project->Target->copy bundle resource for this to work  
     let videoPath = NSBundle.mainBundle().pathForResource("cat", ofType:"mp4")  
       
     //Make a URL from your path  
     let url = NSURL.fileURLWithPath(videoPath!)  
       
     //Initalize the movie player  
     moviePlayer = MPMoviePlayerController(contentURL: url)  
       
     if let player = moviePlayer {  
         
       //Make the player scale the entire view  
       player.view.frame = self.view.bounds  
       player.scalingMode = .AspectFill  
         
       //Add it as a subView to your currentView  
       self.view.addSubview(player.view)  
         
       //Play the video  
       player.prepareToPlay()  
   
     }  
     else {  
       println("Movie player couldn't be initialized")  
     }  
   }  
   
 }  
   

Compile and project and see your video being played !

Download complete project here - https://github.com/aparnasridhar/SampleVideo

Friday, December 19, 2014

Servlets and JSP

Here is a quick overview on getting started with Java Web Development.

J2EE Development

IDE

Preferably an IDE like Eclipse or NetBeans to organize your code.  I use Eclipse.  You can find the latest build for developing Java EE applications here.  Luna is currently the most recent release.

https://eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/lunasr1

Server

You'll also need a Server to host your web application.  You can use Apache's Tomcat, Oracle's Glassfish, IBM's JBoss and other server app's suited for Java Dev.    Link to download Tomcat is below:

http://tomcat.apache.org/

Servlets

These are special applications that are hosted on your web server that enhance its functionality.   They are part of the J2EE suite of technologies used to make web applications.  When a client from a browser sends a request, the server reads the client request, invokes the right servlet to handle the request and then returns the response to the client.

The servlet may also forward the request to another servlet to handle the request and that in turn may return the response.

Why did we develop Servlets?

As the paradigm for layers and tiers developed in the software world, there was a large motivation to separate responsibility.  In an typical Model View Controller architecture, our View would be written in JSP or HTML, our Controller would be written using Servlets and our Model would be represented by a Enterprise Java Bean.  Functioning as the Controller, Servlets provided a way to process requests from the view, fetch data from the model/the database and then provide the results back to the view.

Java Support for Servlet

1.javax.servlet
2.javax.servlet.http

These are the two major packages that provide libraries for implementing Servlets and its related life cycle.  Your Servlet class is nothing but a java class that implements GenericServlet or HttpServlet class.  These classes provide the lifecycle methods for the servlet.

Generic Servlet is a protocol independent implementation of the Servlet interface.  HttpServlet is a protocol dependent implementation namely that of the Http protocol and serves http requests like a get or post.


Web.XML or Deployment Descriptor

This is the configuration file present in the WEB-INF folder of your application that enables the container to provides initialization parameters to the context, servlets and jsp files.  It can also be used to get the list of welcome files, get filters, listeners and so on.  Annotations are an alternative way to do this and reduce clutter in the web.xml available from Servlet version 3.0.

GET versus POST method

The HTTP Get request is usually sent by the browser to query or get data from the database.  These will usually correspond to database reads.  The HTTP Post requests are those that contain data and typical update/write something in the database.

The HTTP Get request contains the data it needs as a query string which is part of the request URL.  For this reason, it isn't suitable to transmit secure information like passwords.  In the HTTP Post request, the data is not submitted as part of the url but as part of the request body.  This is the reason its more suitable for secure data.

Another difference is that the GET request places a limit on the amount of data to be sent (the number of characters on the url string is limited), the POST method doesn't place a limit on the amount of data that can be sent.

GET is also non-idempotent - repeated get requests will give you the same result.  Post is idempotent - multiple requests will not give you the same result - eg first time you register on a website, your account is created.  Second time the same action will not happen.

So why ever use GET?  

Usually when you refresh a page with a POST method, the browser will ask you if you surely want to do that since that action may cause some action to be repeated.  This is the browser's way of making sure you don't perform any repeated updates.  This doesn't happen with the GET method.

Get is the default method that invoked if nothing is specified.


Understanding Servlet Lifecycle

You have the following methods:

1. init()
2. service()
3. destroy()

Init and destroy methods are called only once per servlet.  The service method is called various times for each servlet and every new request is handled by a new thread.

Init can be used to do all action common to all servlets like making database connections and so on.

The web server creates a new request and response object for every request that comes in and passes it to the server.  Its up to the server to keep track if subsequent requests come from the same browser.

Servlet API


ServletContext
  • This is provided by the container is common to all Servlets in your application.
  • It is created by the container when the application is started and destroyed only when the application is destroyed.  
  • They can supply initialization parameters that are common to a group of servlets in the application.
  • This provides access to application level attributes specified using <context-param> in web.xml file. 
  • Accessed by using the getServletContext() method and getAttribute() and setAttribute() methods allow us to store attributes in the context to be accessed by other servlets.
Servlet Config
  • This is used to specify some initial configuration for each servlet.
  • The servlet config is part of the ServletContext
  • The initialization parameters supplied as part of class annotations or in the web.xml file are available as part of the Servlet Config.  These are specific to a particular servlet.
  • Accessed by using getServletConfig() method.
  • There's no way to set/get attributes from the servlet configuration.
Init Parameters

This is data that is passed to the servlet when it is initialized.  This is different from data passed to the servlet from the doGet and POST method which come directly from the client.  The init parameters often help to set default values.

Parameters can be specified as part of Annotations in the servlet class file or as part of the web.xml.

Annotations versus Web.xml
  • When specified as part of web.xml, we can change the value of init parameters without needing to recompile the servlet class.  We only need to restart the server.  Annotation will require you to recompile the class and redeploy on the server.
  • Annotation are simple and are maintained per class level.  They are easier to maintain for application with large number of servlets where entering them in web.xml can be error prone.
  • IDEs like Eclipse provides support to write annotations and pre insert in the class during creation
Attributes Scope

These are data that can be stored that provides data about the request.

You can have attributes in the request, session and context scope.
  1. Request Attributes - Request is specific only to one particular request.  Another request from the same browser will not retain request variable. 
  2. Session Attributes - Session attributes are stored across different requests from the same browser session.  If the user switches his browser, then the session isn't retained. 
  3. Context Attributes - Context or application scope attributes are ones which are available across servlets and remain active till the application is alive.

Monday, December 15, 2014

Designing your First Swift Voice App


Learn it through lectures on Udacity using this link: https://www.udacity.com/course/ud585.

Code for the full project available on github: Pitch Perfect

Open Xcode->Single View Application->



Once created your Navigator will show the default files created namely AppDelegate.swift and ViewController.swift.  Things are very similar to the Objective-C world for now.

We are designing an app that will input your voice using the microphone and then allow you to play back that voice in slow and fast speeds and also add some effects like making you sound like a chipmunk or like Darth Vader.

First, we list down all the things we need to do to make this app happen:
  1. We need a view with a microphone button
  2. On pressing the button, the microphone should record our voice
  3. The recorded voice should be stored
  4. Once saved, we should have the options to play back the voice in different speeds and with different effects.
Going with Apple's Model View Controller Architecture, we can visualize the following components in our application:
  • Model - Stores our audio file
  • Controller - Allows us to input our voice and also allows us to add effects to it
  • View - Displays the microphone, provides a button to record voice, also provides a screen with options to add effects

Interactions:

  • Outlet A way the view can be accessed on the controller.  The controller can use this outlet to make changes to the view like changing the text of a label.
  • ActionA way the view can interact with the controller when events/changes take place on the view. An example would be a button being clicked on the view would invoke an action in the controller to handle the event.

Life Cycles of a viewController

  • viewDidLoad - used for one time initialization
  • viewWillAppear - used to hide/show controls
  • viewDidAppear - used to perform actions after controls appears
  • viewWillDisappear - used to wrap-up actions before the view disappears
  • viewDidDisappear - used to wrap up actions after the view disappears

Navigation View Controller

  • We can embed our view controllers in another navigation view controller that will allow us to navigate between different screens
  • One of the view controllers will be the root view controller which will be displayed first
  • Other view controllers can be segued from the root view controllers by linking it to events like button clicks
  • We navigate back to the calling viewController using the back button

Auto Layout

  • Xcode now provides a way to place controls on the screen and then specify their layout.  
  • Clicking on the control and dragging up or down will allow you to specify constraints on the display of the control.
  • You can make controls horizontally and vertically central to the display
  • You can make controls be positioned at a constant distance from the vertical and horizontal borders
  • You can change the auto layout by clicking on the component and dragging or by clicking on the component and using the auto layout menu at the bottom right of the storyboard layout to specify values directly.

Image

  • image.xcassets allows you to create new image sets for display of images in various apps.
  • These can be scaled as 1x,2x,3x depending on the device used for display.
  • Image sets can then be linked to different UI components using their image attribute.

Designing first view





We have the following components:

1. A microphone button
2. A label to display "recording" when we are recording voice

Steps:
  • Create a UIButton called recordButton and stopButton.  Create a label called recording label.  Set the stopButton and recordingLabel to be hidden when the view first appears.
  • Create outlets for the buttons and labels
  • Create actions for the recordButton and stopButton.
  • When the recordButton is pressed, show the label indicating that the audio is being recorded and also enable the stop button.  Also disable the recordButton so it cannot be pressed again.
  • When the stop button is pressed, hide the label that the audio is being recorded.

 import UIKit  
 class ViewController: UIViewController {  
   @IBOutlet weak var recordButton: UIButton!  
   @IBOutlet weak var stopButton: UIButton!  
   @IBOutlet weak var recordLabel: UILabel!  
   override func viewDidLoad() {  
     super.viewDidLoad()  
     // Do any additional setup after loading the view, typically from a nib.  
   }  
   override func didReceiveMemoryWarning() {  
     super.didReceiveMemoryWarning()  
     // Dispose of any resources that can be recreated.  
   }  
   override func viewDidAppear(animated: Bool) {  
     stopButton.hidden=true  
     recordButton.enabled=true  
   }  
   @IBAction func recordAudio(sender: UIButton) {  
     println("in record")  
     recordLabel.hidden=false  
     stopButton.hidden=false  
     recordButton.enabled=false  
   }  
   @IBAction func stopRecording(sender: UIButton) {  
     recordLabel.hidden=true  
     recordButton.enabled=true  
   }  
 }  

Create a Model

Create a new class and name it recordedAudio.  In this class, we'll store the title and the path for our recording.  When we switch between views in our application, this object will enable us to pass the recorded audio or namely ("the data") of our application.  This is in line with the general design that Apple recommends for storing our application's data.

 import Foundation  
 //This object represents the model  
 //The stored audio file has a title and URL  
 class RecordedAudio:NSObject  
 {  
   var title:String!  
   var filePathURL:NSURL!  
 }  

Initialize your model in your viewController

 class ViewController: UIViewController, AVAudioRecorderDelegate {  
   @IBOutlet weak var recordLabel: UILabel!  
   @IBOutlet weak var recordButton: UIButton!  
   @IBOutlet weak var stopButton: UIButton!  
   @IBOutlet weak var playButton: UIButton!  
   var audioPlayer:AVAudioPlayer!  
   var audioRecorder:AVAudioRecorder!  
   var recordedAudio:RecordedAudio!  
   var filePath:NSURL!  
   ......  
 }  


Record your voice

Back in your viewController, once you have your buttons and event triggering working and your model created, now add the ability to record your voice and stop recording to the recordAudio and stopRecording button action events:
  1. First get the directory path in your app's document folder to save the song
  2. Create a file name - you can use any filename, I'm appending the date/time to mine to make it unique everytime.
  3. Print it out so you can playblack and check the recording
  4. Create a new session for recording
  5. Assign yourself as the delegate for audio recording.  This will need you to also implement the AVAudioRecorderDelegate in your class.  Assigning our class as the delegate for recording will give us the ability to handle any events like "audioRecorderDidFinishRecording".  The advantage of this would be that we can make sure we let CoreAudio handle all the processing for the recording (like recording a 5 min long session) and we make all our transition (to other actions like switching pages) happens only after the processing is done.

  
@IBAction func recordAudio(sender: UIButton) {  
     recordLabel.hidden=false  
     stopButton.hidden=false  
     recordButton.enabled=false  
     
     //Get the place to store the recorded file in the app's memory  
     let dirPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask,true)[0] as String  
     
     //Name the file with date/time to be unique  
     var currentDateTime=NSDate();  
     var formatter = NSDateFormatter();  
     formatter.dateFormat = "ddMMyyyy-HHmmss";  
     var recordingName = formatter.stringFromDate(currentDateTime)+".wav"  
     var pathArray = [dirPath, recordingName]  
     let filePath = NSURL.fileURLWithPathComponents(pathArray)  
     println(filePath)  
     
     //Create a session  
     var session=AVAudioSession.sharedInstance()  
     session.setCategory(AVAudioSessionCategoryPlayAndRecord,error:nil)  
     
     //Create a new audio recorder  
     audioRecorder = AVAudioRecorder(URL: filePath, settings:nil, error:nil)  
     audioRecorder.delegate = self  
     audioRecorder.meteringEnabled=true  
     audioRecorder.prepareToRecord()  
     audioRecorder.record()  
   }  

Stop Recording

Now that we have a button to start recording, lets give the user the ability to stop the recording with a stop button:

   @IBAction func stopRecording(sender: UIButton) {  
     recordLabel.hidden=true  
     recordButton.enabled=true  
     audioRecorder.stop()  
     var audioSession = AVAudioSession.sharedInstance()  
     audioSession.setActive(false, error: nil)  
   }  

Once we have stopped recording,  we can implement the "audioRecorderDidFinishRecording" method to make sure we save our recorded file to our Model object (in our case its going to be a file called recordedAudio) so that we can use this object in the same or other views and it will now contain the recorded file.

   func audioRecorderDidFinishRecording(recorder: AVAudioRecorder!, successfully flag: Bool) {  
     if(flag)  
     {  
       //Store in Model  
       recordedAudio=RecordedAudio()  
       recordedAudio.filePathURL=recorder.url  
       recordedAudio.title=recorder.url.lastPathComponent  
       //Segway once we've finished processing the audio   
     }  
     else  
     {  
       println("recording not successful")  
       recordButton.enabled=true  
       stopButton.hidden=true  
     }  
   }  

In the above snippet, the segway comment gives you the area where can now implement any transitions to other views.

Playing an audio file

We need the AVFoundation library to provide classes to play an audio file.
The AVAudioPlayer is the class that provides for this.

Following is a good code snippet to play an audio file:
  • audioPlayer variable is declared globally so that different functions in the controller can access it.
  • filePath represents the path of the file.  
  • NSBundle.mainBundle asks XCode to look in the current directory for the resource "movie_quote" which is an mp3 file
  • we convert this filePath to a URL so that we can initialize the audio player with it
  • we set the enableRate property of the audio player to be true to allow us to change the rate at which the audio is played.
   var audioPlayer:AVAudioPlayer!  
   override func viewDidLoad() {  
     super.viewDidLoad()  
     if var filePath=NSBundle.mainBundle().pathForResource("movie_quote", ofType: "mp3")  
     {  
       var url=NSURL.fileURLWithPath(filePath)  
       audioPlayer = AVAudioPlayer(contentsOfURL: url, error: nil)  
       audioPlayer.enableRate=true;  
     }  
     else  
     {  
       println("file path is incorrect");  
     }  
     // Do any additional setup after loading the view.  
   }  

The snipped above first let you test the player functionality with a generic recording to make sure your audio player is functioning properly.  You can tweak the code above to make it play the audio file you stored in your model object as well.

Monday, December 1, 2014

CLRS 3e 2.1-4

2.1-4 Consider the problem of adding two n-bit binary integers, stored in two n-element arrays A and B. The sum of the two integers should be stored in binary form in an (n+1)-element array C. State the problem formally and write pseudocode for adding the two integers.

A = n bit binary array
= n bit binary array
C= n+1 bit binary array


1:        sum=0  
2:        for i = 1 to n   
3:           sum = sum+A[i] + B[i]   
4:           C[i]=sum%2  
5:           sum=sum/2  
6:        C[n+1]=sum  


The way we do overflows with integers is using the base 10.  Modulo by 10 gives the last digit after adding.  Division by 10 gives the carry over.  For binary numbers, the same applies with base 2.

If we add 2 binary numbers A = 11 (number 3) and B = 11 (number 3) we get C = 110 (number 6)

CLRS 3e 2.1-3

2.1-3 Consider the searching problem:

Input: A sequence of n numbers A = <a1; a2; : : : ;an> and a value .
Output: An index i such that  v = Ai or the special value NIL if  does not appear in A.

Write pseudocode for linear search, which scans through the sequence, looking for v. Using a loop invariant, prove that your algorithm is correct. Make sure that your loop invariant fulfills the three necessary properties.

LINEAR SEARCH: (A, v)

1:        r=NIL  
2:        for i = 1 to A.length   
3:           if(A[i]=v)   
4:             r=i
5:             return r 
6:           end if
7:        end for 
8:        return r   

We run through the length of the array, if we find the element we return it.  If we've reached the end of the for loop and haven't returned the value, then it wasn't found.  So we return NIL.

Loop Invariant - At the start of every loop, r contains the index of the search value, or r contains the special value NIL.

Initialization - At the start of the loop i=1, there are no elements in A yet considered for comparison. Value of r is NIL, indicating correctly that v has not yet been found.

Maintenance - At the start of each loop, we know r will hold the value NIL since it's not been found.  If it has been found, we would exit the loop and return the index at which it was found.

Termination - If we've reached the end of the loop then by our maintenance condition r will have the the value NIL.  If we've found the value, we exit the loop by returning the value.

CLRS 3e 2.1-2

2.1-2 Rewrite the INSERTION-SORT procedure to sort into non increasing instead of nondecreasing order.

INSERTION-SORT

1:            for j = 2 to A.length  
2:                 key=A[j]  
3:                 i = j -1 
4:                 while( i > 0 && A[i] < key )  
5:                      A[i+1]=A[i] 
6:                      i=i-1  
7:                 A[i+1]=key;  

CLRS 3e 2.2-1

2.1-1 Using Figure 2.2 as a model, illustrate the operation of INSERTION-SORT on the

array A = <31,41,59,26,41,58>

We start with A = <31,41,59,26,41,58>

A = <31,41,59,26,41,58>   //No Swaps (compare 31 < 41)
     
A = <31,41,59,26,41,58>   //No Swaps (compare 41 < 59)
              
A = <31,41,26,59,41,58>   //Swap 59 and 26 (59 > 26)

A = <31,26,41,59,41,58>   //Swap 26 and 41 (41 > 26)

A = <26,31,41,59,41,58>   //Swap 26 and 31 (31 > 26)

A = <26,31,41,41,59,58>   //Swap 59 and 41 (59 < 41)

A = <26,31,41,41,58,59>   //Swap 58 and 59 (59 > 58)