Wednesday, March 9, 2011

iAds Integration


Introduction


iAd allows your application to earn revenue by displaying advertisements to the user. Your application dedicates a portion of its user interface to display banner advertisements and in turn you receive revenue when users view or click those advertisements.
While you are developing your application, iAd sends test advertisements to help you verify your implementation is correct. To receive advertisements from iAd in a release application, you need to select the advertising network option for your application before publishing it.



KeyPoint

iAds are supported on ios 4.0 and above

Steps for iAds integration



1. First of all add iAd.framework as existing framework

2. In your .h file

add the below code,


#import <UIKit/UIKit.h>
#import <iAd/iAd.h>
@interface testViewController : UIViewController < ADBannerViewDelegate>{
id adView;
BOOL adBannerViewIsVisible;
}
@property(nonatomic, retain) IBOutlet id adView;
- (void)fixupAdView;
- (int)getBannerHeight;
- (void)createAdBannerView;
@end
3) In your .m file

add the below code,


@synthesize adView;

4) In your viewDidLoad method, add the below code
[self createAdBannerView];

5) In your .m flee also add the below code,



#pragma mark -
#pragma mark iAdMethods
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
if (adBannerViewIsVisible) {        
adBannerViewIsVisible = NO;
[self fixupAdView];
}
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner {
if (!adBannerViewIsVisible) {                
adBannerViewIsVisible = YES;
[self fixupAdView];
}
}
- (void)createAdBannerView {
Class classAdBannerView = NSClassFromString(@"ADBannerView");
if (classAdBannerView != nil) {
self.adView = [[[classAdBannerView alloc] 
initWithFrame:CGRectZero] autorelease];
[adView setRequiredContentSizeIdentifiers:[NSSet setWithObjects: 
ADBannerContentSizeIdentifier320x50, nil]];
[adView setCurrentContentSizeIdentifier:ADBannerContentSizeIdentifier320x50];
[adView setFrame:CGRectMake(0.0, 436.0, 320.0, 50.0)];
[adView setDelegate:self];
[self.view addSubview:adView];        
}
}
- (int)getBannerHeight {
return 50;
}
- (void)fixupAdView {
if (adView != nil) {        
[adView setCurrentContentSizeIdentifier: ADBannerContentSizeIdentifier320x50];
if (adBannerViewIsVisible) {
CGRect adBannerViewFrame = [adView frame];
adBannerViewFrame.origin.x = 0;
adBannerViewFrame.origin.y = 386;
[adView setFrame:adBannerViewFrame];
} 
else {
[UIView beginAnimations:@"fixupViews" context:nil];
CGRect adBannerViewFrame = [adView frame];
adBannerViewFrame.origin.x = 0;
adBannerViewFrame.origin.y = 436;
[adView setFrame:adBannerViewFrame];
[UIView commitAnimations];
}
}   
}


Tuesday, February 22, 2011

Using SQLite in an iPhone App






This entry describes using SQLite in an iPhone app for displaying , updating & deleting data in the database

1.First of all create a database using SQLite Database browser


Add the database to your project.Also add libsqlite3.0.dylib to your frameworks




2.  In the AppDelegate class add the below code,

- (void)applicationDidFinishLaunching:(UIApplication *)application { 
[self createEditableCopyOfDatabaseIfNeeded];
[self initializeDatabase];

}

-(void) createEditableCopyOfDatabaseIfNeeded{
BOOL success;
NSFileManager *fileManager=[NSFileManager defaultManager];
NSError *error;
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory= [paths objectAtIndex:0];
NSString *writableDBPath= [documentsDirectory stringByAppendingPathComponent:@"testt.sqlite"];
success= [fileManager fileExistsAtPath:writableDBPath ];
if(success) return;
NSString *defaultDBPath=[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"lovetarot.sqlite"];
success=[fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error: &error];
}


-(void) initializeDatabase{
NSMutableArray *todoArray=[[NSMutableArray alloc] init];
self.todos=todoArray;
[todoArray release];
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory= [paths objectAtIndex:0];
NSString *path=[documentsDirectory stringByAppendingPathComponent:@"testt.sqlite"];
if(sqlite3_open ([path UTF8String], &database ) ==SQLITE_OK){
const char *sql="SELECT primaryKey FROM journals";
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(database, sql, -1, &statement ,NULL) ==SQLITE_OK){
while(sqlite3_step(statement) == SQLITE_ROW ){
int primaryKey=sqlite3_column_int(statement,0);
//double date=sqlite3_column_int(statement,1);
GoddessInspiration *td=[[GoddessInspiration alloc] initWithPrimaryKey:primaryKey database:database];
[todos addObject:td];
[td release];
}
}
sqlite3_finalize(statement);
}else{
sqlite3_close(database);
}
}

