problem in inserting the vlaues into database - iphone

i was getting familiar with sqlite and try to insert the values into database but giving exception. tf1 and tf2 are object of textfield. here is my code:
#synthesize tf1, tf2, add, disp;
-(id)initApp
{
if(![super init])
return nil;
//DB stored in application bundle
NSString *DBName = #"kbase.sqlite";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingString:DBName];
db = [FMDatabase databaseWithPath:path];
[db setLogsErrors:TRUE];
[db setTraceExecution:TRUE];
if(![db open])
{
NSLog(#"Could not open Database");
return 0;
}
else
{
NSLog(#"Database opened successfully");
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self initApp];
[add addTarget:self action:#selector(insertButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[disp addTarget:self action:#selector(displaytButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
-(IBAction)insertButtonClicked :(id)sender
{
NSLog(#"insert");
NSLog(#"db.....%#",db);
[db executeUpdate:#"insert into info values (?,?)", tf1.text, tf2.text];
[self resignFirstResponder];
}
-(IBAction)displayButtonClicked:(id)sender
{
NSString *str1 = tf2.text;
NSString *returnResult = [[NSString alloc]init];
FMResultSet *rs = [db executeQuery:#"select name from info where rollno = 1"];
while ([rs next])
{
returnResult = [rs stringForColumn:#"rollno"];
[tf1 setText:returnResult];
[tf2 setText:returnResult];
}
}
databse is opening successfully and controll terminate after printing insert
exception:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSURL executeQuery:]: unrecognized selector sent to instance 0x3d30ef0'
i am not able to configure the problem. plz help.

I think make your method
[db executeUpdate:#"insert into info values (?,?)" withValue1:tf1.text withValue2:tf2.text];
Instead of
[db executeUpdate:#"insert into info values (?,?)", tf1.text, tf2.text];

it seems that db does not exist in this context. If db is a class variable, make sure it is not released somewhere else. Simply put an NSLog(#"%#", db); above the execution to test it.

Related

String not getting split giving unrecognized selector error

Trying to split the string in to array, but it is giving error "[__NSArrayI componentsSeparatedByString:]: unrecognized selector sent to instance 0x11741b20'". The string contains the value, that comes from first index of array then the string needs to be split and store in array.
This is array value.
mcommarr:(
":comment",
":comment",
":comment"
NSString *strr = [[NSString alloc]init];
strr = [self.mCommArr objectAtIndex:indexVal];
NSArray *arr2 = [str componentsSeparatedByString:#","];
Here is the complete method in which i am using this.
-(void)loadData:(int)indexVal;
{
indexVal=serialIndexVal;
serialIndexVal++;
NSLog(#"arrLike:%d", [self.mArrLike count]);
NSLog(#"arrPid:%d", [self.mArrPid count]);
status = [NSString stringWithFormat:#"get"];
[self.mButtonsStatusDict setObject:status forKey:#"status"];
[self.mButtonsPidDict setObject:[self.mArrPid objectAtIndex:indexVal] forKey:#"pid"];
[self.activityIndicator startAnimating];
#try
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSString *status = [NSString stringWithFormat:#"get"];
[self.mButtonsStatusDict setObject:status forKey:#"status"];
[self.mButtonsPidDict setObject:[self.mArrPid objectAtIndex:indexVal] forKey:#"pid"];
self.mButtonsCommentsDict = [MyEventApi showComments:self.mButtonsPidDict];
self.mButtonsDict = [MyEventApi likeDislike:self.mButtonsUidDict post:self.mButtonsPidDict postStatus:self.mButtonsStatusDict];
dispatch_sync(dispatch_get_main_queue(), ^{
[self.activityIndicator stopAnimating];
NSLog(#"buttons data dict:%#", self.mButtonsDict);
if([self.mButtonsDict count] == 0)
{
NSLog(#"server problem no response");
[self.mArrLike addObject: #"0"];
[self.mArrDislike addObject: #"0"];
}else{
[self.mArrLike addObject: [self.mButtonsDict valueForKey:#"like"]];
[self.mArrDislike addObject: [self.mButtonsDict valueForKey:#"dislike"]];
}
if([self.mButtonsCommentsDict count] == 0)
{
NSLog(#"server problem no response");
[self.mCommArrTot addObject: #"0"];
}
else{
self.dictComm = [self.mButtonsCommentsDict valueForKey:#"comments"];
[self.mCommArr addObject:[self.dictComm valueForKey:#"comment"]];
NSLog(#"count:%d",[self.mCommArr count]);
// NSString *strTot = [NSString stringWithFormat:#"%d",tot];
// [self.mCommArrTot addObject:strTot];
NSLog(#"dictcomm:%#", self.dictComm );
NSLog(#"mcommarr:%#", [self.mCommArr objectAtIndex:indexVal]);
strr = [[NSString alloc]init];
strr = [self.mCommArr objectAtIndex:indexVal];
//NSString *strr = [[NSString stringWithFormat:#"%#", [self.mCommArr objectAtIndex:indexVal]];
// NSArray *arr1 = [self string:strr];
// NSArray *splitArray=[self.mCommArr[0] componentsSeparatedByString:#","];
//[strr componentsSeparatedByString:#","];
// NSLog(#"arrSep:%#", arr1);
//int count = [arr1 count];
//NSLog(#"arrcount:%d", count);
// NSString *strTot = [NSString stringWithFormat:#"%d",count];
// [self.mCommArrTot addObject:strTot];
//NSLog(#"mcommarrtot:%#", [self.mCommArrTot objectAtIndex:indexVal]);
}
// NSLog(#"arrLike:%#", [self.mArrLike objectAtIndex:indexVal]);
// NSLog(#"arrDisLike:%#", [self.mArrLike objectAtIndex:indexVal]);
[self.mPublicFriendTable reloadData];
});
});
}
#catch (NSException *exception) {
NSLog(#"main: Caught %#: %#", [exception name], [exception reason]);
}
#finally {
}
}
It get killed when try to split. Why so, i am not getting. If anyone has faced such situation please guide what is wrong her.
You can split the string into an NSArray like below...
NSString *yourString = #"comment,comment,comment";
NSArray *strArray = [yourString componentsSeparatedByString:#","];
NSLog(#"\n\n Array is ==>> %#",strArray);
"[__NSArrayI componentsSeparatedByString:]:
Your error says you tried to send the above method to NSArray, which doesn't has.
As you want to split the array at index 0. you should probably do as :
NSArray *splitArray=[yourArray[0] componentsSeparatedByString:#","];
Here yourArray is the array that you get from Server.
NSString *strr = [[NSString stringWithFormat:#"%#", [self.mCommArr objectAtIndex:indexVal]];
NSArray *arr2 = [strr componentsSeparatedByString:#","];
I think you are passing str right now, which can be an array (as your error points out).
Let me know the results.

Credential match from Plist

I have a plist with Array title and item0,item1,item2 is dictionary to store title and password of my app.now i want to check for signin process
now i Want to check for pass and items should be matched when i press submit button to login.i Tried the below code but xcode crashes
-(void)authenticateCredentials
{
NSMutableArray *plistArray = [NSMutableArray arrayWithArray:[self readFromPlist]];
for (int i = 0; i< [plistArray count]; i++)
{
if ([[[plistArray objectAtIndex:i]objectForKey:#"pass"]isEqualToString:emailTextFeild.text] && [[[plistArray objectAtIndex:i]objectForKey:#"title"]isEqualToString:passwordTextFeild.text])
{
NSLog(#"Correct credentials");
return;
}
NSLog(#"INCorrect credentials");
}
}
and
-(NSArray*)readFromPlist
{
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [documentPaths objectAtIndex:0];
NSString *documentPlistPath = [documentsDirectory stringByAppendingPathComponent:#"XYZ.plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:documentPlistPath];
NSArray *valueArray = [dict objectForKey:#"title"];
return valueArray;
}
the xcode gets crashs ..please check in -(void)authenticateCredentials where i am incorrect?
AND
Crash when I select the submit button,Its wont give any output correct or incorrect in nslog and Xcode crash then , with errorr
2012-12-14 12:10:45.142 NavTutorial[1661:f803] emailEntry: hi#gmail.com.com
2012-12-14 12:10:45.145 NavTutorial[1661:f803] passwordEntry: hellohello
2012-12-14 12:10:45.153 NavTutorial[1661:f803] -[__NSCFConstantString objectForKey:]: unrecognized selector sent to instance 0x1568cd8
2012-12-14 12:10:45.155 NavTutorial[1661:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFConstantString objectForKey:]: unrecognized selector sent to instance 0x1568cd8'
*** First throw call stack:
(0x14d7052 0x11c2d0a 0x14d8ced 0x143df00 0x143dce2 0x3981 0x14d8ec9 0x3735c2 0x37355a 0x418b76 0x41903f 0x417e22 0x39893f 0x398c56 0x37f384 0x372aa9 0x1bcdfa9 0x14ab1c5 0x1410022 0x140e90a 0x140ddb4 0x140dccb 0x1bcc879 0x1bcc93e 0x370a9b 0x211d 0x2095 0x1)
terminate called throwing an exception
and
two days ago this same code worked fine
and if i put Breakpoint for IF condition and later if fails just after if condition.
Modify your authenticateCredentials as shown below and check if it is working. If it is showing an error message as Error! Not a dictionary, you need to check if your plist is having correct structure. Mostly your [objDict objectForKey:#"pass"] is returning a different data type.
- (void)authenticateCredentials {
NSMutableArray *plistArray = [NSMutableArray arrayWithArray:[self readFromPlist]];
for (int i = 0; i< [plistArray count]; i++)
{
id object = [plistArray objectAtIndex:i];
if ([object isKindOfClass:[NSDictionary class]]) {
NSDictionary *objDict = (NSDictionary *)object;
if ([[objDict objectForKey:#"pass"] isEqualToString:emailTextFeild.text] && [[objDict objectForKey:#"title"] isEqualToString:passwordTextFeild.text])
{
NSLog(#"Correct credentials");
return;
}
NSLog(#"INCorrect credentials");
} else {
NSLog(#"Error! Not a dictionary");
}
}
}

'NSRangeException' while reading data from a file

I am trying to save data when the home button is pressed.
Here is my relevant code.
- (NSString *) saveFilePath
{
NSArray *path =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [[path objectAtIndex:0] stringByAppendingPathComponent:#"savefile.plist"];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSArray *values = [[NSArray alloc] initWithObjects:
[NSNumber numberWithInt:askedQuestions], //for questionLabel
[NSNumber numberWithInt:timeMin], //timeMin
[NSNumber numberWithInt:timeSec], //timeSec
[NSNumber numberWithInt:skipCount], //skipped question
[NSNumber numberWithInt:correctAnswers], //corectAnswers
nil];
[values writeToFile:[self saveFilePath] atomically:YES];
}
saveFilePath method is providing the file path.
And in viewDidLoad
NSString *myPath = [self saveFilePath];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:myPath];
if (fileExists)
{
NSArray *values = [[NSArray alloc] initWithContentsOfFile:myPath];
_readerLabel.text = [[values objectAtIndex:0] stringValue];
askedQuestions=[[values objectAtIndex:0] intValue];
timeMin=[[values objectAtIndex:1]intValue];
timeSec=[[values objectAtIndex:2]intValue];
skipCount=[[values objectAtIndex:3]intValue];
correctAnswers=[[values objectAtIndex:4]intValue];
}
UIApplication *myApp = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:myApp];
and i am getting this:
Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (0) beyond bounds (0)'
*** First throw call stack:
(0x16a1012 0x13aee7e 0x16a0deb 0x16957e0 0x6891 0x312d 0x305817 0x305882 0x254a25 0x254dbf 0x254f55 0x25df67 0x221fcc 0x222fab 0x234315 0x23524b 0x226cf8 0x2703df9 0x2703ad0 0x1616bf5 0x1616962 0x1647bb6 0x1646f44 0x1646e1b 0x2227da 0x22465c 0x26cd 0x25f5)
libc++abi.dylib: terminate called throwing an exception
Where is the problem in the code. Please help!
You're not checking to see if anything has worked!
What happens if
NSArray *values = [[NSArray alloc] initWithContentsOfFile:myPath];
either fails (the file might not exist) or if it returns an array with 0 items in?
You need to add something like :
NSArray *values = [[NSArray alloc] initWithContentsOfFile:myPath];
if (values.count > 0) {
...
}
You should also set a breakpoint on applicationDidEnterBackground: and step though to make sure that your save method is working as you expect.
Also, I suspect one of these two lines is wrong :
_readerLabel.text = [[values objectAtIndex:0] stringValue];
askedQuestions=[[values objectAtIndex:0] intValue];
they're both asking for the item at index 0

SQLite Changes Not Saved

I'm using SQLite in iOS 4 on an iPhone, but the changes made by my update statements aren't saved. At first thought perhaps quitting the app might be deleting the database somehow, but they're not even persisted during the same session. The code to initialize my database is (using FMDB):
-(SQLiteDal*) init {
pool = [[NSAutoreleasePool alloc] init];
self = [super init];
if(self != nil){
// Setup some globals
NSString *databaseName = [self getDbPath];
NSLog([NSString stringWithFormat:#"db path: %#", databaseName]);
db = (FMDatabase *)[FMDatabase databaseWithPath:databaseName];
if (![db open]) {
NSLog(#"Could not open db.");
[pool release];
return 0;
}
}
//[self checkAndCreateDatabase];
return self;
}
#pragma mark DB Maintenance
-(NSString *)getDbPath {
NSString *databaseName = #"myapp.db";
// Get the path to the documents directory and append the databaseName
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databaseName = [documentsDir stringByAppendingPathComponent:databaseName];
return databaseName;
}
Both of these methods are called to create the database, then to insert to a table I call:
[db executeQuery:#"INSERT INTO MyTable (Name, Description, Area, Price, ID) VALUES (?,?,?,?,?)",
f.Name,
f.description,
f.area,
f.price,
f.id];
The problem is, when I come to read from MyTable using the statement below, I never get anything back:
FMResultSet *rs = [db executeQuery:#"SELECT * FROM MyTable WHERE ID = ?", id];
while ([rs next]) {
//.. this is never called
As far as I can see I'm not missing anything out, and the DB seems to be in a writable location.
When inserting you need to call executeUpdate not executeQuery. Also you should call beginTransaction and then commit, like this:
[_dbPointer beginTransaction];
BOOL isInserted = [_dbPointer executeUpdate:[NSString stringWithFormat:#"INSERT INTO MyTable (Name, Description, Area, Price, ID) VALUES(?,?,?,?,?);", f.Name,
f.description,
f.area,
f.price,
f.id]];
[_dbPointer commit];

Problem reading a string from an NSDictionary inside an NSMutableArray stored using NSKeyedArchiver

I'm saving some data using a series of NSDictionaries, stored in an NSMutableArray and archived using NSKeyedArchiver.
I'm basically trying to save the states of several instances the class 'Brick', so I've implemented a getBlueprint method like this (slimmed down version)
-(id)getBlueprint
{
// NOTE: brickColor is a string
NSDictionary *blueprint = [NSDictionary dictionaryWithObjectsAndKeys:
brickColor, #"color",
[NSNumber numberWithInt:rotation], #"rotation",
nil];
return blueprint;
}
And so I have another method that creates a new Brick instance when provided with a blueprint.
-(id)initWithBlueprint:(NSDictionary *)blueprint spriteSheet:(NSString *)ssheet
{
if((self == [super init])){
brickColor = [blueprint objectForKey:#"color"];
[self setColorOffset:brickColor];
while(rotation != [[blueprint objectForKey:#"rotation"] intValue]){
[self setRotation:90];
}
}
return self;
}
Which works when I pass it a 'fresh' blueprint, but not when I read a blueprint from a saved file... sort of. For example, the rotation will work, but changing the color wont. So while I can read the value of brickColor using
NSLog(#"brick color %#", [blueprint objectForKey:#"color"]);
if I try something like
if(brickColor == #"purple"){
colorOffset = CGPointMake(72,36);
NSLog(#"Changed offset for -- %# -- to %#", color, NSStringFromCGPoint(colorOffset));
}
And I know that color is purple, the condition doesn't return true. I thought it might be that somehow NSKeyedUnarchiver changed a string into something else, but the following test returns true.
if([color isKindOfClass:[NSString class]]){
NSLog(#"%# IS A STRING", color);
}else{
NSLog(#"!!!!! COLOR IS A NOT STRING !!!!!");
}
As I said, this isn't a problem if I try to use a freshly created NSDictionary as a blueprint, only when a blueprint is archived and then read back in.
So, as usual, I'm wondering if anyone has any ideas why this might be happening.
incase it's relevant, here's how the data is being stored and recieved.
// Saving
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-(void)buildLevelData{
levelData = [[NSMutableArray alloc] initWithCapacity:100];
for(brickSprite *brick in spriteHolder.children){
[levelData addObject:[brick getBlueprint]];
}
}
-(void)saveLevel
{
[self buildLevelData];
NSData *rawDat = [NSKeyedArchiver archivedDataWithRootObject:levelData];
if([self writeApplicationData:rawDat toFile:saveFileName]){
NSLog(#"Data Saved");
}else{
NSLog(#"ERROR SAVING LEVEL DATA!");
}
[[Director sharedDirector] replaceScene:[MainMenu scene]];
}
- (BOOL)writeApplicationData:(NSData *)data toFile:(NSString *)fileName {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
if (!documentsDirectory) {
NSLog(#"Documents directory not found!");
return NO;
}
NSString *appFile = [saveDir stringByAppendingPathComponent:fileName];
return ([data writeToFile:appFile atomically:YES]);
}
// Loading
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- (void) loadRandomMapFrom:(NSString *)dir
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [paths objectAtIndex:0];
if(!docsDir){
NSLog(#"Cound Not Find Documents Directory When trying To Load Random Map");
return;
}
dir = [docsDir stringByAppendingPathComponent:[NSString stringWithFormat:#"/%#", dir]];
// we'll also set the file name here.
NSArray *existingFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:dir error:nil];
// get last file for this test
NSString *filePath = [dir stringByAppendingPathComponent:[existingFiles objectAtIndex:([existingFiles count] - 1)]];
NSMutableArray *levelData = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
[self buildMapWithData:levelData];
}
-(void)buildMapWithData:(NSMutableArray *)lData
{
for(NSDictionary *blueprint in lData){
brickSprite *brick = [[brickSprite alloc] initWithBlueprint:blueprint spriteSheet:#"blocks.png"];
[spriteHolder addChild:brick];
}
}
Sorry about the mess of a question. There's a lot going on that I'm struggling to fully understand myself so it's hard to break it down to the bare minimum.
You should always compare strings with [firstString isEqualToString:secondString], because firstString == secondString only checks for pointer equality, e.g. if both strings are stored at the same location (which they'll never be when comparing dynamically created objects and string constants).