Giacomoni
Giacomoni

Reputation: 1468

Core-data many-to-many relationship

I have an Android app, and now I'm making an iOS version, but I'm having some problem with the joins in CoreData.

I have the following tables:

Cidade
    -cid_codigo integer primary key
    -cid_nome text
    -cid_nome_normalizado text

Anunciante
    -anu_codigo integer primary key
    -anu_nome text
    -some other values

AnuncianteCidade
    -cid_codigo integer
    -anu_codigo integer

To get the all data from table Cidade I use the following method:

+(NSMutableArray *)getAllCidades{
    NSMutableArray *retorno = [[NSMutableArray alloc] init];

    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"Cidade" inManagedObjectContext:context];

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entityDesc];

    //WHERE CLAUSE
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"1 = 1"];
    [request setPredicate:pred];

    NSError *error;
    NSArray *cidades = [context executeFetchRequest:request error:&error];

    if([cidades count] == 0){
        NSLog(@"Nenhuma cidade encontrada");
    }else{
        for(NSManagedObject *cidade in cidades){
            Cidade *c = [[Cidade alloc] init];
            [c initWithCodigo:[[cidade valueForKey:@"cid_codigo"] integerValue] nome:[cidade valueForKey:@"cid_nome"] nomeNormalizado:[cidade valueForKey:@"cid_nome_normalizado"]];
            [retorno addObject:c];
        }
    }

    return retorno;
}

But now, given a name from Cidade, I want to get all the data from Anunciante associated with this Cidade.

How can I do that?

Upvotes: 1

Views: 157

Answers (2)

Marcus S. Zarra
Marcus S. Zarra

Reputation: 46728

Core Data is not a database. Core Data is an object graph that happens to persist to disk and one of the formats that Core Data can persist to is a database structure. This is an important distinction that will help you to work with it moving forward.

First, you cannot call just -init on a NSManagedObject. That will not work as it is not the designated initializer of NSManagedObject. I would suggest you read up on Core Data and learn how to stand up the Core Data stack.

Having said that, your Cidade objects should have a reference to Anunciante. The join table is internal to Core Data and you don't have access to it nor should you. To get all of the Anunciante objects for a Cidade object is to simply request the objects:

Given an NSArray of Cidade objects:

NSArray *objects = ...;
for (NSManagedObject *object in objects) {
  NSSet *anunciantes = [object valueForKey:@"anunciante"];
}

This is assuming you have a many to many relationship defined in the Core Data model editor between the Cidade and the Anunciante entities.

Upvotes: 2

Mundi
Mundi

Reputation: 80271

In addition to Marcus' answer, I would add that a predicate "1 = 1" could be simply left out.

To insert a managed object into the context you use a NSEntityDescription class method:

Cidade *cidade = [NSEntityDescription insertNewObjectForEntityForName:@"Cidade" 
      inManagedObjectContext:context];

All "anunciantes" of a cidade will be conveniently available to you as a NSSet:

cidade.anunciantes

is all you need.

Upvotes: 1

Related Questions