3. Now , create NSObject class, lets name it test

4. In test.h add the below code,

#import <Foundation/Foundation.h>
#import <sqlite3.h>

@interface test : NSObject {
sqlite3 *database;
NSInteger primaryKey;
NSString *text;
NSString  *desc;
NSString *imagePath, *title;
double journalDate;
NSInteger priority;
NSInteger status;
BOOL dirty;
}


@property(assign,nonatomic,readonly) NSInteger primaryKey;
@property (nonatomic,retain) NSString *text;
@property (nonatomic,assign) double journalDate;
@property (nonatomic,retain) NSString *desc;
@property (nonatomic,retain) NSString *imagePath;
@property (nonatomic,retain) NSString *title;
@property (nonatomic)NSInteger priority;
@property (nonatomic)NSInteger status;

-(id)initWithPrimaryKey:(NSInteger )pk database:(sqlite3 *)db;


@end
5. In the test.m add the below code

#import "test.h"

static sqlite3_stmt *init_statement=nil;

@implementation test

@synthesize primaryKey,text,priority,status, desc,imagePath,title,journalDate;

-(id)initWithPrimaryKey:(NSInteger )pk database:(sqlite3 *)db{
  if(self = [super init] ) {
primaryKey=pk;
database =db;
if(init_statement ==nil){
const char *sql=" SELECT date,description,title,imagePath FROM journals WHERE primaryKey=? ";
if (sqlite3_prepare_v2(database, sql, -1, &init_statement, NULL) != SQLITE_OK){
NSAssert1(0,@"Error: Failed to prepare statement with message '%s'.",sqlite3_errmsg(database));
}
}
sqlite3_bind_int(init_statement,1,primaryKey);
if(sqlite3_step(init_statement) == SQLITE_ROW) {
//double journalDate;
self.journalDate=sqlite3_column_double(init_statement,0);
if(sqlite3_column_text(init_statement,1) != NULL)
self.desc=[ NSString stringWithUTF8String:(char *) sqlite3_column_text(init_statement,1)];
if(sqlite3_column_text(init_statement,3) != NULL)
self.imagePath=[NSString stringWithUTF8String:(char *) sqlite3_column_text(init_statement,3)];
if(sqlite3_column_text(init_statement,2) != NULL)
self.title=[NSString stringWithUTF8String:(char *) sqlite3_column_text(init_statement,2)];
}
else{
self.text=@"Nothing";
}
sqlite3_reset(init_statement);
}
return self;
}

@end


    Now displaying the data stored in the database
    

    test *temptest = (test *)[appDelegate.todos objectAtIndex:someindex];
NSInteger temp=temptest.primaryKey;

    temp will contain the value of primary key column, similarly you can get for other columns


  Deleting an entry from the database
1. In the app delegate add the below code,


-(void)removeEntry:(test *)tarot{

NSUInteger index=[todos indexOfObject:tarot];
if(index == NSNotFound) return;
[tarot deleteFromDatabase:database];
[todos removeObject:tarot];
}


2. In the test.m add the below code

bore @ implementation
static sqlite3_stmt *delete_statement=nil;

after @implementation



-(void)deleteFromDatabase:(sqlite3 *)database1{
if(delete_statement == nil){
const char *sql="DELETE FROM journals WHERE primaryKey=?";
if (sqlite3_prepare_v2(database1, sql, -1, &delete_statement, NULL) != SQLITE_OK){
NSAssert1(0,@"Error: Failed to prepare statement with message '%s'.",sqlite3_errmsg(database1));
}
}
sqlite3_bind_int(delete_statement,1, self.primaryKey);
int success = sqlite3_step(delete_statement);
if(success != SQLITE_DONE){
NSAssert1(0,@"Error: failed to save priority with message '%s'.",sqlite3_errmsg(database1));
}
sqlite3_reset(delete_statement);
}


3.Wherever you want to delete, add the below code

   test *tarot=[appDelegate.todos objectAtIndex:someindex];
   [appDelegate removeEntry:tarot];



 Inserting data into the database
1. In the app delegate file add the below code

