2010-07-23 5 views
6

Bisher habe ich es geschafft, das Einfügen in eine SQLite-Datenbank auf dem iPhone, diese Methode zu erstellen:Einfügen NSData in SQLite auf dem iPhone

- (void) insertToDB :(NSString *)Identifier :(NSString *)Name 
{ 
    sqlite3 *database; 

    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) 
    { 
     char *sql1 = "INSERT INTO table VALUES ('"; 
     const char *sql2 = [Identifier cStringUsingEncoding:[NSString defaultCStringEncoding]]; 
     char *sql3 = "', '"; 
     const char *sql4 = [Name cStringUsingEncoding:[NSString defaultCStringEncoding]]; 
     char *sql5 = "')"; 

     char *sqlStatement[255]; 
     strcpy(sqlStatement, sql1); 
     strcat(sqlStatement, sql2); 
     strcat(sqlStatement, sql3); 
     strcat(sqlStatement, sql4); 
     strcat(sqlStatement, sql5); 

     sqlite3_stmt *compiledStatement; 

     if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) 
     { 
      sqlite3_last_insert_rowid(database); 
      sqlite3_reset(compiledStatement); 
     } 

     sqlite3_finalize(compiledStatment); 
    } 
    sqlite3_close(database); 
} 

Jetzt bei suche ich ein Bild in der Datenbank zu speichern. Bisher habe ich found this:

UIImage *cachedImage = [UIImage imageNamed:@"Icon.png"]; 
NSData *dataForImage = UIImagePNGRepresentation(cachedImage); 

Aber ich habe Probleme beim Versuch, diese NSData in den char-Array einzufügen, die die SQLstatement macht. Jeder hat eine Idee, wie man das macht?

(Ich habe ein Feld in der Datenbank vom Typ Blob dafür).

Dank

+1

Do * nicht * BLOBs in die Datenbank einfügen. Es ist schrecklich ineffizient auf allen Ebenen. Speichern Sie einen Pfad in der Datenbank und fügen Sie das BLOB in das Dateisystem ein. – bbum

+0

Ich würde * hoch * empfehlen die Verwendung der Flying Meat Datenbank Wrapper, die alle diese Probleme für Sie bereits gelöst hat und ist * viel * einfacher zu bedienen: http://github.com/ccgus/fmdb –

Antwort

9

ich sqlite3_stmt anstelle einer Zeichenfolge verwenden würde. Dann könnten Sie verwenden, um den Blob an die vorbereitete Anweisung zu binden.

Aber wirklich, es wäre am besten für Leistung, das Bild auf der Festplatte und den Pfad in der Datenbank zu speichern.

Eine andere Möglichkeit, um Bilddaten in XML zu senden, besteht darin, 64 Daten zu kodieren. Ich habe es hier als eine Kategorie auf NSString:

static char base64EncodingTable[64] = { 
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' 
}; 

@implementation NSString (NSStringCategories) 

+ (NSString *) base64StringFromData: (NSData *)data length: (int)length { 
    unsigned long ixtext, lentext; 
    long ctremaining; 
    unsigned char input[3], output[4]; 
    short i, charsonline = 0, ctcopy; 
    const unsigned char *raw; 
    NSMutableString *result; 

    lentext = [data length]; 
    if (lentext < 1) 
     return @""; 
    result = [NSMutableString stringWithCapacity: lentext]; 
    raw = [data bytes]; 
    ixtext = 0; 

    while (true) { 
     ctremaining = lentext - ixtext; 
     if (ctremaining <= 0) 
      break;   
     for (i = 0; i < 3; i++) { 
      unsigned long ix = ixtext + i; 
      if (ix < lentext) 
       input[i] = raw[ix]; 
      else 
       input[i] = 0; 
     } 
     output[0] = (input[0] & 0xFC) >> 2; 
     output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4); 
     output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6); 
     output[3] = input[2] & 0x3F; 
     ctcopy = 4; 
     switch (ctremaining) { 
      case 1: 
       ctcopy = 2; 
       break; 
      case 2: 
       ctcopy = 3; 
       break; 
    } 

    for (i = 0; i < ctcopy; i++) 
     [result appendString: [NSString stringWithFormat: @"%c",    base64EncodingTable[output[i]]]]; 

    for (i = ctcopy; i < 4; i++) 
     [result appendString: @"="]; 

    ixtext += 3; 
    charsonline += 4; 

    if ((length > 0) && (charsonline >= length)) 
     charsonline = 0; 
    } 
    return result; 
} 
+1

+1 für sqlite3_stmt und zum Speichern der Datei auf der Festplatte statt in der Datenbank –

+0

Danke, ich kann das bis Montag nicht versuchen, aber ich werde zurück melden. Was das Speichern auf der Festplatte betrifft, habe ich das in der Vergangenheit gemacht, aber ich streame und speichere die Bilder. Ich dachte nicht, dass Sie ein Bild im Code auf Festplatte speichern könnten? –

+0

Oh, sicher kannst du. Sie haben die NSData: '[dataForImage writeToFile: Pfad atomar: YES];' Erstellen Sie einen eindeutigen Dateinamen für Ihr Bild und speichern Sie es im Dokumentenverzeichnis. Speichern Sie dann diesen Pfad in der Datenbank. Für etwas über 100 kb oder so ist es viel besser als das Speichern des BLOB in sqlite. – Don