Friday, 30 September 2011

Checking white space and Trimming specific character in iphone

#define allTrim( anyobject ) [anyobject
 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet] ]

NSString *stringname = @"   ";
if ( [allTrim( stringname ) length] == 0 ) NSLog(@"Is empty!");

Thursday, 29 September 2011

Text to Speech with flite

Api url
https://bitbucket.org/sfoster/iphone-tts/src
//For code it
https://bitbucket.org/sfoster/iphone-tts/

Different example for iphone

http://pragprog.com/titles/cdirec/source_code
http://www.codingventures.com/2008/12/useful-open-source-libraries-for-iphone-development/

http://iphoneapp-dev.blogspot.com/2011/05/this-example-shows-how-to-upload-images.html

http://www.scoop.it/t/iphone-and-ipad-development/p/5853246/show-a-custom-popover-view-within-your-ipad-app-seaside

http://iphonecode.weebly.com/iphone-learning-codes.html

http://code.google.com/p/iphone-sdk-programming-book-code-samples/

http://www.iphoneexamples.com/

http://pragprog.com/titles/cdirec/source_code

http://www.theiphonedev.com/SourceCode/tabid/143/Default.aspx
http://iphone.zcentric.com/

http://www.bogotobogo.com/XcodeSDK-Chapter12.html


Wednesday, 28 September 2011

UrlDemo2


// For the downloading the MKStoreManager

https://github.com/MugunthKumar/MKStoreKit


// Simple animation

http://www.edumobile.org/iphone/iphone-programming-tutorials/moveimage-in-iphone/


//For pinch in pinch out of uiimageview

http://www.icodeblog.com/2010/10/14/working-with-uigesturerecognizers/

//For image cropping ,transparency etc

http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/


//UIImageView Rotate, Move and Zooming and also for different example


http://w2om.com/uiimage-rotate-move-and-zooming/

//For pub reader example

https://github.com/st3fan/iphone-bookreader




Tuesday, 27 September 2011

Image view zoom in out + Rotate

//For zoom in /out + button with rotate by + - Buttons


#define degreesToRadians(x) (M_PI * x / 180.0)
#define zoomed 0.01
-(IBAction)resizeImageview:(id)sender{
   
    if([sender tag]==1){
        // holderView.frame=CGRectMake(x+3, y+4, width-6,height-8);
        holderView.transform = CGAffineTransformScale(holderView.transform, 1-zoomed, 1-zoomed);
       
    }
    else if([sender tag]==2){
        //holderView.frame=CGRectMake(x-3, y-4, width+6,height+8);       
        holderView.transform = CGAffineTransformScale(holderView.transform, 1+zoomed, 1+zoomed);
    }


}
-(IBAction)rotateImageView:(id)sender{
    if ([sender tag]==3) {
        holderView.transform = CGAffineTransformRotate(holderView.transform, degreesToRadians(-10));
       
    }
    else if([sender tag]==4){
        holderView.transform = CGAffineTransformRotate(holderView.transform, degreesToRadians(10));
       
    }   
}

Friday, 16 September 2011

Recording with saving in iphone

#import <UIKit/UIKit.h>
#import <sqlite3.h>
@class record_audio_testViewController;

@interface record_audio_testAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    record_audio_testViewController *viewController;
    NSString *databaseName;
    NSString *databasePath;
    NSMutableArray *recoredAudioArray;
}
@property(nonatomic,retain)NSMutableArray *recoredAudioArray;
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet record_audio_testViewController *viewController;
-(void) checkAndCreateDatabase;
-(void) readEngEntryArrayFromDatabase;
-(void) updateDatabase:(NSString *)pathName;
- (void)insertIntoDatabase:(NSString *)Name;
@end



//////////////////
 #import "record_audio_testAppDelegate.h"
#import "record_audio_testViewController.h"
#import "TableFields.h"
@implementation record_audio_testAppDelegate
@synthesize recoredAudioArray;
@synthesize window;
@synthesize viewController;


- (void)applicationDidFinishLaunching:(UIApplication *)application {  
    databaseName = @"100Songs5.sqlite";
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];
    databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
  
    // Execute the "checkAndCreateDatabase" function
    [self checkAndCreateDatabase];
    [self readEngEntryArrayFromDatabase];

  
    NSLog(@"%@",recoredAudioArray);
    // Override point for customization after app launch  
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}
-(void) checkAndCreateDatabase{
    // Check if the SQL database has already been saved to the users phone, if not then copy it over
    BOOL success;
  
    // Create a FileManager object, we will use this to check the status
    // of the database and to copy it over if required
    NSFileManager *fileManager = [NSFileManager defaultManager];
  
    // Check if the database has already been created in the users filesystem
    success = [fileManager fileExistsAtPath:databasePath];
  
    // If the database already exists then return without doing anything
    if(success) return;
  
    // If not then proceed to copy the database from the application to the users filesystem
  
    // Get the path to the database in the application package
    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
  
    // Copy the database from the package to the users filesystem
    [fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
  
    [fileManager release];
}

-(void) readEngEntryArrayFromDatabase {
    // Setup the database object
  

    sqlite3 *database;
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];
    databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
    // Init the EngEntryArray Array
    recoredAudioArray = [[NSMutableArray alloc] init];
  
    // Open the database from the users filessytem
    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
        // Setup the SQL Statement and compile it for faster access
        const char *sqlStatement = "select * from RecordedAudio";
        sqlite3_stmt *compiledStatement;
        if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
            // Loop through the results and add them to the feeds array
            while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
                // Read the data from the result row
                NSString *EngEntryNm = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
              
                 [recoredAudioArray addObject:EngEntryNm];
              
         }
        }
        // Release the compiled statement from memory
        sqlite3_finalize(compiledStatement);
      
    }
    sqlite3_close(database);
  
}