-(void)addEntry:(test *)tarot {
[tarot insertNewTodoIntoDatabase:database];
[todos addObject:tarot];
}


2.In the test.m add the below code

before @ implementation
static sqlite3_stmt *insert_statement=nil;

after @implementation

-(NSInteger)insertNewTodoIntoDatabase:(sqlite3 *)database1{
database=database1;
if(insert_statement ==nil){
//NSString temp=td.textField.text
static char *sql="INSERT INTO journals (date,description,title,imagePath) VALUES (?,?,?,?)";
//static char *sql="INSERT INTO todo (text) VALUES (td.textFld.text)";
        if (sqlite3_prepare_v2(database1, sql, -1, &insert_statement, NULL) != SQLITE_OK){
NSAssert1(0,@"Error: Failed to prepare statement with message '%s'.",sqlite3_errmsg(database1));
}
}
sqlite3_bind_double(insert_statement,1,journalDate);
sqlite3_bind_text(insert_statement,2,[self.desc UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(insert_statement,3,[self.title UTF8String], -1, SQLITE_TRANSIENT); 
sqlite3_bind_text(insert_statement,4,[self.imagePath UTF8String], -1, SQLITE_TRANSIENT);
int success=sqlite3_step(insert_statement);
sqlite3_reset(insert_statement);
if(success != SQLITE_ERROR){
primaryKey = sqlite3_last_insert_rowid(database1);
return primaryKey;
}
NSAssert1(0,@"Error: failed to insert into the database with message '%s'.",sqlite3_errmsg(database1));
return -1;
}

3 Now, wherever you want to add the data into database add the below code

 test *test1 = [[test alloc] init];
[test1 setJournalDate:milliSecs];
[test1 setTitle:self.titleTextField.text];
[test1 setDesc:self.descrpnText.text];
[test1 setImagePath:@"NO"];
[appDelegate addEntry:test1];


 Updating data into the database
1.In the app delegate class, add the below code
-(void)updateEntry:(test *)tarot {
NSUInteger index=[todos indexOfObject:tarot];
if(index == NSNotFound) return;
[tarot updateIntoDatabase:database];
}
2. In the test.m add the below code
before @ implementation
static sqlite3_stmt *update_statement=nil;

after @implementation

-(NSInteger)updateIntoDatabase:(sqlite3 *)database1{
database=database1;
if(update_statement == nil){
const char *sql="UPDATE journals SET date=?, description=?, title=?, imagePath=? WHERE primaryKey=?";
if (sqlite3_prepare_v2(database1, sql, -1, &update_statement, NULL) != SQLITE_OK){
NSAssert1(0,@"Error: Failed to prepare statement with message '%s'.",sqlite3_errmsg(database1));
}
}
sqlite3_bind_int(update_statement,5, self.primaryKey);
sqlite3_bind_double(update_statement,1,journalDate);
sqlite3_bind_text(update_statement,2,[self.desc UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(update_statement,3,[self.title UTF8String], -1, SQLITE_TRANSIENT); 
sqlite3_bind_text(update_statement,4,[self.imagePath UTF8String], -1, SQLITE_TRANSIENT); 
int success = sqlite3_step(update_statement);
if(success != SQLITE_DONE){
NSAssert1(0,@"Error: failed to save with message '%s'.",sqlite3_errmsg(database1));
}
sqlite3_reset(update_statement);
return self.primaryKey;
}

3. Now after editing the entry , you need to save it in the database for that add the below code

 test *test1=[appDelegate.todos objectAtIndex:(someindex)];
[test1 setJournalDate:milliSecs];
[test1 setTitle:self.titleTextField.text];
[test1 setDesc:self.descrpnText.text];
[test1 setImagePath:imageValue];
[appDelegate updateTarot:test1];

Monday, February 21, 2011

Embedding youtube video in a webview


This post describes how you can embed you tube video in a webView which is in a table cell & on row selection autoplay youtube video

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

UIWebView  *wbView = (UIWebView *)[cell.contentView viewWithTag:1];
NSString *embedHTML = @"\
<html><head>\
<style type=\"text/css\">\
body {\
background-color: transparent;\
color: white;\
}\
</style>\
</head><body style=\"margin:0\">\
<embed id=\"yt\" src=\"%@\" type=\"application/x-shockwave-flash\" \
width=\"%0.0f\" height=\"%0.0f\"></embed>\
</body></html>";
NSString *html = [NSString stringWithFormat:embedHTML,url, 64.0, 64.0];
[wbView loadHTMLString:html baseURL:nil];



}

 "url" is the youtube video url


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [category_table cellForRowAtIndexPath:indexPath];
UIWebView  *wbView = (UIWebView *)[cell.contentView viewWithTag:1];
UIButton *btn = [self findButtonInView:wbView];
[btn sendActionsForControlEvents:UIControlEventTouchUpInside];
}


// detecting the play button on the you tube video thumbnail

- (UIButton *)findButtonInView:(UIView *)view {
UIButton *button = nil;
if ([view isMemberOfClass:[UIButton class]]) {
return (UIButton *)view;
}
if (view.subviews && [view.subviews count] > 0) {
for (UIView *subview in view.subviews) {
button = [self findButtonInView:subview];
if (button) return button;
}
}
return button;
}


- (void)webViewDidFinishLoad:(UIWebView *)_webView {
UIButton *button = [self findButtonInView:_webView];
[button sendActionsForControlEvents:UIControlEventTouchUpInside];
}


Displaying images from server in a table cell in a thread


We mostly use this concept when we need to load many images from server .Using this concept, the main Thread does not gets blocked till each image is loaded & user can interact with the UI. However, threading is used when you don't want your main thread to block till your aspected task is completed. 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

UIImageView *imgView= (UIImageView *)[cell.contentView viewWithTag:IMAGE_TAG];
id object = [imageDict objectForKey:[NSString stringWithFormat:@"%i,%i", indexPath.section, indexPath.row]];
if(!object){
[NSThread detachNewThreadSelector:@selector(displayingSmallImage:) toTarget:self withObject:indexPath];
}
else
{
if(![object isKindOfClass:[NSNull class]]){
UIImage *img = (UIImage *)object;
imgView.image = img;
}
}

}


imageDict is a global NSMutableDictionary


- (void) displayingSmallImage:(NSIndexPath *)indexPath{

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSString *imageUrl = [url to be used for fetching image from the server];
imageUrl = [(NSString *)CFURLCreateStringByAddingPercentEscapes(nil, (CFStringRef)imageUrl, NULL, NULL, kCFStringEncodingUTF8)autorelease];
NSURL *url = [NSURL URLWithString:imageUrl];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];

if(image){
[imageDict setObject:image forKey:[NSString stringWithFormat:@"%i,%i",indexPath.section,indexPath.row]];
}
else{
[imageDict setObject:[NSNull null] forKey:[NSString stringWithFormat:@"%i,%i",indexPath.section,indexPath.row]];
}

[self performSelectorOnMainThread:@selector(setImageInCell:) withObject:indexPath waitUntilDone:NO];
[pool release];

}


