2

I Want to save the image in Database and fetch the image in database.i am convert the image in NSData and the image is store successfully in database but when i fetch that image from database then it crash.it give this warning

Warning :- -[__NSCFString bytes]: unrecognized selector sent to instance 0x7916000

Below code For save the image in Database

NSData *dataImage1 = UIImagePNGRepresentation(image3.image);
 NSString   *str = [NSString stringWithFormat:@"Insert into Gallery(ImageName) VALUES ('%@')",dataImage1];
[Database executeQuery:str];

//Database.m

+(NSString* )getDatabasePath{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"Database"];
    return writableDBPath;

}

+(NSMutableArray *)executeQuery:(NSString*)str{

    sqlite3_stmt *statement= nil;
    sqlite3 *database;
    NSString *strPath = [self getDatabasePath];
    NSMutableArray *allDataArray = [[NSMutableArray alloc] init];
    if (sqlite3_open([strPath UTF8String],&database) == SQLITE_OK) {
        if (sqlite3_prepare_v2(database, [str UTF8String], -1, &statement, NULL) == SQLITE_OK) {


            while (sqlite3_step(statement) == SQLITE_ROW) {
                            NSInteger i = 0;
                NSInteger iColumnCount = sqlite3_column_count(statement);
                NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
                while (i< iColumnCount) {
                    NSString *str = [self encodedString:(const unsigned char*)sqlite3_column_text(statement, i)];


                NSString *strFieldName = [self encodedString:(const unsigned char*)sqlite3_column_name(statement, i)];

                    [dict setObject:str forKey:strFieldName];
                    i++;
                }

                [allDataArray addObject:dict];
                [dict release];
            }
        }

        sqlite3_finalize(statement);
    } 
    sqlite3_close(database);
    return allDataArray;
}

//Fetch image

NSString *str =[NSString stringWithFormat:@"Select * from Gallery where id = 1"];
NSMutableArray *arra =[Database executeQuery:str];
NSData *d =[[arra objectAtIndex:0] valueForKey:@"ImageName"];
UIImage *img = [[UIImage alloc] initWithData:d];
NSLog(@"%@",img);

Thanks in Advance

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Rushabh
  • 3,208
  • 5
  • 28
  • 51

2 Answers2

2

Your problem is that you cannot insert binary data by building a SQL statement with a stringWithFormat. You're inserting the NSData (binary data) into a field called ImageName, and you cannot use stringWithFormat to build that SQL statement.

Did you really mean to insert the image itself? In that case you'd use SQL like below, with a ? placeholder, and then use sqlite3_bind_blob for column number 1 with your NSData before you call sqlite3_step. Thus, the SQL would look like:

Insert into Gallery(ImageName) VALUES (?)

(As an aside, I'm not a fan of the choice of ImageName for the actual data of the image. I'd either use Image for the actual image data, or ImageName for the name of the image.)

And then, after preparing your SQL, you'd then call:

sqlite3_bind_blob(statement, 1, [dataImage1 bytes], [dataImage1 length], SQLITE_TRANSIENT);

You can then invoke sqlite3_step, like normal, to execute the SQL to insert the data.

When retrieving the data, after you successfully sqlite3_step, you'd use the appropriate sqlite3_column_blob functions:

const void *bytes = sqlite3_column_blob(statement, 0);
int len = sqlite3_column_bytes(statement, 0);
NSData *data = [NSData dataWithBytes:bytes length:len];
UIImage *image = [UIImage imageWithData:data];

Having said that, SQLite is notoriously inefficient in storing large blob data. You might want to store the image in the Documents folder and then just store the filename in your ImageName field.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
0

i think you are getting bytes in string type in

[[arra objectAtIndex:0] valueForKey:@"ImageName"];

so first get string and then convert it to data.

try like this:

NSData* data = [[[arra objectAtIndex:0] valueForKey:@"ImageName"] dataUsingEncoding:NSUTF8StringEncoding];
Armaan Stranger
  • 3,140
  • 1
  • 14
  • 24
  • NSString *str =[NSString stringWithFormat:@"Select * from Gallery where id = 1"]; NSMutableArray *arra =[Database executeQuery:str]; NSData* data = [[[arra objectAtIndex:0] valueForKey:@"ImageName"] dataUsingEncoding:NSUTF8StringEncoding]; UIImage *img = [[UIImage alloc] initWithData:data]; NSLog(@"%@",img); – Rushabh Aug 01 '13 at 12:46
  • what your ImageName contains?? i think you have saved nsdata in string . so we need to get data in string and then convert it to nsdata. so above code should work. show me your data. – Armaan Stranger Aug 01 '13 at 12:51
  • You cannot just take binary `NSData`, throw it into a `NSString`, and then insert that into a SQL statement with `stringWithFormat`. There are tons of problems with that approach. – Rob Aug 01 '13 at 13:00