Nicolas Charvoz
Nicolas Charvoz

Reputation: 1509

Create NSMutableDictionary with NSString

I want to create a NSMutableDictionnary with a NSString.

-(NSMutableDictionary *)getList{
//Declaration d'un objet SQLITE
sqlite3 *database;

//Declaration de notre String qui sera retourne
NSMutableDictionary *aromaArray = [[NSMutableDictionary alloc] init];

// Ouverture de la base de donnees
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {

    //Chaine de caracteres de la requete
    const char *sqlStatement = "SELECT name_fr FROM aroma_huiles";

    //Creation de l'objet statement
    sqlite3_stmt *compiledStatement;

    //Compilation de la requete et verification du succes
    if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {

        // Creation d'un dictionnaire des noms de colonnes
        NSDictionary *dictionary = [self indexByColumnName:compiledStatement];
        //char **final = malloc(4096 * sizeof(*final));
        NSMutableArray *array = [[NSMutableArray alloc] init];

        while(sqlite3_step(compiledStatement) == SQLITE_ROW) {

            //Assigne la valeur dans la chaine de caracteres
            char *tab;
            tab = (char*)sqlite3_column_text(compiledStatement, [[dictionary objectForKey:@"name_fr"] intValue]);
            NSString *final = [NSString stringWithUTF8String:tab];
            if (final != nil) {
                NSString *firstLetter = [final substringToIndex:1];
                [aromaArray setObject:final forKey:firstLetter];
            }
        }
    }
    else {
        //Envois une exception en cas de probleme de requete
        NSAssert1(0, @"Erreur :. '%s'", sqlite3_errmsg(database));
    }

    // Finalisation de la requete pour liberer la memoire
    sqlite3_finalize(compiledStatement);

}
else {
    //Envois une exception en cas de probleme d'ouverture
    NSAssert(0, @"Erreur d'ouverture de la base de donnees");
}
//Fermer la base de donnees
sqlite3_close(database);

//Retourne la valeur
return aromaArray;

}

I think this is the easiest method, only 2 lines, but It still reject it :

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString count]: unrecognized selector sent to instance 0x1093180c0'

Upvotes: 0

Views: 135

Answers (5)

Nicolas Charvoz
Nicolas Charvoz

Reputation: 1509

So I finally manage to fix the problem ! Simple solution, a bit slow but still it works now ! My problem was totally different than what I thought at the begining. I tried to make a Dictionnary with NSString, and the values were replaced at each loop .. So I only got 20 products when I had 84 at the begining, the Dictionnary was built, but It crashed because I nedded a DIctionnary made with NSArray ! I didn't notice that, so I finally find the solution (I will replace the while with for) :

tab = (char*)sqlite3_column_text(compiledStatement, [[dictionary objectForKey:@"name_fr"] intValue]);
            NSString *final = [NSString stringWithUTF8String:tab];
            if (final != nil && final.length >0) {
                [array addObject:final];
            }
        }
        int i = 0;
        int j = 0;
        NSMutableArray *table = [[NSMutableArray alloc] init];
        while (i < [array count])
        {
            NSString *firstLetter = [array[i] substringToIndex:1];
            table = [[NSMutableArray alloc] init];
            while (j < [array count])
            {
                NSString *secondLetter = [array[j] substringToIndex:1];
                if ([secondLetter isEqualToString:firstLetter]) {
                    [table addObject:array[j]];
                }
                j++;
            }
            j = 0;
            [aromaArray setObject:table forKey:firstLetter];
            i++;
        }

Thank you all for your help :)

Upvotes: 0

Lithu T.V
Lithu T.V

Reputation: 20021

I think the reason for the crash is these lines

 tab = (char*)sqlite3_column_text(compiledStatement, [[dictionary objectForKey:@"name_fr"] intValue]);
 NSString *final = [NSString stringWithUTF8String:tab];

if the char value is nil and is converted to the string value an exception may come.ie the case appear when basically there is no value in the corresponding row in table.

so try

tab = (char*)sqlite3_column_text(compiledStatement, [[dictionary objectForKey:@"name_fr"] intValue]);
if(tab){
     NSString *final = [NSString stringWithUTF8String:tab];
     //everything else that comes under is to be here
}

Upvotes: 0

Hemant Singh Rathore
Hemant Singh Rathore

Reputation: 2139

Why don't you directly create dictionary while you fetch data from DB

while(sqlite3_step(compiledStatement) == SQLITE_ROW) {

            //Assigne la valeur dans la chaine de caracteres
            char *tab;
            tab = (char*)sqlite3_column_text(compiledStatement, [[dictionary objectForKey:@"name_fr"] intValue]);
            NSString *final = [NSString stringWithUTF8String:tab];
            if (final != nil && final.length >0) {
//get substring from string here
NSString *firstLetter = [final substringToIndex:1];
//Add objects in dictionary here
                    [aromaArray setObject:final forKey:firstLetter];
            }
        }

Upvotes: 0

user2828120
user2828120

Reputation: 233

Change while (array[j]) to while (j < [array count])

Upvotes: 0

Lars Blumberg
Lars Blumberg

Reputation: 21461

What you see is that your array variable is accessed outside of its bounds. There is simply no element after index 66 as it contains only 67 elements.

You are using a hard to read loop constructs when iterating over array. Instead of while in your case you can transform your loops to use the for construct:

for (int j = 0; j < [array count]; j++) {
...
    for (int i = 0; i < [array count]; i++) {
    ...
    }
}

Doing so there's no need anymore for resetting i to 0 and there's no need for increasing i and j outside of the loop header (remove i++ and j++ statements at the bottom of your loops).

Upvotes: 1

Related Questions