Pull to refresh

Comments 9

NSDictionary *productTotalSumAndAveragePriceGroupedByCountries =
[[[[[Product all
] aggregatedBy:@[
@[kAggregateSum, @«amount»],
@[kAggregatorAverage, @«price»]]
] groupedBy:@[@«country»]
] having:predicate
] execute];
Это вместо обычного SQL-запроса?
Это вместо NSFetchRequest-а. Упомянутый вами request полностью эквивалентен

NSFetchRequest *fetchRequest = [[ALFetchRequest alloc] init];
fetchRequest.managedObjectContext = managedObjectContext;

NSString *entityName = @"Product";
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext];

[fetchRequest setEntity:entity];
[fetchRequest setIncludesPendingChanges:YES];

// sum amount
NSExpression *fieldExp1 = [NSExpression expressionForKeyPath:@"amount"];
NSExpression *agrExp1 = [NSExpression expressionForFunction:agr arguments:@[fieldExp]];
NSExpressionDescription *resultDescription1 = [[NSExpressionDescription alloc] init];
NSString *resultName1 = @"sumAmount";
[resultDescription1 setName:resultName1];
[resultDescription1 setExpression:agrExp1];
[resultDescription1 setExpressionResultType:NSInteger64AttributeType];

// average price
NSExpression *fieldExp2 = [NSExpression expressionForKeyPath:@"price"];
NSExpression *agrExp2 = [NSExpression expressionForFunction:agr arguments:@[fieldExp]];
NSExpressionDescription *resultDescription2 = [[NSExpressionDescription alloc] init];
NSString *resultName2 = @"sumAmount";
[resultDescription2 setName:resultName2];
[resultDescription2 setExpression:agrExp2];
[resultDescription2 setExpressionResultType:NSInteger64AttributeType];

// country
NSDictionary *availableKeys = [entity attributesByName];
NSAttributeDescription *country = [availableKeys valueForKey:@"country"];

fetch.propertiesToFetch = [NSArray arrayWithObjects:country, resultDescription1, resultDescription2, nil];
fetch.propertiesToGroupBy = [NSArray arrayWithObject:country];
fetch.resultType = NSDictionaryResultType;

NSError *error;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:self error:&error];
if (!fetchedObjects || error) {
    NSLog(@"Error: Execution of the fetchRequest: %@, Failed with Description: %@",self,error);
}
return fetchedObjects;


Но читать его легче, на мой взгляд.
Я просто немного не понимаю в чем тут «сахар», если есть язык SQL, на котором все это выглядит куда понятнее. И этому языку уже не один десяток лет.

Я довольно далек от iOS — разработки, наверное дело в том, что нельзя просто так взять и сделать SQL-запрос из данного приложения к этим данным?
Да, просто SQL запрос в CoreData сделать не получится. Но дело не только в этом.

В CoreData есть такая замечательная пара классов как NSFetchedResultsController и UITableViewController. Они очень оптимизированы и удобны в использовании. Так например, даже если в результате выполнения запроса мы получаем миллион записей, то FetchedResultsController загрузит в память только ту часть, которая видна из TableView. Если где-то в другом контроллере кто-то добавит, удалит или изменит содержимое отображаемых данных, то FRC автоматически стянет измененные данные в TableView с использованием приятных глазу анимаций.
Выгоды от CoreData не всегда могут быть столь однозначны. Можно к SQLite взять ActiveRecords или еще какой FMDB и количество кода для UITableViewContoller будет почти таким же, а запросы будут на чистом SQL.

Тут каждый решает сам в каждом конкретном кейсе.
По правде, я не использовал FMDB и интересно извещает ли он об изменениях. То есть, допустим я сделал селект всех продуктов, перешел на другой скрин и там добавил новый продукт. В первый TableView мне придет извещение, что данные изменились и их надо забрать?
Да, если Вы работаете только с sqlite. Но возможности CoreData намного шире чем работа только с одной базой данных.
Конечно, я про sqlite паттерны только и написал. UIDocument никто не отменял вообщем-то)
Sign up to leave a comment.

Articles