call an array method - objective-c

I have this method, and I am trying to call that method doing [self getUsers ObjectAtIndex:0] but compiler won't compile that line at all and says it's unknown. How do I call an array method to display all the string in it?
- (NSArray*)getUsers
{
NSArray *getUsers = [[NSArray alloc] init];
NSString *databasepath;
NSString *docsDir;
NSArray *dirPaths;
//NSString *databasePath;
//get the document directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
//build the path to the database file
databasepath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent:
#"users.db"]];
const char *dbPath = [databasepath UTF8String];
sqlite3_stmt *statement;
sqlite3 *userdb;
if (sqlite3_open(dbPath, &userdb) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat:#"SELECT * FROM USERS WHERE username = \"%#\"", txtUsername.text];
const char *sql_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(userdb, sql_stmt, -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
char *field = (char*) sqlite3_column_text(statement, 1);
NSString *usernameField = [[NSString alloc]initWithUTF8String:field];
//NSLog(#"%#", usernameField);
getUsers = [NSArray arrayWithObject:usernameField];
}
}
sqlite3_finalize(statement);
}
sqlite3_close(userdb);
return getUsers;
}

Use [[self getUsers] objectAtIndex:0].
If you use the latest Xcode/clang version, you can also use [self getUsers][0], since arrays now support indexing.

Consider say you had a method -(id)someMethod, and then called it like this:
id myValue = [self someMethod];
Inside someMethod, there is a return statement - whatever is to the right of the return is what will be assigned to myValue in the calling method or function.
Just call like this:
NSArray *arrAllUsers = [self getUsers]; //As getUsers is method which returns nsarray.

Related

Cocoa sqlite db file

