Sprawdzanie danych podstawowych dla określonych atrybutów podczas tworzenia nowych obiektów i zwracania obiektu, jeśli istnieje, lub tworzenia nowego, jeśli nie istnieje

Mam problem ze sprawdzeniem, czy określony atrybut jednostki istnieje w podstawowej bazie danych (poprzez predykaty) przed utworzeniem nowego obiektu; jeśli obiekt istnieje, wolę go zwrócić niż utworzyć nowy obiekt.

Mam prostą aplikację, która ma widok tabeli z przyciskiem plus na pasku nawigacji; użytkownik klika to i wyświetla kontroler widoku z 4 polami tekstowymi. Wypełniają te informacje, naciskają Save i zostają zapisane w Core Data i wyświetlane w TableView (za pomocą NSFetchedResultsControllers).

Model danych jest następujący:

Jednostka transakcji z atrybutem isReceived BOOL Osoba Entity z nazwą atrybut atrybut Okazja Jednostka z tytułem ciąg atrybut Atrybut Element z kwotą atrybut string

Transakcja ma związek z jednostkami Person (whoBy), Occasion (Occasion) i Item.

W kontrolerze widoku za pomocą metody składowania mam poniższy kod, który będzie wstawiał nowe obiekty do transakcji, osób, obiektów okazji itp. Każda transakcja jest oczywiście unikalna, ale przy każdej transakcji użytkownik może wybrać istniejącą OSOBĘ i / lub Okazja, a jeśli ta osoba nie istnieje, zostanie utworzona (podobnie z okazji).

Jestem nieco zmieszany co do formatu kodu tutaj.

EDYTUJ: Próbowałem kombinacji kodu i po prostu nie mogę tego uzyskać. W poniższym kodzie odwołuję się do person.name w predykacie, ale próbowałem również utworzyć lokalną zmienną NSString, aby pomieścićself.nameTextField.text kod, ale nic nie zrobił. Próbowałem utworzyć właściwość NSString, aby odwołać się do niej w ten sposób, a to nie działa. Próbowałem użyć słówMATCHES, LIKE, CONTAINS, == i każda kombinacja między nimi.

- (IBAction)save:(id)sender
{
    NSManagedObjectContext *context = [self managedObjectContext];
    Transaction *transaction= [NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:context];
    Person *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
    Occasion *occasion = [NSEntityDescription insertNewObjectForEntityForName:@"Occasion" inManagedObjectContext:context];
    Item *amount = [NSEntityDescription insertNewObjectForEntityForName:@"item" inManagedObjectContext:context];

 NSFetchRequest *personFind = [NSFetchRequest fetchRequestWithEntityName:@"Person"];

    personFind.predicate = [NSPredicate predicateWithFormat:@"name == %@", person.name];
    // I have tried every combination of the predicate like MATCHES, LIKE. 
    // I created a local NSString variable and an NSString property
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
    personFind.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

    NSError *error = nil;
    NSArray *matches = [context executeFetchRequest:personFind error:&error];

    if (!matches || ([matches count] > 1))
    {
        // Handle Error
    }
    else if ([matches count] == 0)
    {
        person.name = self.nameTextField.text;
        transaction.whoBy = person;
        occasion.title = self.occasionTextField.text;
        transaction.occasion = occasion;
    }

    else
    {
        person = [matches lastObject];
        transaction.whoBy = person; 
        occasion.title = self.occasionTextField.text
        transaction.occasion = occasion; 
    }


if (![context save:&error])
    {
        NSLog(@"Can't save! %@ %@", error, [error localizedDescription]);

    }
    [self dismissViewControllerAnimated:YES completion:nil];

}

Logicznie rzecz biorąc, to co chcę osiągnąć to:

Gdy użytkownik dodaje transakcję, sprawdź, czy jest to nowa osoba lub istniejąca - jeśli jest to już istniejąca, wybierz ją z listy osób (a gdy użytkownik wybierze osobę, pobierz jej identyfikator NSManagedObjectID). Jeśli jest nowy, utwórz go na miejscu.

To samo z okazji.

Ustaw wszystkie pozostałe pola obiektu Transakcji (kwota itp.).

Moje pytanie brzmi:

Jakiego predykatu używam, aby to działało?

Kiedy umieściłem punkt przerwania w tej metodzie, NOWA NAZWA (taka, która wcześniej nie istniała) poprawnie wywołujeelse if ([matches count] == 0) metoda i jeśli utworzę wpis o istniejącej nazwie, wywołuje on

else
        {
            person = [matches lastObject];
            transaction.whoBy = person; 
            occasion.title = self.occasionTextField.text
            transaction.occasion = occasion; 
        }

Nawet z tym stwierdzeniem nadal tworzy nowy obiekt osoby o tej samej nazwie.

Prawidłowo wdrożę tę okazję po otrzymaniu pracy, ale jestem po prostu zgubiony, jak to zrobić.

Każda pomoc byłaby bardzo mile widziana!

questionAnswers(1)

yourAnswerToTheQuestion