Создание уникального идентификатора для программы Core Data на iPhone

У меня возникли проблемы с этим материалом Core Data. Как создать новую запись с уникальным идентификатором? В SQL я бы просто объявил одно поле в качестве поля автоинкремента. Я не вижу ничего подобного здесь, но я мог просто что-то упустить. Я просто хочу автоматически увеличивать поле NSInteger, поэтому, когда я вручную добавляю элементы в базу данных, у меня будет какая-то форма ссылки на них.

Ответ 1

Хотя я согласен с тем, что вы сказали, есть механизм ID за основными данными. Идентификатор действительно управляется Core-Data, но вы можете получить их с помощью:

NSManagedObjectID *moID = [managedObject objectID];

Для получения дополнительной информации см. Руководство по программированию основных данных

Ответ 2

Это не так, как работает CoreData.

В CoreData вы создаете экземпляры объектов. Каждый экземпляр уникален. Затем вы извлекаете и обрабатываете экземпляры по мере необходимости. CoreData заботится о сохранении для вас, включая уникальные идентификационные экземпляры.

Откажитесь от всего, что вы знаете о традиционных реляционных базах данных.

Начните здесь.

Затем перейдите здесь.

В частности, this.

CoreData - это невероятно мощный бит технологии, который предлагает функции, выходящие за рамки базы данных, такие как постоянство. Это сэкономит вам много строк кода и будет очень хорошо работать, если вы его примете.

Ответ 3

Эта функция класса вернет следующий доступный номер для вашего свойства id (оно должно быть целочисленным).

Я называю это автоинкрементным генератором. Я по-прежнему согласен с другими, что для этого существует objectID, но иногда вам просто нужен номер.

Вы можете поместить эту функцию в свой подкласс NSManagedObject для объекта:

+(NSNumber *)nextAvailble:(NSString *)idKey forEntityName:(NSString *)entityName inContext:(NSManagedObjectContext *)context{


    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSManagedObjectContext *moc = context;
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:moc];

    [request setEntity:entity];
    // [request setFetchLimit:1];

    NSArray *propertiesArray = [[NSArray alloc] initWithObjects:idKey, nil];
    [request setPropertiesToFetch:propertiesArray];
    [propertiesArray release], propertiesArray = nil;

    NSSortDescriptor *indexSort = [[NSSortDescriptor alloc] initWithKey:idKey ascending:YES];
    NSArray *array = [[NSArray alloc] initWithObjects:indexSort, nil];
    [request setSortDescriptors:array];
    [array release], array = nil;
    [indexSort release], indexSort = nil;

    NSError *error = nil;
    NSArray *results = [moc executeFetchRequest:request error:&error];
    // NSSLog(@"Autoincrement fetch results: %@", results);
    NSManagedObject *maxIndexedObject = [results lastObject];
    [request release], request = nil;
    if (error) {
        NSLog(@"Error fetching index: %@\n%@", [error localizedDescription], [error userInfo]);
    }
    //NSAssert3(error == nil, @"Error fetching index: %@\n%@", [error localizedDescription], [error userInfo]);

    NSInteger myIndex = 1;
    if (maxIndexedObject) {
        myIndex = [[maxIndexedObject valueForKey:idKey] integerValue] + 1;
    }

    return [NSNumber numberWithInteger:myIndex];
}

Ответ 4

Взгляните на: [[NSProcessInfo processInfo] globallyUniqueString].

Документы Apple: Глобальный идентификатор для процесса. Идентификатор включает имя хоста, идентификатор процесса и отметку времени, которая гарантирует, что идентификатор уникален для сети, что удобно, если вы не хотите, чтобы люди угадали идентификатор.

Ответ 5

Вот три вида уникального ID-представления объекта CoreData:

NSManagedObjectID *taskID = [task objectID];
NSURL *taskUniqueURLKey = task.objectID.URIRepresentation;
NSString *taskUniqueStringKey = task.objectID.URIRepresentation.absoluteString;

!!!! Примечание: если вы хотите использовать выше уникальный ключ в качестве индекса, убедитесь, что объект сохранен в контексте перед его использованием, или objectID будет временным идентификатором, который будет заменен позже (например, после сохранены). См. Документ Apple класса NSManagedObjectID:

- (BOOL)isTemporaryID;    // indicates whether or not this ID will be replaced later, 
such as after a save operation (temporary IDs are assigned to newly inserted objects 
and replaced with permanent IDs when an object is written to a persistent store); most
 IDs return NO

Ответ 6

Что делать, если мы хотим синхронизировать с удаленной базой данных, которая нуждается в автоинкрементном идентификаторе для уникальных строк данных? Есть ли способ реализовать autoincremented id, если нам нужно. Я понимаю, что это не требуется для основных данных, но мне нужно импортировать данные из удаленной базы данных, а затем снова загружать и удостоверять, что идентификатор не поврежден.

Ответ 7

Я думаю, что это будет полезно в таких условиях.

http://lists.apple.com/archives/cocoa-dev/2006/Jul/msg01801.html Мы можем получить maxExistingID. Таким образом, мы можем увеличить это при сохранении нового элемента

Ответ 8

Обновить в @Lukasz ответ в Swift:

static func nextAvailble(_ idKey: String, forEntityName entityName: String, inContext context: NSManagedObjectContext) -> Int {
    let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: entityName)
    fetchRequest.propertiesToFetch = [idKey]
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: idKey, ascending: true)]

    do {
        let results = try context.fetch(fetchRequest)
        let lastObject = (results as! [NSManagedObject]).last

        guard lastObject != nil else {
            return 1
        }

        return lastObject?.value(forKey: idKey) as! Int + 1

    } catch let error as NSError {
        //handle error
    }

    return 1 
}

Ответ 9

Основные данные используются для инфраструктуры persistance, эта структура абстрагирует первичный ключ.

Каждый NSManagedObject имеет свой собственный уникальный ключ, встроенный в который доступен в свойстве objectID.

Этот идентификатор внутренне используется для связывания объектов над его отношениями. Нет необходимости поддерживать собственный идентификатор в качестве первичного ключа, как вы привыкли делать в SQL.

Вы всегда можете получить идентификатор NSManagedObject.objectID. и выборку объектного контекста с помощью NSMananagedObjectContext.objectWithId