Swift3 CoreData에서 Group By해서 MAX 값 구하기

2016. 10. 2. 01:47아이폰 개발

Swift CoreData 사용 방법

http://avilos.codes/mobile/ios-swift/ios-swift-%EC%BD%94%EC%96%B4%EB%8D%B0%EC%9D%B4%ED%84%B0core-data/




//Group by, MAX 구하기

        let quantityExpression = NSExpressionDescription()

        quantityExpression.name = "max.timestamp"

        quantityExpression.expression = NSExpression(forFunction: "max:", arguments: [NSExpression(forKeyPath: "timestamp")])

        quantityExpression.expressionResultType = .dateAttributeType

        

        let request2: NSFetchRequest<NSFetchRequestResult> = Test.fetchRequest()

        request2.entity = NSEntityDescription.entity(forEntityName: "Test", in: context)

        request2.propertiesToGroupBy = ["address"]

        request2.resultType = NSFetchRequestResultType.dictionaryResultType

        request2.propertiesToFetch = [quantityExpression]

        

        do {

            let results = try context.fetch(request2)

            

            print(results.count)

            print(results)

          } catch let error as NSError {

            fatalError("Error fetching max sequence: \(error)")

        }



* Object-C로 Group by Max Value를 구하는 방법

http://stackoverflow.com/questions/35860513/fetch-all-other-values-in-row-for-maximum-value-of-group-by-using-core-data-in-o


NSExpression *dateKeyExpression = [NSExpression     expressionForKeyPath:@"date"];
NSExpression *maxDateExpression = [NSExpression expressionForFunction:@"max:" arguments:[NSArray arrayWithObject:dateKeyExpression]];
NSExpressionDescription *maxDateED = [[NSExpressionDescription alloc] init];
[maxDateED setExpression:maxDateExpression];
[maxDateED setName:@"maxDate"];
[maxDateED setExpressionResultType:NSDateAttributeType];

NSAttributeDescription *clientName = [[self entityDescription].attributesByName objectForKey:@"clientName"];
[request setPropertiesToFetch:[NSArray arrayWithObjects:clientName, maxDateED, nil]];
[request setPropertiesToGroupBy:[NSArray arrayWithObject:clientName]];
[request setResultType:NSDictionaryResultType];


* Swift는 아니지만 Max value 구하는 방법

http://stackoverflow.com/questions/10398019/core-data-how-to-fetch-an-entity-with-max-value-property


- (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;
}


* Swift 3에서의 FetchRequest

https://developer.apple.com/library/content/releasenotes/General/WhatNewCoreData2016/ReleaseNotes.html


func findAnimals() {
    let request: NSFetchRequest<Animal> = Animal.fetchRequest
    do {
        let searchResults = try context.fetch(request)
        ... use(searchResults) ...
    } catch {
        print("Error with request: \(error)")
    }
}


* Swift 3에서 managedObjectContext 구하는 방법

http://stackoverflow.com/questions/37956720/how-to-create-managedobjectcontext-using-swift-3-in-xcode-8


let context = (UIApplication.shared().delegate as! AppDelegate).persistentContainer.viewContext
lazy var persistentContainer: NSPersistentContainer = {

    let container = NSPersistentContainer(name: "you_model_file_name")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error {

            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()

* swift 3에서 manage Object Context를 이용하여 새로운 객체를 생성하는 방법

http://stackoverflow.com/questions/38339167/swift-3-core-data-nsentitydescription-is-nil


let newPerson = Person(context: context)
newPerson.first = "Thomas"

* Swift 3에서 현재 날짜 구하는 방법

https://stackoverflow.com/questions/39513258/get-current-date-in-swift-3


let date = NSDate()
let calendar = NSCalendar.current
let components = calendar.dateComponents([.year, .month, .day, .hour], from: date as Date)

let year =  components.year
let month = components.month
let day = components.day

print(year)
print(month)
print(day)

* Could not cast value of type 'NSKnownKeysDictionary1' (0x10d02d328) to 'MyProject.Day' 오류 발생시 해결 방법

http://stackoverflow.com/questions/39521384/swift-3-core-data-nsexpression-forfunction-sum-throws-error-could-not-ca


let sumRequest: NSFetchRequest<NSFetchRequestResult> = Day.fetchRequest()




* Swift CoreData Max query라고 하는데 도움이 안되는 예제

https://www.vankuik.nl/2016-05-24_Swift_example_of_CoreData_max_query