Manthan
Manthan

Reputation: 3914

Set Action on Local Notification in iphone SDK

In my app, i scheduled Local Notification on my first view Controller. It works fine. To set the action on "View" button my code is as below:

//AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotif =
    [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
    if (localNotif)
    {
// did something Here when app launch by View button of notification
// added row in Db
}  
    return YES;
}

- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif
{

    // Handle the notificaton when the app is running
    NSLog(@"Recieved Notification %@",notif);

    app.applicationIconBadgeNumber=notif.applicationIconBadgeNumber++;
}

Question: It works fine for the first time only.

But for the second time, the notification is showing but the row is not added in my DB

// Edited

I want to give some action when user presses the button "View".

How can I identify that action?

edited

- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif
{


    // Handle the notificaton when the app is running
    NSLog(@"Recieved Notification %@",notif);

    app.applicationIconBadgeNumber=notif.applicationIconBadgeNumber++;

    UIApplicationState state = [app applicationState];
    if (state == UIApplicationStateInactive) {
        // Application was in the background when notification
        // was delivered.

        [self localNotif];

    }


}

- (void) localNotif
{

    [self databaseOpen];
    NSString *maxIdPt = [NSString stringWithFormat:@"select Max(id) from Points"];
    NSLog(@"Max id from points table %@",maxIdPt);
    NSMutableArray *p1 = [[NSMutableArray alloc]init];
    p1 = [[[database executeQuery:maxIdPt]mutableCopy]retain];


    int p=[[[p1 objectAtIndex:0]valueForKey:@"Max(id)"]intValue];
    NSLog(@"%d",p);


    NSString *maxPt = [NSString stringWithFormat:@"select Points from Points where id = %d",p];
    NSLog(@"Maxp %@",maxPt);
    NSMutableArray * p2 = [[NSMutableArray alloc]init];
    p2 =[[[database executeQuery:maxPt]mutableCopy]retain];

    int k = [[[p2 objectAtIndex:0]valueForKey:@"Points"]intValue];
    NSLog(@"Points %d",k);

    k = k + 250;

    NSLog(@"%d",k);


    NSString *mtpoints = [NSString stringWithFormat:@"insert into Points(Points) values (%d)",k];
    NSLog(@" lbl Points are %@",mtpoints);
    NSMutableArray * m1 = [[NSMutableArray alloc]init];
    m1 = [[[database executeQuery:mtpoints]mutableCopy]retain];
    [database close];


}

The same method i called in application didFinishLaunchingWithOptions

First time the score is updated but second time it doesn't. Even the notification is not shown.

Upvotes: 0

Views: 3668

Answers (2)

2014
2014

Reputation: 119

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {


        sk = [[SKDatabase alloc] init];
        NSString *db = @"MindEditor.db";
        [sk initWithDynamicFile:db];
        userid=@"0";
    }


   SKDatabase.h


//
//  SKDatabase.h
//  Version 1.1
//
//  Created by Shannon Appelcline on 9/11/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

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

@protocol SKDatabaseDelegate <NSObject>
@optional
- (void)databaseTableWasUpdated:(NSString *)table;
@end

@interface SKDatabase : NSObject {

    id<SKDatabaseDelegate> delegate;
    sqlite3 *dbh;
    BOOL dynamic;
}

@property (assign) id<SKDatabaseDelegate> delegate;
@property sqlite3 *dbh;
@property BOOL dynamic;

- (id)initWithFile:(NSString *)dbFile;
- (id)initWithDynamicFile:(NSString *)dbFile;
- (void)close;

- (sqlite3_stmt *)prepare:(NSString *)sql;

- (id)lookupColForSQL:(NSString *)sql;
- (NSDictionary *)lookupRowForSQL:(NSString *)sql;
- (NSArray *)lookupAllForSQL:(NSString *)sql;

- (int)lookupCountWhere:(NSString *)where forTable:(NSString *)table;
- (int)lookupMax:(NSString *)key Where:(NSString *)where forTable:(NSString *)table;
- (int)lookupSum:(NSString *)key Where:(NSString *)where forTable:(NSString *)table;

- (void)insertArray:(NSArray *)dbData forTable:(NSString *)table;
- (void)insertDictionary:(NSDictionary *)dbData forTable:(NSString *)table;

