Core Data Documentation は、次のように述べています。
[fetched]プロパティに関連付けられたフェッチ要求には並べ替え順序を設定できるため、フェッチされたプロパティに順序を付けることができます。
Xcodeのデータモデルエディタでフェッチされたプロパティのソート記述子を指定するにはどうすればよいですか?関連するフィールドがどこにも見つかりません。これが何か違いを生むなら、私はiPhoneプラットフォーム用に開発しています。
グラフィカルモデルエディターでこれが不可能な場合、コード内のフェッチされたプロパティのフェッチ要求を変更して、並べ替え記述子を含めるにはどうすればよいですか?
モデリングツールには、フェッチリクエストでソート記述子を設定する方法がないようです。
モデルをロードした後、永続ストアコーディネーターに関連付ける前に、ソート順を制御するフェッチされたプロパティの説明を見つけて、それらのフェッチ要求をソートのあるフェッチ要求に置き換えることができるはずです[1]。それらに設定された記述子。
[1]原則として、これは機能するはずです。実際には、私はそうしなかったか、それをテストしていません。
実際にモデルのフェッチされたプロパティを取得し、それにソート記述子を追加できます(ここでもコードで)。これは、Core Dataを使用してテンプレートの1つを選択した場合に、XCodeがAppDelegateで生成する標準的な方法で行いました。
ところで。これにより、データモデル内のすべてのモデルでフェッチされたすべてのプロパティが並べ替えられます。それを使って凝った適応性を得ることができますが、名前で並べ替える必要のあるプロパティをそれぞれがフェッチした7つの別々のモデルの並べ替えを処理する最も簡潔な方法でした。うまく機能します。
/**
Returns the managed object model for the application.
If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
*/
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
// Find the fetched properties, and make them sorted...
for (NSEntityDescription *entity in [managedObjectModel entities]) {
for (NSPropertyDescription *property in [entity properties]) {
if ([property isKindOfClass:[NSFetchedPropertyDescription class]]) {
NSFetchedPropertyDescription *fetchedProperty = (NSFetchedPropertyDescription *)property;
NSFetchRequest *fetchRequest = [fetchedProperty fetchRequest];
// Only sort by name if the destination entity actually has a "name" field
if ([[[[fetchRequest entity] propertiesByName] allKeys] containsObject:@"name"]) {
NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortByName]];
[sortByName release];
}
}
}
}
return managedObjectModel;
}
グラフィカルエディタでそれらを指定しません(私が知る限り)。
フェッチを行うコードでそれらを指定します。
NSFetchRequest* request = [[NSFetchRequest alloc] init];
NSEntityDescription* entity = [NSEntityDescription entityForName:@"whatYouAreLookingFor"
inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
// here's where you specify the sort
NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:@"name" ascending:YES];
NSArray* sortDescriptors = [[[NSArray alloc] initWithObjects: sortDescriptor, nil] autorelease];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];
fetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:@"myCache"];
Tim Shadelのすばらしい答えを使用して、NSManagedObjectサブクラスごとの並べ替えを追加しました...
... Tier.m(NSManagedObjectサブクラス)内...
+ (void)initialize
{
if(self == [Tier class])
{
NSFetchedPropertyDescription *displayLessonPropertyDescription = [[[Tier entityDescription] propertiesByName] objectForKey:@"displayLesson"];
NSFetchRequest *fetchRequest = [displayLessonPropertyDescription fetchRequest];
NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:@"displayOrder" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortByName]];
[sortByName release];
}
}
ただし、残念ながら、並べ替えの機能は多少制限されています。たとえば、少なくともSQLiteバッキングストアでは、数値を含むNSStringであるフィールドを取得して、数値で並べ替えることはできません。ただし、文字列でアルファベット順に並べ替えたり、数値として格納された値でのみ数値で並べ替えたりする限り、フェッチ要求に適用されるNSSortDescriptorは問題なく機能します。
単一のフェッチされたプロパティの場合、Swift 4、Xcode 9.4:
// retrieve the fetched property's fetch request
let fetchedPropertyRequest = (modelName.entitiesByName["entityName"]!.propertiesByName["fetchedPropertyName"] as! NSFetchedPropertyDescription).fetchRequest
// set up the sort descriptors
let sortDescriptors = [NSSortDescriptor(key: "keyName", ascending: true)]
// add the sort descriptors to the fetch request
fetchedPropertyRequest!.sortDescriptors = sortDescriptors
これは、loooonnnnnngggggggの方法と同じです。
// retrieve the fetched property's fetch request
let theEntityDescription: NSEntityDescription = modelName.entitiesByName["entityName"]!
let theFetchedPropertyDescription = theEntityDescription.propertiesByName["fetchedPropertyName"]! as! NSFetchedPropertyDescription
let theFetchedPropertyRequest = theFetchedPropertyDescription.fetchRequest
// set up the sort descriptors
let sortDescriptor1 = NSSortDescriptor(key: "keyName", ascending: true)
let theSortDescriptors = [sortDescriptor1]
// add the sort descriptors to the fetch request
theFetchedPropertyRequest!.sortDescriptors = theSortDescriptors
注:この例では、値を強制的にアンラップします。 実際のコードではオプションの値を考慮に入れてください!
これをNSManagedObject
サブクラスに入れます。
+ (void)initialize
{
if (self != [EntityManagedObjectSubClass class]) return;
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
NSEntityDescription *entityDescription = [managedObjectModel entitiesByName][@"entityName"];
NSFetchedPropertyDescription *fetchedPropertyDescription = [entityDescription propertiesByName][@"fetchedPropertyName"];
NSFetchRequest *fetchRequest = [fetchedPropertyDescription fetchRequest];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"sortDescriptorKey" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
}
EntityManagedObjectSubClass
、entityName
、fetchedPropertyName
、およびsortDescriptorKey
を独自のものに置き換えます。