Wednesday 29 September 2010

iPhone, why I moved from FMDB to direct Sqlite3

I'm still quite disappointed, FMDB was easy to implement and only a few lines of code to do almost anything. I've even posted some example code on my blog. But when I sat and thought about, I realised I'd wasted two days (in total) trying figure out why sql wasn't working.

There must be some problems in the libraries as the sql was working but failed on simple sql statements.

So today I've decided to use Sqlite3 directly, which has taken me have a day and I have all the previous code replaced and working. Yes, it takes more code and is more difficult to implement.

by JM

Monday 27 September 2010

iPhone, how to insert a record using fmdb

One of the easiest ways to perform transactions with a database with the iPhone is with the fmdb libraries. Its a few lines of code to do almost anything.

This is the primary documentation for fmdb http://gusmueller.com/blog/archives/2005/3/22.html

It's pretty good and straight forward. But, I've had some problems today trying to insert a record. None of the usage code I found on the web seemed to be any different to the code I was using.

However, after inserting one field at a time I found my problem was due to using an integer where I needed to use NSNumber. So I thought I'd post the code I arrived at, maybe it will help someone else.






NSMutableString *strAmount = [NSMutableString stringWithString:txtAmount.text];
[strAmount replaceCharactersInRange: [strAmount rangeOfString: strCurrencySymbol]  withString:@""];
NSString *strRecurrance = [self.pickerRecurranceData objectAtIndex:intSelRecurrenceRow];
NSArray *parts = [strRecurrance componentsSeparatedByString: @" "];

NSNumber *numInterval = [NSNumber numberWithInt:[[parts objectAtIndex:0] intValue]];
NSString *strIntervalType = [parts objectAtIndex:1];

// string to date
NSString *myDateString = btnStartDate.titleLabel.text;
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:@"dd MM yyyy"];
NSDate *datStartDate = [[NSDate alloc] init];
datStartDate = [dateFormatter dateFromString:myDateString];

NSString *strDesc = txtDescription.text;


FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
if (![db open]) {
NSLog(@"Could not open db.");
}

if (![db tableExists:@"mytable"]) {
[db executeUpdate:@"CREATE TABLE 'mytable' ('pid' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,'desc' VARCHAR,'sdate' DATETIME,'interval' INTEGER,'itype' VARCHAR,'price' DOUBLE);", nil];
}

[db beginTransaction];


[db executeUpdate:@"INSERT INTO mytable (desc,sdate,interval,itype,price) VALUES (?,?,?,?,?);",
strDesc, datStartDate, numInterval, strIntervalType, strAmount, nil];

//NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);

[db commit];
[db close];

by JM

Thursday 23 September 2010

How to add a decimal point or a done button to the iphone number pad

Following on from our blog post about how to add the done button to the iphone number pad, here's how upgrade that code to add a decimal point as well, well not at the same time :)

How to add your own Done button to the iPhone numeric keypad



Ok, first of all if you haven't done so already, get the code working posted in the done blog post.

Now open up your NumberKeypadModController.h file and add the following to the top of the file below your foundation import.






#define KeyPadTypeDoneButton 1
#define KeyPadTypeDecimalPoint 2

Add this to the interface.






int intKeyPadType;

And this under properties






- (void)setKeyPadType:(int)value;
-(id)initWithKeyPadType: (int)value;

Now open your NumberKeypadModController.m file and add.






-(id)initWithKeyPadType: (int)value
{
[self setKeyPadType:value];
//self = [super init];
self = [self init];
if( self != nil ){
//self.intKeyPadType = value;

}
return self;

}

- (void)setKeyPadType:(int)value {
intKeyPadType = value;
NSLog(@"key=%i", intKeyPadType);
}

Now where you see the line containing @"Done", replace that with ..






if (intKeyPadType == KeyPadTypeDecimalPoint ) {
doneButton.titleLabel.font = [UIFont systemFontOfSize:35];
[doneButton setTitle:@"." forState:UIControlStateNormal];
} else if (intKeyPadType == KeyPadTypeDoneButton ) {
doneButton.titleLabel.font = [UIFont boldSystemFontOfSize:18];
[doneButton setTitle:@"DONE" forState:UIControlStateNormal];
}

Also replace the following functions






- (void)textFieldShouldEndEditing:(UITextField *)textField {
if (textField.keyboardType != UIKeyboardTypeNumberPad)
{
doneButtonShownRecently = YES;
if (intKeyPadType == KeyPadTypeDoneButton ) {
[self performSelector:@selector(considerDoneButtonReallyHidden) withObject:nil afterDelay:SLIDE_OUT_ANIMATION_DURATION];
}
return;
}
[self removeDoneFromKeyboard];
}- (void) donePressed {

if (intKeyPadType == KeyPadTypeDecimalPoint ) {
NSString *currentText = currentTextField.text;
if ([currentText rangeOfString:@"." options:NSBackwardsSearch].length == 0) {
currentTextField.text = [currentTextField.text stringByAppendingString:@"."];
}else {
//alreay has a decimal point
}
} else if (intKeyPadType == KeyPadTypeDoneButton ) {
[self.currentTextField resignFirstResponder];
}
if ([delegate respondsToSelector:@selector(donePressed:)])
[delegate performSelector:@selector(donePressed:) withObject:self.currentTextField];
}

At this point, I'd like to cite and give credit to DevUp for the decimal point formatting code in the donePressed function above.
http://blog.devedup.com/index.php/2010/03/13/iphone-number-pad-with-a-decimal-point/

Now in you useage code replace the following code..






int intCurrentKeyPad;- (void)viewDidLoad {
[super viewDidLoad];
//intCurrentKeyPad = KeyPadTypeDoneButton;
intCurrentKeyPad = KeyPadTypeDecimalPoint;

self.numberKeyPadModController = [[[NumberKeypadModController alloc] initWithKeyPadType:intCurrentKeyPad] autorelease];
//self.numberKeyPadModController = [[[NumberKeypadModController alloc] init] autorelease];
numberKeyPadModController.delegate = self;

[numberKeyPadModController setKeyPadType:intCurrentKeyPad];

if (intCurrentKeyPad == KeyPadTypeDoneButton ) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(doneButton:) name:@"DoneButtonPressed" object:nil];
}

textFieldRow1.delegate = self;
}

- (void)doneButtonPressed:(UITextField*)sender{
if (intCurrentKeyPad == KeyPadTypeDoneButton ) {
if ([textFieldRow1 isEditing]) {
[textFieldRow1 resignFirstResponder];
}
}
}

- (void) donePressed:(id)sender {
if (intCurrentKeyPad == KeyPadTypeDoneButton ) {
UIView* firstResponder = [self.view findFirstResponder];
[firstResponder resignFirstResponder];
}
}

Ok I hope this helps you out!

Feel free to make a comment about this article, let me know if you have any problems with it.

by Jules.