- (void)updateArray:(NSArray *)dbData forTable:(NSString *)table;
- (void)updateArray:(NSArray *)dbData forTable:(NSString *)table where:(NSString *)where;
- (void)updateDictionary:(NSDictionary *)dbData forTable:(NSString *)table;
- (void)updateDictionary:(NSDictionary *)dbData forTable:(NSString *)table where:(NSString *)where;
- (void)updateSQL:(NSString *)sql forTable:(NSString *)table;

- (void)deleteWhere:(NSString *)where forTable:(NSString *)table;

- (BOOL)runDynamicSQL:(NSString *)sql forTable:(NSString *)table;

@end

   SKDatabase.m




//
//  SKDatabase.m
//  Version 1.1
//
//  Created by Shannon Appelcline on 9/11/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "SKDatabase.h"

@implementation SKDatabase

@synthesize delegate;
@synthesize dbh;
@synthesize dynamic;

// Two ways to init: one if you're just SELECTing from a database, one if you're UPDATing
// and or INSERTing

- (id)initWithFile:(NSString *)dbFile {
    if (self = [super init]) {

        NSString *paths = [[NSBundle mainBundle] resourcePath];
        NSString *path = [paths stringByAppendingPathComponent:dbFile];

        int result = sqlite3_open([path UTF8String], &dbh);
        NSAssert1(SQLITE_OK == result, NSLocalizedStringFromTable(@"Unable to open the sqlite database (%@).", @"Database", @""), [NSString stringWithUTF8String:sqlite3_errmsg(dbh)]); 
        self.dynamic = NO;
    }

    return self;    
}

- (id)initWithDynamicFile:(NSString *)dbFile {
    if (self = [super init]) {

        NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *docDir = [docPaths objectAtIndex:0];
        NSString *docPath = [docDir stringByAppendingPathComponent:dbFile];

        NSFileManager *fileManager = [NSFileManager defaultManager];

        if (![fileManager fileExistsAtPath:docPath]) {

            NSString *origPaths = [[NSBundle mainBundle] resourcePath];
            NSString *origPath = [origPaths stringByAppendingPathComponent:dbFile];

            NSError *error;
            int success = [fileManager copyItemAtPath:origPath toPath:docPath error:&error];            
            NSAssert1(success,[NSString stringWithString:@"Failed to copy database into dynamic location"],error);
        }
        int result = sqlite3_open([docPath UTF8String], &dbh);
        NSAssert1(SQLITE_OK == result, NSLocalizedStringFromTable(@"Unable to open the sqlite database (%@).", @"Database", @""), [NSString stringWithUTF8String:sqlite3_errmsg(dbh)]); 
        self.dynamic = YES;
    }

    return self;    
}

// Users should never need to call prepare

- (sqlite3_stmt *)prepare:(NSString *)sql {

    const char *utfsql = [sql UTF8String];

    sqlite3_stmt *statement;

    if (sqlite3_prepare([self dbh],utfsql,-1,&statement,NULL) == SQLITE_OK) {
        return statement;
    } else {
        return 0;
    }
}

// Three ways to lookup results: for a variable number of responses, for a full row
// of responses, or for a singular bit of data

- (NSArray *)lookupAllForSQL:(NSString *)sql {
    sqlite3_stmt *statement;
    id result;
    NSMutableArray *thisArray = [NSMutableArray arrayWithCapacity:4];
    if (statement = [self prepare:sql]) {
        while (sqlite3_step(statement) == SQLITE_ROW) { 
            NSMutableDictionary *thisDict = [NSMutableDictionary dictionaryWithCapacity:4];
            for (int i = 0 ; i < sqlite3_column_count(statement) ; i++) 
            {
                if (sqlite3_column_decltype(statement,i) != NULL &&
                    strcasecmp(sqlite3_column_decltype(statement,i),"Boolean") == 0)
                {
                    result = [NSNumber numberWithBool:(BOOL)sqlite3_column_int(statement,i)];
                } 
                else if (sqlite3_column_type(statement, i) == SQLITE_TEXT)
                {
                    result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)];
                } 
                else if 
                    (sqlite3_column_type(statement,i) == SQLITE_INTEGER)
                {
                    result = [NSNumber numberWithInt:(int)sqlite3_column_int(statement,i)];
                } 
                else if (sqlite3_column_type(statement,i) == SQLITE_FLOAT)
                {
                    result = [NSNumber numberWithFloat:(float)sqlite3_column_double(statement,i)];                  
                }
                else 
                {
                    result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)];
                }
                if (result) 
                {
                    [thisDict setObject:result
                                 forKey:[NSString stringWithUTF8String:sqlite3_column_name(statement,i)]];
                }
            }
            [thisArray addObject:[NSDictionary dictionaryWithDictionary:thisDict]];
            [thisArray retain];
        }
    }
    sqlite3_finalize(statement);
    return thisArray;
}