- (void)setImageInCell:(NSIndexPath *)indexPath{

[tableView_meals reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
}

Programmatically image resizing in an iPhone App




Resizing Image

UIImage *image = [entry videoImage];
UIImage *tempImage = nil;
CGSize targetSize = CGSizeMake(196,110);
UIGraphicsBeginImageContext(targetSize);
CGRect thumbnailRect = CGRectMake(0, 0, 0, 0);
thumbnailRect.origin = CGPointMake(0.0,0.0);
thumbnailRect.size.width  = targetSize.width;
thumbnailRect.size.height = targetSize.height;
[image drawInRect:thumbnailRect];
tempImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();


Now, you can use tempImage ( resized Image ) 

Playing video stored on a server in an iPhone App


- (void)viewDidLoad {

[super viewDidLoad];
[self playVideo:@"test url" frame:CGRectMake(20, 70, 280, 250)];
}


- (void)playVideo:(NSString *)urlString frame:(CGRect)frame {
NSString *embedHTML = @"\
<html><head>\
<style type=\"text/css\">\
body {\
background-color: transparent;\
color: white;\
}\
</style>\
<script>\
function load(){document.getElementById(\"yt\").play();}\
</script>\
</head><body onload=\"load()\"style=\"margin:0\">\
<video id=\"yt\" src=\"%@\" \
width=\"%0.0f\" height=\"%0.0f\" autoplay controls></video>\
</body></html>";
NSString *html = [NSString stringWithFormat:embedHTML, urlString, frame.size.width, frame.size.height];
UIWebView *videoView = [[UIWebView alloc] initWithFrame:frame];
[videoView loadHTMLString:html baseURL:nil];
[self.view addSubview:videoView];
[videoView release];
NSLog(@"%@",html);
}