1

Note:

  1. I have stored NSData in local database.
  2. I want to use it back from local database. But as it is stored in local database as text ,facing issue in converting back it into NSData.
  3. strDbData is object of type NSString here.

I have one NSData stored in local database like <a3829c97 3b1efacb c7680f7e 7e7a95a2>

Now I want to retrive it back, so I am doing as mentioned below but I am receiving error.

1) First way

NSData *myData = (NSData*)strDbData;
NSLog(@"%@",[myData class]);

Error : -[__NSCFString AES256DecryptWithKey:]: unrecognized selector sent to instance 0x1ddcd9c0

2) Second way

NSData *myData = [[NSData alloc]initWithData:(NSData*)strDbData];

Error: -[__NSCFString bytes]: unrecognized selector sent to instance 0x1dd61a40

So how do I convert NSData sotred in local database as 'text' back into NSData ?

EDIT

strDbData = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 6)];

EDIT 2 Storing NSData in database

-(BOOL)updateSingleRow:(NSData*)myData 
{
    @try
    {
        BOOL success = NO;
        sqlite3_stmt    *statement;
        const char *stmt = [[NSString stringWithFormat:@"UPDATE ABC SET XYZ = '%@' WHERE ID = 1 ",myData] UTF8String];
        if (sqlite3_open([databaseFilePath UTF8String], &database) == SQLITE_OK)
        {
            if(sqlite3_prepare_v2(database, stmt, -1, &statement, NULL) == SQLITE_OK)
            {
                if(sqlite3_step(statement) != SQLITE_DONE )
                {
                    NSLog( @"updateSingleRow Error: %s", sqlite3_errmsg(database) );
                }
                else if (sqlite3_total_changes(database)>0)
                {
                    success = YES;
                }
                else if (sqlite3_total_changes(database)==0)
                {
                    NSLog(@"No Updates : %@" , query);
                }
            }
            sqlite3_finalize(statement);
            sqlite3_close(database);
        }
        return success;
    }
    @catch (NSException *exception)
    {
        TRACE_ERROR(@"updateSingleRow", exception.name, exception.description);
    }
}
βhargavḯ
  • 9,786
  • 1
  • 37
  • 59

3 Answers3

2

If the SQLite column contains binary data, you should read it back via

const void *bytes = sqlite3_column_blob(statement, 6);
int length = sqlite3_column_bytes(statement, 6);
NSData *myData = [[NSData alloc] initWithBytes:bytes length:length];

instead of reading it into a string.

To store binary data, use a "prepared statement". (I did not test this code, I hope that it is correct!)

const char *stmt = "UPDATE ABC SET XYZ = ? WHERE ID = 1";
if (sqlite3_prepare_v2(database, stmt, -1, &statement, NULL) == SQLITE_OK) {
    sqlite3_bind_blob(statement, 1, [myData bytes], [myData length], NULL);
    // ...
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • the way you show is correct. I appreciate for this. but why when i print myData while fetching it is printing <3c613338 32396339 37203362 31656661 63622063 37363830 66376520 37653761 39356132 3e>. Why this is so.? Also when i print class of it, it shows NSConcreteData instead NSData – βhargavḯ Apr 12 '13 at 12:03
  • @Bhargavi: That means that you have stored the **string** "" in your database and not binary data. So you have another problem in your code where you save the data. Perhaps you can show that code (I already guess where the problem is :-) – Martin R Apr 12 '13 at 12:09
  • I have edited in question again .please suggest me what I am doing wrong – βhargavḯ Apr 12 '13 at 12:16
  • one more question what should be data type of field in sqlite db for storing NSData binary or blob ? – βhargavḯ Apr 12 '13 at 12:19
  • @Bhargavi: I have updated the answer, I hope that helps. - Probably BLOB, but I am not 100% sure, please try it yourself. – Martin R Apr 12 '13 at 12:29
  • @Bhargavi: Did you make some progress with this problem? Did my answer help? – Martin R Apr 15 '13 at 09:52
  • I will work on that issue afterwards and will implement this way surely. I will tell you which one helped me for sure. :) – βhargavḯ Apr 15 '13 at 09:55
1

Did you try load data as dataWithContentsOfFile:, or initWithBytes:length:, or some else from NSData methods.

Some example:

void* bytedata = [self getByteDataByParam:param];

NSData* loadedData = [NSData dataWithBytes:byteData length:length];
Lexandr
  • 679
  • 1
  • 6
  • 22
-1

Your Database Field should of type Blob instead of String that will solve the problem

M.Shuaib Imran
  • 1,287
  • 16
  • 29