-(void) updateDatabase:(NSString *)pathName
{
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];
    databasePath = [documentsDir stringByAppendingPathComponent:databaseName];

    sqlite3 *db ;
    sqlite3_stmt *update_statement;
    
    NSString *sqlStr = [NSString stringWithFormat:@"UPDATE RecordedAudio SET File_Name='%@' WHERE File_ID='%d'",
                        pathName];
  
    const char *sql = [sqlStr UTF8String];
    if(sqlite3_open([databasePath UTF8String], &db) == SQLITE_OK) {
      
     if (sqlite3_prepare_v2(db, sql, -1, &update_statement, NULL) != SQLITE_OK) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"DatabaseNotAvailable", @"") message:[NSString stringWithUTF8String:sqlite3_errmsg(db)]
                                                       delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
        [alert show];  
        [alert release];
        //return NO;
    }
    }
    int success = sqlite3_step(update_statement);
    if (success == SQLITE_ERROR) {
        NSAssert1(0, @"Error: failed to insert into the database with message '%s'.", sqlite3_errmsg(db));
        //return NO;
    }
  
    sqlite3_finalize(update_statement);
    
}
- (void)insertIntoDatabase:(NSString *)Name{
    sqlite3 *database;
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];
    databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
  
   /* if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
        const char *sqlStatement;  
        sqlite3_stmt *addStmt;
      
    
            sqlStatement = "insert into RecordedAudio(File_Name) Values(?)";
     
        if(sqlite3_prepare_v2(database, sqlStatement, -1, &addStmt, NULL) != SQLITE_OK)
            NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database));
      
      
        sqlite3_bind_text(addStmt,1,[Name UTF8String],-1,SQLITE_TRANSIENT);
      
        if(SQLITE_DONE != sqlite3_step(addStmt))
            NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database));
      
        sqlite3_finalize(addStmt);
      
        //Reset the add statement.
       // sqlite3_reset(addStmt);
        sqlite3_close(database);
    }*/
 
  
    sqlite3_stmt *insert_statement;
  
    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
        static char *sql = "insert into RecordedAudio(File_Name) Values(?)";
        if (sqlite3_prepare_v2(database, sql, -1, &insert_statement, NULL) != SQLITE_OK) {
            NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
        }
    }
  
    sqlite3_bind_text(insert_statement,1,[Name UTF8String],-1,SQLITE_TRANSIENT);
    
    int success = sqlite3_step(insert_statement);
    // Because we want to reuse the statement, we "reset" it instead of "finalizing" it.
    sqlite3_finalize(insert_statement);
    //sqlite3_reset(insert_statement);
    insert_statement=nil;
    if (success == SQLITE_ERROR) {
        NSAssert1(0, @"Error: failed to insert into the database with message '%s'.", sqlite3_errmsg(database));
    } else {
      
    //    primarykey = sqlite3_last_insert_rowid(db);
    }
   
}


- (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
}


@end
/////////////////


#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreAudio/CoreAudioTypes.h>
#import "record_audio_testAppDelegate.h"
@interface record_audio_testViewController : UIViewController <AVAudioRecorderDelegate> {

    record_audio_testAppDelegate *appDel;
    IBOutlet UIButton * btnStart;
    IBOutlet UIButton * btnPlay;
    IBOutlet UIActivityIndicatorView * actSpinner;
    BOOL toggle;
   
    //Variables setup for access in the class:
    NSURL * recordedTmpFile;
    AVAudioRecorder * recorder;
    NSError * error;
   
   
   
    AVAudioPlayer *audioPlayer;
    AVAudioRecorder *audioRecorder;
    int recordEncoding;
    enum
    {
        ENC_AAC = 1,
        ENC_ALAC = 2,
        ENC_IMA4 = 3,
        ENC_ILBC = 4,
        ENC_ULAW = 5,
        ENC_PCM = 6,
    } encodingTypes;
}


-(IBAction) startRecording;
-(IBAction) stopRecording;
-(IBAction) playRecording;
-(IBAction) stopPlaying;


@property (nonatomic,retain)IBOutlet UIActivityIndicatorView * actSpinner;
@property (nonatomic,retain)IBOutlet UIButton * btnStart;
@property (nonatomic,retain)IBOutlet UIButton * btnPlay;

- (IBAction) start_button_pressed;
- (IBAction) play_button_pressed;
@end

/////////////////

#import "record_audio_testViewController.h"


NSURL *   tempFilePath;
int countRecord;
@implementation record_audio_testViewController
@synthesize actSpinner, btnStart, btnPlay;



/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}
*/

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/



// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
   
    appDel=(record_audio_testAppDelegate *)[[UIApplication sharedApplication]delegate];
   
    recordEncoding = ENC_AAC;

    //Start the toggle in true mode.
    toggle = YES;
    //btnPlay.hidden = YES;

    //Instanciate an instance of the AVAudioSession object.
    AVAudioSession * audioSession = [AVAudioSession sharedInstance];
    //Setup the audioSession for playback and record.
    //We could just use record and then switch it to playback leter, but
    //since we are going to do both lets set it up once.
    [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: &error];
    //Activate the session
    [audioSession setActive:YES error: &error];
    countRecord=1;
}




