Michael
Michael

Reputation: 303

Core Data - How can I get the max value from an entity attribute (Swift)


Recipe

I have an entity Recipe with an attribute recipeID. How can I get the max(recipeID) as an Int value in Swift?

I'm new in swift, please help me. Thanks in advance.

func fetchMaxID() {
    let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
    let fetchRequest = NSFetchRequest(entityName: "Recipe")

    fetchRequest.fetchLimit = 1
    let sortDescriptor = NSSortDescriptor(key: "recipeID", ascending: false)
    fetchRequest.sortDescriptors = [sortDescriptor]
    do {
        let maxID = try [managedObjectContext?.executeFetchRequest(fetchRequest)].first
        print(maxID)
    } catch _ {

    }
}

Upvotes: 11

Views: 5806

Answers (4)

Mark
Mark

Reputation: 11

To check the max of an entity attribute you can simply use:

func findMaxRecipeID() -> Int {
    let maxRecipeID = recipe?.value(forKeyPath: "[email protected]") as! Int
    return maxRecipeID
}

You can use this to @sum, @max, @min, @count - saves quite a few lines of code.

Upvotes: 0

jarora
jarora

Reputation: 5762

The way that Apple recommends and is the fastest is using NSExpressions. moc is a NSManagedObjectContext.

private func getLastContactSyncTimestamp() -> Int64? {

    let request: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest()
    request.entity = NSEntityDescription.entity(forEntityName: "Contact", 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
}

Upvotes: 13

Mochi
Mochi

Reputation: 1117

Learning from Ray Wenderlich's Core Data Tutorial

https://www.raywenderlich.com/115695/getting-started-with-core-data-tutorial/

func fetchMaxRecipe() {
    let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
    let fetchRequest = NSFetchRequest(entityName: "Recipe")

    fetchRequest.fetchLimit = 1
    let sortDescriptor = NSSortDescriptor(key: "recipeID", ascending: false)
    fetchRequest.sortDescriptors = [sortDescriptor]
    do {
        let recipes = try context.executeFetchRequest(fetchRequest) as! [Recipe]
        let max = recipes.first
        print(max?.valueForKey("recipeID") as! Int)
    } catch _ {

    }
}

Hope this helps =).

Upvotes: 5

Michael
Michael

Reputation: 303

func fetchMaxID() {
    let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
    let fetchRequest = NSFetchRequest(entityName: "Recipe")

    fetchRequest.fetchLimit = 1
    let sortDescriptor = NSSortDescriptor(key: "recipeID", ascending: false)
    fetchRequest.sortDescriptors = [sortDescriptor]
    do {
        let results = try context.executeFetchRequest(fetchRequest) as! [Recipe]
        if (results.count > 0) {
            for result in results {
                print(result.recipeID!)
            }
        } else {
            print("No Recipe")
        }
    } catch let error as NSError {
        // failure
        print("Fetch failed: \(error.localizedDescription)")
    }

}

This works also!

Upvotes: 2

Related Questions