- (NSDictionary *)lookupRowForSQL:(NSString *)sql {
    sqlite3_stmt *statement;
    id result;
    NSMutableDictionary *thisDict = [NSMutableDictionary dictionaryWithCapacity:4];
    if (statement = [self prepare:sql]) 
    {
        if (sqlite3_step(statement) == SQLITE_ROW) 
        {   
            for (int i = 0 ; i < sqlite3_column_count(statement) ; i++) 
            {
                if (strcasecmp(sqlite3_column_decltype(statement,i),"Boolean") == 0)
                {
                    result = [NSNumber numberWithBool:(BOOL)sqlite3_column_int(statement,i)];
                } 
                else if (sqlite3_column_type(statement, i) == SQLITE_TEXT) 
                {
                    result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)];
                } 
                else if (sqlite3_column_type(statement,i) == SQLITE_INTEGER)
                {
                    result = [NSNumber numberWithInt:(int)sqlite3_column_int(statement,i)];
                } 
                else if (sqlite3_column_type(statement,i) == SQLITE_FLOAT)
                {
                    result = [NSNumber numberWithFloat:(float)sqlite3_column_double(statement,i)];                  
                } 
                else 
                {
                    result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)];
                }
                if (result) 
                {
                    [thisDict setObject:result
                                 forKey:[NSString stringWithUTF8String:sqlite3_column_name(statement,i)]];
                }
            }
        }
    }
    sqlite3_finalize(statement);
    return thisDict;
}

- (id)lookupColForSQL:(NSString *)sql {

    sqlite3_stmt *statement;
    id result;
    if (statement = [self prepare:sql]) {
        if (sqlite3_step(statement) == SQLITE_ROW) {        
            if (strcasecmp(sqlite3_column_decltype(statement,0),"Boolean") == 0) {
                result = [NSNumber numberWithBool:(BOOL)sqlite3_column_int(statement,0)];
            } else if (sqlite3_column_type(statement, 0) == SQLITE_TEXT) {
                result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,0)];
            } else if (sqlite3_column_type(statement,0) == SQLITE_INTEGER) {
                result = [NSNumber numberWithInt:(int)sqlite3_column_int(statement,0)];
            } else if (sqlite3_column_type(statement,0) == SQLITE_FLOAT) {
                result = [NSNumber numberWithDouble:(double)sqlite3_column_double(statement,0)];                    
            } else {
                result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,0)];
            }
        }
    }
    sqlite3_finalize(statement);
    return result;

}

// Simple use of COUNTS, MAX, etc.

- (int)lookupCountWhere:(NSString *)where forTable:(NSString *)table {

    int tableCount = 0;
    NSString *sql = [NSString stringWithFormat:@"SELECT COUNT(*) FROM %@ WHERE %@",
                     table,where];      
    sqlite3_stmt *statement;

    if (statement = [self prepare:sql]) {
        if (sqlite3_step(statement) == SQLITE_ROW) {        
            tableCount = sqlite3_column_int(statement,0);
        }
    }
    sqlite3_finalize(statement);
    return tableCount;

}

- (int)lookupMax:(NSString *)key Where:(NSString *)where forTable:(NSString *)table {

    int tableMax = 0;
    NSString *sql = [NSString stringWithFormat:@"SELECT MAX(%@) FROM %@ WHERE %@",
                     key,table,where];      
    sqlite3_stmt *statement;
    if (statement = [self prepare:sql]) {
        if (sqlite3_step(statement) == SQLITE_ROW) {        
            tableMax = sqlite3_column_int(statement,0);
        }
    }
    sqlite3_finalize(statement);
    return tableMax;

}

- (int)lookupSum:(NSString *)key Where:(NSString *)where forTable:(NSString *)table {

    int tableSum = 0;
    NSString *sql = [NSString stringWithFormat:@"SELECT SUM(%@) FROM %@ WHERE %@",
                     key,table,where];      
    sqlite3_stmt *statement;
    if (statement = [self prepare:sql]) {
        if (sqlite3_step(statement) == SQLITE_ROW) {        
            tableSum = sqlite3_column_int(statement,0);
        }
    }
    sqlite3_finalize(statement);
    return tableSum;

}