-(IBAction) startRecording
{    NSLog(@"startRecording");
   
         NSString *audioFileName=[NSString stringWithFormat:@"Record%d",countRecord];
    NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
   
    NSString *docsDir = [dirPaths objectAtIndex:0];
   
   tempFilePath = [NSURL fileURLWithPath:[docsDir stringByAppendingPathComponent:[NSString stringWithFormat: @"%@.%@",audioFileName, @"caf"]]];
   
    NSLog(@"%@",tempFilePath);
    NSMutableDictionary* recordSetting = [[NSMutableDictionary alloc] init];
    [recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
    [recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
    [recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
    //stringByAppendingPathComponent: [NSString stringWithFormat: @"%@.%@",audioFileName, @"caf"]]];
   
   
    recorder = [[ AVAudioRecorder alloc] initWithURL:tempFilePath settings:recordSetting error:&error];
    [recorder setDelegate:self];
   
    [recorder prepareToRecord];
   
    [recorder record];

       NSLog(@"recording");
}

-(IBAction) stopRecording
{
    
    NSURL *url =  tempFilePath;
    NSData *data = [NSData dataWithContentsOfURL:url];
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    path = [path stringByAppendingString:[NSString stringWithFormat:@"Record%d",countRecord]];
    [data writeToFile:path atomically:YES];
   
    BOOL checkUpadte;
    [appDel readEngEntryArrayFromDatabase];
    NSMutableArray *checkArray=[[NSMutableArray alloc] init];
    checkArray=appDel.recoredAudioArray;
    NSLog(@"checkArray %@",checkArray);
    NSString *check=[NSString stringWithFormat:@"Record%d.caf",countRecord];
    for (int i=0; i<[checkArray count]; i++) {
       
        if ([[checkArray objectAtIndex:i] isEqualToString:check]) {
       
            checkUpadte=YES;
           
        }
        else{
            checkUpadte=NO;
            i=[checkArray count];
        }
    }
   
    if (checkUpadte==NO) {
        // insert
        [appDel insertIntoDatabase:check];//[NSString stringWithFormat:@"Record%d.caf",countRecord ]];
    }
    else{
        // update
        [appDel updateDatabase:check];//[NSString stringWithFormat:@"Record%d.caf",countRecord ]];
       
    }
    //UISaveVideoAtPathToSavedPhotosAlbum(path,self, @selector(imageSavedToPhotosAlbum: didFinishSavingWithError: contextInfo:),self);   
   
  
    countRecord+=1;
    NSLog(@"stopRecording");
    [audioRecorder stop];
    NSLog(@"stopped");
}
- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    NSString *message;
    NSString *title;
    if (!error) {
       
        title = NSLocalizedString(@"Photo ", @"");
        message = NSLocalizedString(@"Photo Is Saved To Photo Gallary Successfully", @"");
    } else {
        title = NSLocalizedString(@"Photo Is Not Saved To Photo Gallary", @"");
        message = [error description];
    }
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
                                                    message:message
                                                   delegate:nil
                                          cancelButtonTitle:NSLocalizedString(@"ButtonOK", @"")
                                          otherButtonTitles:nil];
    [alert show];
    [alert release];
}

-(IBAction) playRecording
{
    NSLog(@"playRecording");
    // Init audio with playback capability
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
   
   // NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/Record1.caf", [[NSBundle mainBundle] resourcePath]]];
   // NSError *error;
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:tempFilePath error:&error];
    audioPlayer.numberOfLoops = 0;
    [audioPlayer play];
    NSLog(@"playing");
}

-(IBAction) stopPlaying
{
    NSLog(@"stopPlaying");
    [audioPlayer stop];
    NSLog(@"stopped");
}

- (void)dealloc
{
    [audioPlayer release];
    [audioRecorder release];
    [super dealloc];
}



/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (IBAction)  start_button_pressed{

    if(toggle)
    {
        toggle = NO;
        [actSpinner startAnimating];
        [btnStart setTitle:@"Stop Recording" forState: UIControlStateNormal ];   
        btnPlay.enabled = toggle;
        btnPlay.hidden = !toggle;
       
        //Begin the recording session.
        //Error handling removed.  Please add to your own code.
               
        //Setup the dictionary object with all the recording settings that this
        //Recording sessoin will use
        //Its not clear to me which of these are required and which are the bare minimum.
        //This is a good resource: http://www.totodotnet.net/tag/avaudiorecorder/
        NSMutableDictionary* recordSetting = [[NSMutableDictionary alloc] init];
        [recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
        [recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
        [recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
       
        //Now that we have our settings we are going to instanciate an instance of our recorder instance.
        //Generate a temp file for use by the recording.
        //This sample was one I found online and seems to be a good choice for making a tmp file that
        //will not overwrite an existing one.
        //I know this is a mess of collapsed things into 1 call.  I can break it out if need be.
        recordedTmpFile = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent: [NSString stringWithFormat: @"%.0f.%@", [NSDate timeIntervalSinceReferenceDate] * 1000.0, @"caf"]]];
        NSLog(@"Using File called: %@",recordedTmpFile);
        //Setup the recorder to use this file and record to it.
        recorder = [[ AVAudioRecorder alloc] initWithURL:recordedTmpFile settings:recordSetting error:&error];
        //Use the recorder to start the recording.
        //Im not sure why we set the delegate to self yet. 
        //Found this in antother example, but Im fuzzy on this still.
        [recorder setDelegate:self];
        //We call this to start the recording process and initialize
        //the subsstems so that when we actually say "record" it starts right away.
        [recorder prepareToRecord];
        //Start the actual Recording
        [recorder record];
        //There is an optional method for doing the recording for a limited time see
        //[recorder recordForDuration:(NSTimeInterval) 10]
       
    }
    else
    {
        toggle = YES;
        [actSpinner stopAnimating];
        [btnStart setTitle:@"Start Recording" forState:UIControlStateNormal ];
        btnPlay.enabled = toggle;
        btnPlay.hidden = !toggle;
       
        NSLog(@"Using File called: %@",recordedTmpFile);
        //Stop the recorder.
        [recorder stop];
    }
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
   
    // Release any cached data, images, etc that aren't in use.
}

-(IBAction) play_button_pressed{

    //The play button was pressed...
    //Setup the AVAudioPlayer to play the file that we just recorded.
    AVAudioPlayer * avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:recordedTmpFile error:&error];
    [avPlayer prepareToPlay];
    [avPlayer play];
   
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    //Clean up the temp file.
    NSFileManager * fm = [NSFileManager defaultManager];
    [fm removeItemAtPath:[recordedTmpFile path] error:&error];
    //Call the dealloc on the remaining objects.
    [recorder dealloc];
    recorder = nil;
    recordedTmpFile = nil;
}