I'm having a bit of trouble understanding why the below code is not working:
sqlite3_stmt *statement5;
NSString *databasePath2 = #"default-gameData.db";
NSInteger speed_int = 0;
const char *dbPath2 = [databasePath2 UTF8String];
if(sqlite3_open(dbPath2, &db)==SQLITE_OK){
NSString *getspeeds = #"SELECT * FROM planeInfo";
NSLog(#"%#",getspeeds);
const char *getspeed_stmt = [getspeeds UTF8String];
if(sqlite3_prepare_v2(db, getspeed_stmt, -1, &statement5, nil)==SQLITE_OK){
NSLog(#"%d",sqlite3_step(statement5));
NSString *org_plane_info_id = [[NSString alloc] init];
while(sqlite3_step(statement5) == SQLITE_ROW){
if((const char*)sqlite3_column_text(statement5, 1)==NULL){
org_plane_info_id = #"no";
}
else{
org_plane_info_id = [[NSString alloc] initWithUTF8String:(const char*)sqlite3_column_text(statement5, 1)];
}
NSLog(#"%#",org_plane_info_id);
if(org_plane_info_id==plane_info_id){
NSString *speed = [[NSString alloc] initWithUTF8String:(const char*)sqlite3_column_text(statement5, 2)];
NSLog(#"%#",speed);
speed_int = [speed integerValue];
return speed_int;
}
}
}
}
if(speed_int==0){
return 0;
}
sqlite3_close(db);
I've found the source of the problem being the database path, the file is stored where the .h and .m files are so I think that's where I am going wrong, but what do I have to do to get that to work?
Cocoa/Foundation doesn't know where your file is. You need to tell it that it's in the app bundle.
NSString *databasePath2 = [[NSBundle mainBundle] pathForResource:#"default-gameData" ofType:#"db"];

unable to save image in SQLite in iPhone

can anybody tell me why i am unable to insert an image in sqlite. Some time i get error like:
1)(sqlite3_step(stm) == SQLITE_DONE) , getting value as 21.
2)gets stored in an array and not into databse.
I a fresher in objective c so if u could post back a code it would be sweet, as i searched almost evry site.
Thanks!
-(IBAction)submitDetails:(id)sender
{
sqlite3_stmt *stm;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &connectDB) == SQLITE_OK)
{
UIImage *contactImage = imageView.image;
NSData *imageData = UIImageJPEGRepresentation(contactImage, 100);
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:imageData forKey:#"image"];
[defaults synchronize];
NSLog(#"Data saved");
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO STUDENTS (name,salary, gid,photo) VALUES (\"%#\", \"%#\", \"%#\",?)", name.text,salary.text,gid.text,imageData] ;
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(connectDB, insert_stmt, -1, &stm, NULL);
NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirec = [paths objectAtIndex:0];
NSString *imgePath = [documentsDirec stringByAppendingPathComponent:#"note.sqlite"];
if(sqlite3_open([imgePath UTF8String], &database) == SQLITE_OK){
const char *sql = "insert into images (images) values (?)";
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) == SQLITE_OK){
UIImage *edtedImae = [info objectForKey:UIImagePickerControllerOriginalImage];
NSData *dataForImage = UIImagePNGRepresentation(edtedImae);
sqlite3_bind_blob(addStmt, 1, [dataForImage bytes], [dataForImage length], SQLITE_TRANSIENT);
NSLog(#"1st ..... %i",sqlite3_step(stm));
NSLog(#" 2nd.... %i",SQLITE_DONE);
if (sqlite3_step(stm) == SQLITE_DONE)
{
NSString* aName=name.text;
NSString* aSalary=salary.text;
NSString* aGid=gid.text;
UIImage* aPhoto=[UIImage imageWithData:imageData];
Person *person = [[Person alloc] initWithName:aName salary:aSalary gid:aGid photo:aPhoto];
[rootObject.list addObject:person];
[person release];
status.text = #"Contact added";
NSLog(#"contact added %# %#",name.text,gid.text);
NSLog(#"the count in person list is %i",[rootObject.list count]);
name.text = #"";
gid.text = #"";
salary.text = #"";
}
else
{
status.text = #"Failed to add contact";
}
sqlite3_finalize(stm);
sqlite3_close(connectDB);
}
}
Don't save the image in the database if you can avoid it. Instead, use columns to store the file name and any other attributes and then save the image as a document. I use a guid method to create file names. Don't forget to remove the document if you should remove the db entry.

Issue with return value after query in Sqlite database

In my app I am executing a query to get the count of images which are having same category and that category is passed by me as the parameter. Now when the query is executed I want to get two results either 1 or more than one. For that purpose I think I need to convert the string to integer. When I check the value of the String it is showing me 1 but when that value is returned to the method it is showing something like this:695842 and something else also. What could be the reason? Please help. I am posting the part of code:-
-(NSInteger)searchImagesInSameCategory:(NSString *)categoryName
{
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory= [paths objectAtIndex:0];
NSString *path=[documentsDirectory stringByAppendingPathComponent:#"SymbolTalkLanguageElement.sqlite"];
//Open the database
//might have to make database as property
if(sqlite3_open([path UTF8String], &dataBase) ==SQLITE_OK)
{
sqlite3_stmt *statement;
NSString *strSQL = [[NSString alloc]init];
strSQL = #"select Count(ImageName) from tblLanguageElement where Category='";
strSQL = [[strSQL stringByAppendingString:categoryName] stringByAppendingString:#"'"];
const char *bar = [strSQL UTF8String];
if(sqlite3_prepare(dataBase, bar, -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSLog(#"%#",[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)]);
int k;
//NSString *string=[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
//NSLog(string);
k=[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
//NSLog([NSString stringWithFormat:#"Count for k:-%d",k]);
//[list addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)]];
//return [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
return k;
}
}
}
return 1;
}
You should use intValue method to convert a NSString to int.
NSString *integerStr = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
k = [integerStr intValue];

another EXC_BAD_ACCESS

I fixed the error of my last question but my code raise another EXC_BAD_ACCESS
at
const char *sqlStatement = [NewData UTF8String];
the complete code is
sqlite3 *database;
// Setup some globals
NSString *databaseName = #"test.sql";
// Get the path to the documents directory and append the databaseName
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
NSString * databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
[databasePath retain];
sqlite3_stmt *compiledStatement;
NSString * TheNewText = self.animalDesciption.text;
[TheNewText retain];
NSString * the_user = AnimalName ;
[ the_user retain];
NSString *NewData = [NSString stringWithFormat:#"%#%#%#%#", #"Update animals set description = ",TheNewText , " Where name = ",the_user];
[NewData retain] ;
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = [NewData UTF8String];
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL)== SQLITE_OK) {
sqlite3_reset(sqlStatement);
}
Did you try to alloc and init NSString?
NSString *NewData = [[NSString alloc] initWithFormat:#"%#%#%#%#", #"Update animals set description = ",TheNewText , " Where name = ",the_user];
and don't retain it?
I'd bet the string is getting collected by an autorelease run. Look in the docs for UTF8String, they suggest copying the string to ensure it lasting beyond that point.
My real suggestion, after some thought, is to get rid of the assignment to a stepping stone variable.
I'd say use it like this:
if(sqlite3_prepare_v2(database, [NewData UTF8String], -1, &compiledStatement, NULL)== SQLITE_OK) {
sqlite3_reset(compiledStatement);
Note the change in the reset statement. That may be your real problem, your code is trying to execute a string instead of a prepared sqlite statement.

Passing a column name instead of index in sqlite3

The problem code:
NSString *query = #"SELECT Name FROM Category";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil)
== SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
char *row =(char *)sqlite3_column_text(statement,0);
char *rowData = (char *)sqlite3_column_text(statement,1);
NSString *fieldName = [[NSString alloc] initWithUTF8String:row];
NSString *fieldValue = [[NSString alloc] initWithUTF8String:rowData];
NSLog(#"%#",fieldName);
NSLog(#"%#",fieldValue);
[fieldName release];
[fieldValue release];
}
sqlite3_finalize(statement);
}
char *row =(char *)sqlite3_column_text(statement,0);
In the above code instead of 0 can't I just pass a column name?
How can I do that ?
You can't, not with the C bindings anyway. Instead, you may use this Objective-C wrapper over the standard C interface: FMDB