// INSERTing and UPDATing

- (void)insertArray:(NSArray *)dbData forTable:(NSString *)table {

//  NSMutableString *sql = [NSMutableString stringWithCapacity:16];
//  [sql appendFormat:@"INSERT INTO %@ (",table];
//  
//  
//  for (int i = 0 ; i < [dbData count] ; i++) {
//      NSLog(@"%@",[[dbData objectAtIndex:i] objectForKey:@"mid"]);
//      [sql appendFormat:@"%@",[[dbData objectAtIndex:i] objectForKey:@"key"]];
//      if (i + 1 < [dbData count]) {
//          [sql appendFormat:@", "];
//      }
//  }
//  [sql appendFormat:@") VALUES("];
//  for (int i = 0 ; i < [dbData count] ; i++) {
//      if ([[[dbData objectAtIndex:i] objectForKey:@"value"] intValue]) {
//          [sql appendFormat:@"%@",[[[dbData objectAtIndex:i] objectForKey:@"value"] intValue]];
//      } else {
//          [sql appendFormat:@"'%@'",[[dbData objectAtIndex:i] objectForKey:@"value"]];
//      }
//      if (i + 1 < [dbData count]) {
//          [sql appendFormat:@", "];
//      }
//  }
//  [sql appendFormat:@")"];
//  [self runDynamicSQL:sql forTable:table];
    for(int i=0;i<[dbData count];i++)
    {
        NSDictionary *dict=[dbData objectAtIndex:i];
        NSMutableString *sql = [NSMutableString stringWithCapacity:16];
        [sql appendFormat:@"INSERT INTO %@ (",table];

        NSArray *dataKeys = [dict allKeys];
        for (int i = 0 ; i < [dataKeys count] ; i++) {
            [sql appendFormat:@"%@",[dataKeys objectAtIndex:i]];
            if (i + 1 < [dataKeys count]) {
                [sql appendFormat:@", "];
            }
        }

        [sql appendFormat:@") VALUES("];
        for (int i = 0 ; i < [dataKeys count] ; i++) {
            if ([[dict objectForKey:[dataKeys objectAtIndex:i]] intValue]) {
                [sql appendFormat:@"%@",[dict objectForKey:[dataKeys objectAtIndex:i]]];
            } else {
                [sql appendFormat:@"'%@'",[dict objectForKey:[dataKeys objectAtIndex:i]]];
            }
            if (i + 1 < [dict count]) {
                [sql appendFormat:@", "];
            }
        }

        [sql appendFormat:@")"];
        [self runDynamicSQL:sql forTable:table];
    }
}

- (void)insertDictionary:(NSDictionary *)dbData forTable:(NSString *)table {

    NSMutableString *sql = [NSMutableString stringWithCapacity:16];
    [sql appendFormat:@"INSERT INTO %@ (",table];

    NSArray *dataKeys = [dbData allKeys];
    for (int i = 0 ; i < [dataKeys count] ; i++) {
        [sql appendFormat:@"%@",[dataKeys objectAtIndex:i]];
        if (i + 1 < [dbData count]) {
            [sql appendFormat:@", "];
        }
    }

    [sql appendFormat:@") VALUES("];
    for (int i = 0 ; i < [dataKeys count] ; i++) {
        //if ([[dbData objectForKey:[dataKeys objectAtIndex:i]] intValue]) {
//          [sql appendFormat:@"%@",[dbData objectForKey:[dataKeys objectAtIndex:i]]];
//      } else {

        [sql appendFormat:@"'%@'",[dbData objectForKey:[dataKeys objectAtIndex:i]]];
        //}
        if (i + 1 < [dbData count]) {
            [sql appendFormat:@", "];
        }
    }

    [sql appendFormat:@")"];
    [self runDynamicSQL:sql forTable:table];
}

- (void)updateArray:(NSArray *)dbData forTable:(NSString *)table { 
    [self updateArray:dbData forTable:table where:NULL];
}