@end
.xib
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
    <data>
        <int key="IBDocument.SystemTarget">784</int>
        <string key="IBDocument.SystemVersion">10K549</string>
        <string key="IBDocument.InterfaceBuilderVersion">1306</string>
        <string key="IBDocument.AppKitVersion">1038.36</string>
        <string key="IBDocument.HIToolboxVersion">461.00</string>
        <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
            <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
            <string key="NS.object.0">301</string>
        </object>
        <object class="NSArray" key="IBDocument.IntegratedClassDependencies">
            <bool key="EncodedWithXMLCoder">YES</bool>
            <string>IBUIButton</string>
            <string>IBUIActivityIndicatorView</string>
            <string>IBUIView</string>
            <string>IBProxyObject</string>
        </object>
        <object class="NSArray" key="IBDocument.PluginDependencies">
            <bool key="EncodedWithXMLCoder">YES</bool>
            <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
        </object>
        <object class="NSMutableDictionary" key="IBDocument.Metadata">
            <bool key="EncodedWithXMLCoder">YES</bool>
            <object class="NSArray" key="dict.sortedKeys" id="0">
                <bool key="EncodedWithXMLCoder">YES</bool>
            </object>
            <reference key="dict.values" ref="0"/>
        </object>
        <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
            <bool key="EncodedWithXMLCoder">YES</bool>
            <object class="IBProxyObject" id="372490531">
                <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
                <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
            </object>
            <object class="IBProxyObject" id="843779117">
                <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
                <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
            </object>
            <object class="IBUIView" id="774585933">
                <reference key="NSNextResponder"/>
                <int key="NSvFlags">274</int>
                <object class="NSMutableArray" key="NSSubviews">
                    <bool key="EncodedWithXMLCoder">YES</bool>
                    <object class="IBUIButton" id="1048870925">
                        <reference key="NSNextResponder" ref="774585933"/>
                        <int key="NSvFlags">292</int>
                        <string key="NSFrame">{{20, 20}, {280, 37}}</string>
                        <reference key="NSSuperview" ref="774585933"/>
                        <reference key="NSNextKeyView" ref="491348703"/>
                        <bool key="IBUIOpaque">NO</bool>
                        <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
                        <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
                        <int key="IBUIContentHorizontalAlignment">0</int>
                        <int key="IBUIContentVerticalAlignment">0</int>
                        <object class="NSFont" key="IBUIFont" id="265054451">
                            <string key="NSName">Helvetica-Bold</string>
                            <double key="NSSize">15</double>
                            <int key="NSfFlags">16</int>
                        </object>
                        <int key="IBUIButtonType">1</int>
                        <string key="IBUINormalTitle">Begin Recording</string>
                        <object class="NSColor" key="IBUIHighlightedTitleColor" id="494537766">
                            <int key="NSColorSpace">3</int>
                            <bytes key="NSWhite">MQA</bytes>
                        </object>
                        <object class="NSColor" key="IBUINormalTitleColor">
                            <int key="NSColorSpace">1</int>
                            <bytes key="NSRGB">MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA</bytes>
                        </object>
                        <object class="NSColor" key="IBUINormalTitleShadowColor" id="423988075">
                            <int key="NSColorSpace">3</int>
                            <bytes key="NSWhite">MC41AA</bytes>
                        </object>
                    </object>
                    <object class="IBUIButton" id="531567224">
                        <reference key="NSNextResponder" ref="774585933"/>
                        <int key="NSvFlags">292</int>
                        <string key="NSFrame">{{20, 225}, {280, 37}}</string>
                        <reference key="NSSuperview" ref="774585933"/>
                        <reference key="NSNextKeyView" ref="100974320"/>
                        <bool key="IBUIOpaque">NO</bool>
                        <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
                        <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
                        <int key="IBUIContentHorizontalAlignment">0</int>
                        <int key="IBUIContentVerticalAlignment">0</int>
                        <reference key="IBUIFont" ref="265054451"/>
                        <int key="IBUIButtonType">1</int>
                        <string key="IBUINormalTitle">stop Recording</string>
                        <reference key="IBUIHighlightedTitleColor" ref="494537766"/>
                        <object class="NSColor" key="IBUINormalTitleColor">
                            <int key="NSColorSpace">1</int>
                            <bytes key="NSRGB">MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA</bytes>
                        </object>
                        <reference key="IBUINormalTitleShadowColor" ref="423988075"/>
                    </object>
                    <object class="IBUIButton" id="100974320">
                        <reference key="NSNextResponder" ref="774585933"/>
                        <int key="NSvFlags">292</int>
                        <string key="NSFrame">{{20, 295}, {280, 37}}</string>
                        <reference key="NSSuperview" ref="774585933"/>
                        <reference key="NSNextKeyView"/>
                        <bool key="IBUIOpaque">NO</bool>
                        <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
                        <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
                        <int key="IBUIContentHorizontalAlignment">0</int>
                        <int key="IBUIContentVerticalAlignment">0</int>
                        <reference key="IBUIFont" ref="265054451"/>
                        <int key="IBUIButtonType">1</int>
                        <string key="IBUINormalTitle">Play</string>
                        <reference key="IBUIHighlightedTitleColor" ref="494537766"/>
                        <object class="NSColor" key="IBUINormalTitleColor">
                            <int key="NSColorSpace">1</int>
                            <bytes key="NSRGB">MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA</bytes>
                        </object>
                        <reference key="IBUINormalTitleShadowColor" ref="423988075"/>
                    </object>
                    <object class="IBUIActivityIndicatorView" id="491348703">
                        <reference key="NSNextResponder" ref="774585933"/>
                        <int key="NSvFlags">-2147483356</int>
                        <string key="NSFrame">{{141, 65}, {37, 37}}</string>
                        <reference key="NSSuperview" ref="774585933"/>
                        <reference key="NSNextKeyView" ref="853401572"/>
                        <bool key="IBUIOpaque">NO</bool>
                        <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
                        <bool key="IBUIUserInteractionEnabled">NO</bool>
                        <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
                        <int key="IBUIStyle">0</int>
                    </object>
                    <object class="IBUIButton" id="853401572">
                        <reference key="NSNextResponder" ref="774585933"/>
                        <int key="NSvFlags">-2147483356</int>
                        <string key="NSFrame">{{20, 122}, {280, 37}}</string>
                        <reference key="NSSuperview" ref="774585933"/>
                        <reference key="NSNextKeyView" ref="531567224"/>
                        <bool key="IBUIOpaque">NO</bool>
                        <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
                        <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
                        <bool key="IBUIEnabled">NO</bool>
                        <int key="IBUIContentHorizontalAlignment">0</int>
                        <int key="IBUIContentVerticalAlignment">0</int>
                        <reference key="IBUIFont" ref="265054451"/>
                        <int key="IBUIButtonType">1</int>
                        <string key="IBUINormalTitle">Play Recording</string>
                        <reference key="IBUIHighlightedTitleColor" ref="494537766"/>
                        <object class="NSColor" key="IBUINormalTitleColor">
                            <int key="NSColorSpace">1</int>
                            <bytes key="NSRGB">MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA</bytes>
                        </object>
                        <reference key="IBUINormalTitleShadowColor" ref="423988075"/>
                    </object>
                </object>
                <string key="NSFrame">{{0, 20}, {320, 460}}</string>
                <reference key="NSSuperview"/>
                <reference key="NSNextKeyView" ref="1048870925"/>
                <object class="NSColor" key="IBUIBackgroundColor">
                    <int key="NSColorSpace">3</int>
                    <bytes key="NSWhite">MC43NQA</bytes>
                    <object class="NSColorSpace" key="NSCustomColorSpace">
                        <int key="NSID">2</int>
                    </object>
                </object>
                <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
                <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
                <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
            </object>
        </object>
        <object class="IBObjectContainer" key="IBDocument.Objects">
            <object class="NSMutableArray" key="connectionRecords">
                <bool key="EncodedWithXMLCoder">YES</bool>
                <object class="IBConnectionRecord">
                    <object class="IBCocoaTouchOutletConnection" key="connection">
                        <string key="label">view</string>
                        <reference key="source" ref="372490531"/>
                        <reference key="destination" ref="774585933"/>
                    </object>
                    <int key="connectionID">7</int>
                </object>
                <object class="IBConnectionRecord">
                    <object class="IBCocoaTouchOutletConnection" key="connection">
                        <string key="label">actSpinner</string>
                        <reference key="source" ref="372490531"/>
                        <reference key="destination" ref="491348703"/>
                    </object>
                    <int key="connectionID">15</int>
                </object>
                <object class="IBConnectionRecord">
                    <object class="IBCocoaTouchOutletConnection" key="connection">
                        <string key="label">btnStart</string>
                        <reference key="source" ref="372490531"/>
                        <reference key="destination" ref="1048870925"/>
                    </object>
                    <int key="connectionID">16</int>
                </object>
                <object class="IBConnectionRecord">
                    <object class="IBCocoaTouchEventConnection" key="connection">
                        <string key="label">startRecording</string>
                        <reference key="source" ref="1048870925"/>
                        <reference key="destination" ref="372490531"/>
                        <int key="IBEventType">7</int>
                    </object>
                    <int key="connectionID">20</int>
                </object>
                <object class="IBConnectionRecord">
                    <object class="IBCocoaTouchEventConnection" key="connection">
                        <string key="label">stopRecording</string>
                        <reference key="source" ref="531567224"/>
                        <reference key="destination" ref="372490531"/>
                        <int key="IBEventType">7</int>
                    </object>
                    <int key="connectionID">24</int>
                </object>
                <object class="IBConnectionRecord">
                    <object class="IBCocoaTouchEventConnection" key="connection">
                        <string key="label">playRecording</string>
                        <reference key="source" ref="853401572"/>
                        <reference key="destination" ref="372490531"/>
                        <int key="IBEventType">7</int>
                    </object>
                    <int key="connectionID">26</int>
                </object>
                <object class="IBConnectionRecord">
                    <object class="IBCocoaTouchEventConnection" key="connection">
                        <string key="label">playRecording</string>
                        <reference key="source" ref="100974320"/>
                        <reference key="destination" ref="372490531"/>
                        <int key="IBEventType">7</int>
                    </object>
                    <int key="connectionID">29</int>
                </object>
            </object>
            <object class="IBMutableOrderedSet" key="objectRecords">
                <object class="NSArray" key="orderedObjects">
                    <bool key="EncodedWithXMLCoder">YES</bool>
                    <object class="IBObjectRecord">
                        <int key="objectID">0</int>
                        <reference key="object" ref="0"/>
                        <reference key="children" ref="1000"/>
                        <nil key="parent"/>
                    </object>
                    <object class="IBObjectRecord">
                        <int key="objectID">-1</int>
                        <reference key="object" ref="372490531"/>
                        <reference key="parent" ref="0"/>
                        <string key="objectName">File's Owner</string>
                    </object>
                    <object class="IBObjectRecord">
                        <int key="objectID">-2</int>
                        <reference key="object" ref="843779117"/>
                        <reference key="parent" ref="0"/>
                    </object>
                    <object class="IBObjectRecord">
                        <int key="objectID">6</int>
                        <reference key="object" ref="774585933"/>
                        <object class="NSMutableArray" key="children">
                            <bool key="EncodedWithXMLCoder">YES</bool>
                            <reference ref="1048870925"/>
                            <reference ref="491348703"/>
                            <reference ref="853401572"/>
                            <reference ref="531567224"/>
                            <reference ref="100974320"/>
                        </object>
                        <reference key="parent" ref="0"/>
                    </object>
                    <object class="IBObjectRecord">
                        <int key="objectID">8</int>
                        <reference key="object" ref="1048870925"/>
                        <reference key="parent" ref="774585933"/>
                        <string key="objectName">Button - Begin Recording</string>
                    </object>
                    <object class="IBObjectRecord">
                        <int key="objectID">9</int>
                        <reference key="object" ref="491348703"/>
                        <reference key="parent" ref="774585933"/>
                    </object>
                    <object class="IBObjectRecord">
                        <int key="objectID">17</int>
                        <reference key="object" ref="853401572"/>
                        <reference key="parent" ref="774585933"/>
                    </object>
                    <object class="IBObjectRecord">
                        <int key="objectID">22</int>
                        <reference key="object" ref="531567224"/>
                        <reference key="parent" ref="774585933"/>
                        <string key="objectName">Button - Begin Recording</string>
                    </object>
                    <object class="IBObjectRecord">
                        <int key="objectID">27</int>
                        <reference key="object" ref="100974320"/>
                        <reference key="parent" ref="774585933"/>
                        <string key="objectName">Button - Begin Recording</string>
                    </object>
                </object>
            </object>
            <object class="NSMutableDictionary" key="flattenedProperties">
                <bool key="EncodedWithXMLCoder">YES</bool>
                <object class="NSArray" key="dict.sortedKeys">
                    <bool key="EncodedWithXMLCoder">YES</bool>
                    <string>-1.CustomClassName</string>
                    <string>-2.CustomClassName</string>
                    <string>17.IBPluginDependency</string>
                    <string>22.IBPluginDependency</string>
                    <string>27.IBPluginDependency</string>
                    <string>6.IBEditorWindowLastContentRect</string>
                    <string>6.IBPluginDependency</string>
                    <string>8.IBPluginDependency</string>
                    <string>9.IBPluginDependency</string>
                </object>
                <object class="NSMutableArray" key="dict.values">
                    <bool key="EncodedWithXMLCoder">YES</bool>
                    <string>record_audio_testViewController</string>
                    <string>UIResponder</string>
                    <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
                    <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
                    <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
                    <string>{{465, 298}, {320, 480}}</string>
                    <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
                    <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
                    <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
                </object>
            </object>
            <object class="NSMutableDictionary" key="unlocalizedProperties">
                <bool key="EncodedWithXMLCoder">YES</bool>
                <reference key="dict.sortedKeys" ref="0"/>
                <reference key="dict.values" ref="0"/>
            </object>
            <nil key="activeLocalization"/>
            <object class="NSMutableDictionary" key="localizations">
                <bool key="EncodedWithXMLCoder">YES</bool>
                <reference key="dict.sortedKeys" ref="0"/>
                <reference key="dict.values" ref="0"/>
            </object>
            <nil key="sourceID"/>
            <int key="maxID">29</int>
        </object>
        <object class="IBClassDescriber" key="IBDocument.Classes"/>
        <int key="IBDocument.localizationMode">0</int>
        <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
        <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
            <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
            <integer value="784" key="NS.object.0"/>
        </object>
        <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
            <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
            <integer value="3000" key="NS.object.0"/>
        </object>
        <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
        <int key="IBDocument.defaultPropertyAccessControl">3</int>
        <string key="IBCocoaTouchPluginVersion">301</string>
    </data>
