usa plus españa apple iphone objective-c ios core-data nsfetchedresultscontroller

iphone - plus - Datos principales: cómo recuperar una entidad con la propiedad de valor máximo



iphone xs (5)

Establece fetchLimit en 1 y ordena por personId de personId en orden descendente. P.ej:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Person"]; fetchRequest.fetchLimit = 1; fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"personId" ascending:NO]]; NSError *error = nil; id person = [managedObjectContext executeFetchRequest:fetchRequest error:&error].firstObject;

Tengo una entidad Person con una propiedad personId (personId es único)

¿Cómo puedo buscar a la Persona con el máximo ID de persona?

(Quiero buscar a la persona en sí, no el valor de la propiedad)


La forma recomendada es utilizar el Método recomendado de Apple NSExpression. Esperaría que esto fuera menos costoso que usar un ordenamiento. Si lo piensas bien, con un tipo, deberías tomar todos los registros para clasificarlos y mantener el máximo. Con una expresión solo tendrías que leer la lista y mantener en la memoria el máximo.

Aquí hay un ejemplo que uso con NSDate

- (NSDate *)lastSync:(PHAssetMediaType)mediaType { NSEntityDescription *entity = [NSEntityDescription entityForName:kMediaItemEntity inManagedObjectContext:self.managedObjectContext]; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; fetchRequest.entity = entity; fetchRequest.resultType = NSDictionaryResultType; NSMutableArray *predicates = [NSMutableArray array]; [predicates addObject:[NSPredicate predicateWithFormat:@"%K=%d", kMediaType,mediaType]]; [predicates addObject:[NSPredicate predicateWithFormat:@"%K=%d", kMediaProviderType,self.mediaProviderType]]; NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates: predicates]; fetchRequest.predicate = predicate; // Create an expression for the key path. NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:kSyncTime]; // Create an expression to represent the function you want to apply NSExpression *maxExpression = [NSExpression expressionForFunction:@"max:" arguments:@[keyPathExpression]]; // Create an expression description using the maxExpression and returning a date. NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; [expressionDescription setName:@"maxDate"]; [expressionDescription setExpression:maxExpression]; [expressionDescription setExpressionResultType:NSDateAttributeType]; // Set the request''s properties to fetch just the property represented by the expressions. fetchRequest.propertiesToFetch = @[expressionDescription] ; // @[kSyncTime]; NSError *fetchError = nil; id requestedValue = nil; // fetch stored media NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&fetchError]; if (fetchError || results == nil || results.count == 0) { return [NSDate dateWithTimeIntervalSince1970:0]; } requestedValue = [[results objectAtIndex:0] valueForKey:@"maxDate"]; if (![requestedValue isKindOfClass:[NSDate class]]) { return [NSDate dateWithTimeIntervalSince1970:0]; } DDLogDebug(@"sync date %@",requestedValue); return (NSDate *)requestedValue; }


La respuesta dada anteriormente usando NSExpression es correcta. Aquí está la versión Swift.

private func getLastSyncTimestamp() -> Int64? { let request: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest() request.entity = NSEntityDescription.entity(forEntityName: "EntityName", in: self.moc) request.resultType = NSFetchRequestResultType.dictionaryResultType let keypathExpression = NSExpression(forKeyPath: "timestamp") let maxExpression = NSExpression(forFunction: "max:", arguments: [keypathExpression]) let key = "maxTimestamp" let expressionDescription = NSExpressionDescription() expressionDescription.name = key expressionDescription.expression = maxExpression expressionDescription.expressionResultType = .integer64AttributeType request.propertiesToFetch = [expressionDescription] var maxTimestamp: Int64? = nil do { if let result = try self.moc.fetch(request) as? [[String: Int64]], let dict = result.first { maxTimestamp = dict[key] } } catch { assertionFailure("Failed to fetch max timestamp with error = /(error)") return nil } return maxTimestamp }

donde moc es un NSManagedObjectContext.


Necesita usar NSFetchRequest con NSPredicate para especificar su consulta ...

Adaptado de la Guía de programación de predicados de Apple:

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:managedObjectContext]; [request setEntity:entity]; request.predicate = [NSPredicate predicateWithFormat:@"personId==max(personId)"]; request.sortDescriptors = [NSArray array]; NSError *error = nil; NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];


Swift 3

let request:NSFetchRequest = Person.fetchRequest() let sortDescriptor1 = NSSortDescriptor(key: "personId", ascending: false) request.sortDescriptors = [sortDescriptor1] request.fetchLimit = 1 do { let persons = try context.fetch(request) return persons.first?.personId } catch { print(error.localizedDescription) }