- (void)updateArray:(NSArray *)dbData forTable:(NSString *)table where:(NSString *)where {

    NSMutableString *sql = [NSMutableString stringWithCapacity:16];
    [sql appendFormat:@"UPDATE %@ SET ",table];

    for (int i = 0 ; i < [dbData count] ; i++) {
        if ([[[dbData objectAtIndex:i] objectForKey:@"value"] intValue]) {
            [sql appendFormat:@"%@=%@",
             [[dbData objectAtIndex:i] objectForKey:@"key"],
             [[dbData objectAtIndex:i] objectForKey:@"value"]];
        } else {
            [sql appendFormat:@"%@='%@'",
             [[dbData objectAtIndex:i] objectForKey:@"key"],
             [[dbData objectAtIndex:i] objectForKey:@"value"]];
        }       
        if (i + 1 < [dbData count]) {
            [sql appendFormat:@", "];
        }
    }
    if (where != NULL) {
        [sql appendFormat:@" WHERE %@",where];
    } else {
        [sql appendFormat:@" WHERE 1",where];
    }       
    [self runDynamicSQL:sql forTable:table];
}

- (void)updateDictionary:(NSDictionary *)dbData forTable:(NSString *)table { 
    [self updateDictionary:dbData forTable:table where:NULL];
}

- (void)updateDictionary:(NSDictionary *)dbData forTable:(NSString *)table where:(NSString *)where {

    NSMutableString *sql = [NSMutableString stringWithCapacity:16];
    [sql appendFormat:@"UPDATE %@ SET ",table];

    NSArray *dataKeys = [dbData allKeys];
    for (int i = 0 ; i < [dataKeys count] ; i++) {
        if ([[dbData objectForKey:[dataKeys objectAtIndex:i]] intValue]) {
            [sql appendFormat:@"%@=%@",
             [dataKeys objectAtIndex:i],
             [dbData objectForKey:[dataKeys objectAtIndex:i]]];
        } else {
            [sql appendFormat:@"%@='%@'",
             [dataKeys objectAtIndex:i],
             [dbData objectForKey:[dataKeys objectAtIndex:i]]];
        }       
        if (i + 1 < [dbData count]) {
            [sql appendFormat:@", "];
        }
    }
    if (where != NULL) {
        [sql appendFormat:@" WHERE %@",where];
    }
    [self runDynamicSQL:sql forTable:table];
}

- (void)updateSQL:(NSString *)sql forTable:(NSString *)table {
    [self runDynamicSQL:sql forTable:table];
}

- (void)deleteWhere:(NSString *)where forTable:(NSString *)table {

    NSString *sql = [NSString stringWithFormat:@"DELETE FROM %@ WHERE %@",
                     table,where];
    [self runDynamicSQL:sql forTable:table];
}

// INSERT/UPDATE/DELETE Subroutines

- (BOOL)runDynamicSQL:(NSString *)sql forTable:(NSString *)table {

    int result;
    //NSAssert1(self.dynamic == 1,[NSString stringWithString:@"Tried to use a dynamic function on a static database"],NULL);
    sqlite3_stmt *statement;
    if (statement = [self prepare:sql]) {
        result = sqlite3_step(statement);
    }       
    sqlite3_finalize(statement);
    if (result) {
        if (self.delegate != NULL && [self.delegate respondsToSelector:@selector(databaseTableWasUpdated:)]) {
            [delegate databaseTableWasUpdated:table];
        }   
        return YES;
    } else {
        return NO;
    }

}

// requirements for closing things down

- (void)dealloc {
    [self close];
    [delegate release];
    [super dealloc];
}

- (void)close {

    if (dbh) {
        sqlite3_close(dbh);
    }
}

@end

Upvotes: 0

TheEye
TheEye

Reputation: 9346

Probably the second time the didFinishLaunchingWithOptions function is not called when the user presses the button in the notification, as the app is already running in the background (as opposed to being started from the not-running state).

You also have to handle the function call to

(void)application:(UIApplication *)application 
        didReceiveLocalNotification:(UILocalNotification *)notification {
// do your db update here, too ...
}

in order to cover situations where your app is already running in the background.

EDIT:

To see whether the app was started or was already running (= user pressed "View" on notification versus app is running in foreground), check the APplication state:

UIApplicationState state = [application applicationState];
  if (state == UIApplicationStateInactive) {
    // Application was in the background when notification
    // was delivered.
  }

Credits to Use Your Loaf - Adding Local Notifications With iOS 4.

Upvotes: 2

Related Questions