</archive>





Thursday, 15 September 2011

Second Url FIle

// For IAd Banner View Demo

http://bees4honey.com/blog/tutorial/how-to-add-iad-banner-in-iphoneipad-app/

http://www.raywenderlich.com/1371/how-to-integrate-iad-into-your-iphone-app

All Kind of Demo

http://pragprog.com/titles/amiphd/source_code

// ITennis Game
http://www.icodeblog.com/2009/05/04/iphone-game-programming-tutorial-part-4-basic-game-audio/

//Loading Html file into webview with Image Src

  NSString *path =[[NSBundle mainBundle] pathForResource:[generalArray objectAtIndex:rowId] ofType:@"html"];
      
[webView loadRequest: [NSURLRequest requestWithURL: [NSURL fileURLWithPath:path isDirectory:NO]]];
 
//For the Content Mode of UIView etc,

http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/WindowsandViews/WindowsandViews.html



//For the slide view like the actual image is sliding by caBasic transition

 CABasicAnimation *theAnimation;
    theAnimation=[CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
    theAnimation.duration=1;
    theAnimation.repeatCount=2;
    theAnimation.autoreverses=YES;
    theAnimation.fromValue=[NSNumber numberWithFloat:0];
    theAnimation.toValue=[NSNumber numberWithFloat:-320];
    [self.view.layer addAnimation:theAnimation forKey:@"animateLayer"];


Appliction can become active in background code

http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/BackgroundExecution/BackgroundExecution.html

If you do not want your application to remain in the background when it is quit, you can explicitly opt out of the background execution model by adding the UIApplicationExitsOnSuspend key to your application’s Info.plist file and setting its value to YES. When an application opts out, it cycles between the not running, inactive, and active states and never enters the background or suspended states. When the user taps the Home button to quit the application, the applicationWillTerminate: method of the application delegate is called and the application has approximately five seconds to clean up and exit before it is terminated and moved back to the not running state.
Opting out of background execution may be preferable for certain types of applications. Specifically, if coding for the background may require adding significant complexity to your application, terminating the application may be a simpler solution. Also, if your application consumes a large amount of memory, the system might need to terminate your application quickly anyway to make room for other applications. Thus, opting to terminate, instead of switch to the background, might yield the same results and save you development time and effort.

Support for some types of background execution must be declared in advance by the application that uses them. An application declares this support by including the UIBackgroundModes key in its Info.plist file. Its value is an array that contains one or more strings with the following values:
  • audio. The application plays audible content to the user while in the background. (This includes streaming audio or video content using AirPlay.)
  • location. The application keeps users informed of their location, even while running in the background.
  • voip. The application provides the ability for the user to make phone calls using an Internet connection.
Each of the preceding values lets the system know that your application should be woken up at appropriate times to respond to relevant events. For example, an application that begins playing music and then moves to the background still needs execution time to fill the audio output buffers. Including the audio key tells the system frameworks that they should continue playing and make the necessary callbacks to the application at appropriate intervals. If the application does not include this key, any audio being played by the application stops when the application moves to the background.
In addition to the preceding keys, iOS provides two other ways to do work in the background:
  • Task completion—Applications can ask the system for extra time to complete a given task.
  • Local notifications—Applications can schedule local notifications to be delivered at a predetermined time.
For more information about how to initiate background tasks from your code, see “Implementing Long-Running Background Tasks.”

Implementing Long-Running Background Tasks

Applications can request permission to run in the background in order to manage specific services for the user. Such applications do not run continuously but are woken up by the system frameworks at appropriate times to perform work related to those services.

Tracking the User’s Location

There are several ways to track the user’s location in the background, some of which do not actually involve running regularly in the background:
  • Applications can register for significant location changes. (Recommended) The significant-change location service offers a low-power way to receive location data and is highly recommended for applications that do not need high-precision location data. With this service, location updates are generated only when the user’s location changes significantly; thus, it is ideal for social applications or applications that provide the user with noncritical, location-relevant information. If the application is suspended when an update occurs, the system wakes it up in the background to handle the update. If the application starts this service and is then terminated, the system relaunches the application automatically when a new location becomes available. This service is available in iOS 4 and later, only on devices that contain a cellular radio.
  • Applications can continue to use the standard location services. Although not intended for running indefinitely in the background, the standard location services are available in all versions of iOS and provide the usual updates while the application is running, including while running in the background. However, updates stop as soon as the application is suspended or terminated, and new location updates do not cause the application to be woken up or relaunched. This type of service is appropriate when location data is used primarily when the application is in the foreground.
  • An application can declare itself as needing continuous background location updates. An application that needs regular location updates, both in the foreground and background, should add the UIBackgroundModes key to its Info.plist file and set the value of this key to an array containing the location string. This option is intended for applications that provide specific services, such as navigation services, that involve keeping the user informed of his or her location at all times. The presence of the key in the application’s Info.plist file tells the system that it should allow the application to run as needed in the background.
You are encouraged to use the significant location change service or use the standard services sparingly. Location services require the active use of an iOS device’s onboard radio hardware. Running this hardware continuously can consume a significant amount of power. If your application does not need to provide precise and continuous location information to the user, it is best to use those services that minimize power consumption. Chief among these low-power services is the significant location change service introduced in iOS 4. This service provides periodic location updates and can even wake up a background application, or relaunch a terminated application, to deliver them.
For applications that require more precise location data at regular intervals, such as navigation applications, you need to declare the application as a continuous background application. This option is available for applications that truly need it, but it is the least desirable option because it increases power usage considerably.
For information about how to use each of the location services in your application, see Location Awareness Programming Guide.

Playing Background Audio

Applications that play audio can include the UIBackgroundModes key (with the value audio) in their Info.plist file to register as a background-audio application. This key is intended for use by applications that provide audible content to the user while in the background, such as music-player or streaming-audio applications. Applications that support audio or video playback over AirPlay should also include this key so that they continue streaming their content while in the background.
When the audio value is present, the system’s media frameworks automatically prevent your application from being suspended when it moves to the background. As long as it is playing audio or video content, the application continues to run in the background to support that content. However, if the application stops playing that audio or video, the system suspends it. Similarly, if the application does not include the appropriate key in its Info.plist file, the application becomes eligible for suspension immediately upon entering the background.
You can use any of the system audio frameworks to initiate the playback of background audio, and the process for using those frameworks is unchanged. (For video playback over AirPlay, you must use the Media Player framework to present your video.) Because your application is not suspended while playing media files, callbacks operate normally while your application is in the background. Your application should limit itself to doing only the work necessary to provide data for playback while in the background. For example, a streaming audio application would download any new data from its server and push the current audio samples out for playback. You should not perform any extraneous tasks that are unrelated to playing the content.
Because more than one application may support audio, the system limits which applications can play audio at any given time. The foreground application always has permission to play audio. In addition, one or more background applications may also be allowed to play some audio content depending on the configuration of their audio session object. Applications should always configure their audio session object appropriately and work carefully with the system frameworks to handle interruptions and other types of audio-related notifications. For information on how to configure your application’s audio session properly for background execution, see Audio Session Programming Guide.

Implementing a VoIP Application

A Voice over Internet Protocol (VoIP) application allows the user to make phone calls using an Internet connection instead of the device’s cellular service. Such an application needs to maintain a persistent network connection to its associated service so that it can receive incoming calls and other relevant data. Rather than keep VoIP applications awake all the time, the system allows them to be suspended and provides facilities for monitoring their sockets for them. When incoming traffic is detected, the system wakes up the VoIP application and returns control of its sockets to it.
To configure a VoIP application, you must do the following:
  1. Add the UIBackgroundModes key to your application’s Info.plist file. Set the value of this key to an array that includes the voip string.
  2. Configure one of the application’s sockets for VoIP usage.
  3. Before moving to the background, call the setKeepAliveTimeout:handler: method to install a handler to be executed periodically. Your application can use this handler to maintain its service connection.
  4. Configure your audio session to handle transitions to and from active use.
Including the voip value in the UIBackgroundModes key lets the system know that it should allow the application to run in the background as needed to manage its network sockets. An application with this key is also relaunched in the background immediately after system boot to ensure that the VoIP services are always available.
Most VoIP applications also need to be configured as background audio applications to deliver audio while in the background. Therefore, you should include both the audio and voip values to the UIBackgroundModes key. If you do not do this, your application cannot play audio while it is in the background. For more information about the UIBackgroundModes key, see Information Property List Key Reference.

Configuring Sockets for VoIP Usage

In order for your application to maintain a persistent connection while it is in the background, you must tag your application’s main communication socket specifically for VoIP usage. Tagging this socket tells the system that it should take over management of the socket when your application is suspended. The handoff itself is totally transparent to your application. And when new data arrives on the socket, the system wakes up the application and returns control of the socket so that the application can process the incoming data.
You need to tag only the socket you use for communicating with your VoIP service. This is the socket you use to receive incoming calls or other data relevant to maintaining your VoIP service connection. Upon receipt of incoming data, the handler for this socket needs to decide what to do. For an incoming call, you likely want to post a local notification to alert the user to the call. For other noncritical data, though, you might just process the data quietly and allow the system to put your application back into the suspended state.
In iOS, most sockets are managed using streams or other high-level constructs. To configure a socket for VoIP usage, the only thing you have to do beyond the normal configuration is add a special key that tags the interface as being associated with a VoIP service. Table 4-1 lists the stream interfaces and the configuration for each.
Table 4-1  Configuring stream interfaces for VoIP usage
InterfaceConfiguration
NSInputStream and NSOutputStreamFor Cocoa streams, use the setProperty:forKey: method to add the NSStreamNetworkServiceType property to the stream. The value of this property should be set to NSStreamNetworkServiceTypeVoIP.
NSURLRequestWhen using the URL loading system, use the setNetworkServiceType: method of your NSMutableURLRequest object to set the network service type of the request. The service type should be set to NSURLNetworkServiceTypeVoIP.
CFReadStreamRef and CFWriteStreamRefFor Core Foundation streams, use the CFReadStreamSetProperty or CFWriteStreamSetProperty function to add the kCFStreamNetworkServiceType property to the stream. The value for this property should be set to kCFStreamNetworkServiceTypeVoIP.
Because VoIP applications need to stay running in order to receive incoming calls, the system automatically relaunches the application if it exits with a nonzero exit code. (This type of exit could happen in cases where there is memory pressure and your application is terminated as a result.) However, terminating the application also releases all of its sockets, including the one used to maintain the VoIP service connection. Therefore, when the application is launched, it always needs to create its sockets from scratch.
For more information about configuring Cocoa stream objects, see Stream Programming Guide. For information about using URL requests, see URL Loading System Programming Guide. And for information about configuring streams using the CFNetwork interfaces, see CFNetwork Programming Guide.

Installing a Keep-Alive Handler

To prevent the loss of its connection, a VoIP application typically needs to wake up periodically and check in with its server. To facilitate this behavior, iOS lets you install a special handler using the setKeepAliveTimeout:handler: method of UIApplication. You typically install this handler in the applicationDidEnterBackground: method of your application delegate. Once installed, the system calls your handler at least once before the timeout interval expires, waking up your application as needed to do so.
Your keep-alive handler executes in the background and should return as quickly as possible. Handlers are given a maximum of 30 seconds to perform any needed tasks and return. If a handler has not returned after 30 seconds, the system terminates the application.
When installing your handler, specify the largest timeout value that is practical for your application’s needs. The minimum allowable interval for running your handler is 600 seconds and attempting to install a handler with a smaller timeout value will fail. Although the system promises to call your handler block before the timeout value expires, it does not guarantee the exact call time. To improve battery life, the system typically groups the execution of your handler with other periodic system tasks, thereby processing all tasks in one quick burst. As a result, your handler code must be prepared to run earlier than the actual timeout period you specified.

Configuring Your Application’s Audio Session

As with any background audio application, the audio session for a VoIP application must be configured properly to ensure the application works smoothly with other audio-based applications. Because audio playback and recording for a VoIP application are not used all the time, it is especially important that you create and configure your application’s audio session object only when it is needed. For example, you would create it to notify the user of an incoming call or while the user was actually on a call. As soon as the call ends, you would then release the audio session and give other audio applications the opportunity to play their audio.
For information about how to configure and manage an audio session for a VoIP application, see Audio Session Programming Guide.

Completing a Finite-Length Task in the Background

Any time before it is suspended, an application can call the beginBackgroundTaskWithExpirationHandler: method to ask the system for extra time to complete some long-running task in the background. If the request is granted, and if the application goes into the background while the task is in progress, the system lets the application run for an additional amount of time instead of suspending it. (The backgroundTimeRemaining property of the UIApplication object contains the amount of time the application has to run.)
You can use task completion to ensure that important but potentially long-running operations do not end abruptly when the user leaves the application. For example, you might use this technique to save user data to disk or finish downloading an important file from a network server. There are a couple of design patterns you can use to initiate such tasks:
  • Wrap any long-running critical tasks with beginBackgroundTaskWithExpirationHandler: and endBackgroundTask: calls. This protects those tasks in situations where your application is suddenly moved to the background.
  • Wait for your application delegate’s applicationDidEnterBackground: method to be called and start one or more tasks then.
All calls to the beginBackgroundTaskWithExpirationHandler: method must be balanced with a corresponding call to the endBackgroundTask: method. The endBackgroundTask: method lets the system know that the task is complete and that the application can now be suspended. Because applications are given only a limited amount of time to finish background tasks, you must call this method before time expires or the system will terminate your application. To avoid termination, you can also provide an expiration handler when starting a task and call the endBackgroundTask: method from there. (You can also check the value in the backgroundTimeRemaining property of the application object to see how much time is left.)
An application can have any number of tasks running at the same time. Each time you start a task, the beginBackgroundTaskWithExpirationHandler: method returns a unique identifier for the task. You must pass this same identifier to the endBackgroundTask: method when it comes time to end the task.
Listing 4-2 shows how to start a long-running task when your application transitions to the background. In this example, the request to start a background task includes an expiration handler just in case the task takes too long. The task itself is then submitted to a dispatch queue for asynchronous execution so that the applicationDidEnterBackground: method can return normally. The use of blocks simplifies the code needed to maintain references to any important variables, such as the background task identifier. The bgTask variable is a member variable of the class that stores a pointer to the current background task identifier.
Listing 4-2  Starting a background task at quit time
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UIApplication*    app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task.
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
In your own expiration handlers, you can include additional code needed to close out your task. However, any code you include must not take too long to execute. By the time your expiration handler is called, your application is already very close to its time limit. For this reason, perform only minimal cleanup of your state information and end the task.

Scheduling the Delivery of Local Notifications

The UILocalNotification class in UIKit provides a way to schedule the delivery of local notifications. Unlike push notifications, which require setting up a remote server, local notifications are scheduled by your application and executed on the current device. You can use this capability to achieve the following behaviors:
  • A time-based application can ask the system to post an alert at a specific time in the future. For example, an alarm clock application would use this alert to implement alarms.
  • An application running in the background can post a local notification to get the user’s attention.
To schedule the delivery of a local notification, create an instance of the UILocalNotification class, configure it, and schedule it using the methods of the UIApplication class. The local notification object contains information about the type of notification to deliver (sound, alert, or badge) and the time (when applicable) at which to deliver it. The methods of the UIApplication class provide options for delivering notifications immediately or at the scheduled time.
Listing 4-3 shows an example that schedules a single alarm using a date and time that is set by the user. This example configures only one alarm at a time and cancels the previous alarm before scheduling a new one. (Your own applications can have no more than 128 local notifications active at any given time, any of which can be configured to repeat at a specified interval.) The alarm itself consists of an alert box and a sound file that is played if the application is not running or is in the background when the alarm fires. If the application is active and therefore running in the foreground, the application delegate’s application:didReceiveLocalNotification: method is called instead.
Listing 4-3  Scheduling an alarm notification
- (void)scheduleAlarmForDate:(NSDate*)theDate
{
UIApplication* app = [UIApplication sharedApplication];
NSArray*    oldNotifications = [app scheduledLocalNotifications];
// Clear out the old notification before scheduling a new one.
if ([oldNotifications count] > 0)
[app cancelAllLocalNotifications];
// Create a new notification.
UILocalNotification* alarm = [[[UILocalNotification alloc] init] autorelease];
if (alarm)
{
alarm.fireDate = theDate;
alarm.timeZone = [NSTimeZone defaultTimeZone];
alarm.repeatInterval = 0;
alarm.soundName = @"alarmsound.caf";
alarm.alertBody = @"Time to wake up!";
[app scheduleLocalNotification:alarm];
}
}
Sound files used with local notifications have the same requirements as those used for push notifications. Custom sound files must be located inside your application’s main bundle and support one of the following formats: Linear PCM, MA4, ยต-Law, or a-Law. You can also specify the sound name default to play the default alert sound for the device. When the notification is sent and the sound is played, the system also triggers a vibration on devices that support it.