2016-05-28 31 views
0

私の関係は下の画像のようになります。CoreData関係で並べ替え

CoreData relation

私は積極的に推進して、その後、開始日であるもので最初のイベントをソートしたいと思います。プロモーションは、現在の日付が開始日と終了日の間にある場合にアクティブになります。残念ながら、CoreDataのために、私は並べ替えのために一時的なプロパティを使用することができません。私のコントローラでは、フェッチコントローラを使用していません。

これを達成する方法はありますか?

更新:

私は、ソート記述子を以下ました:

// First is incorrect 
[NSSortDescriptor(key: "promotion.start", ascending: false), 
NSSortDescriptor(key: "start", ascending: true)] 

述語(彼らはOKだ、しかし):

let promotionsPredicate = 
    NSPredicate(format: "(%@ >= promotion.start && %@ <= promotion.end) && " + 
       "(ANY promotion.cities.id == %@)", NSDate(), NSDate(), objectID) 
let eventsPredicate = 
    NSPredicate(format: "start >= %@ && venue.city.id == %@", 
           NSDate(), objectID) 

let subpredicates = [eventsPredicate, promotionsPredicate]      
let compoundPredicate NSCompoundPredicate(orPredicateWithSubpredicates: subpredicates) 

そして、これは要求(IですCoreStoreを使用していますが、このアイデアは明確でなければなりません)。

class func pagedEventsForPredicateSortedByInPromoAndStartDate(predicate: NSPredicate, 
                   descriptors: [NSSortDescriptor], 
                   fetchOffset: Int, 
                   fetchLimit: Int) -> [Event] { 

    return CoreStore.fetchAll(From(Event), 
           Where(predicate), 
           OrderBy(descriptors), 
           Tweak { (fetchRequest) -> Void in 
           fetchRequest.fetchOffset = fetchOffset 
           fetchRequest.fetchLimit = fetchLimit 
           fetchRequest.returnsObjectsAsFaults = false 
     }) ?? [] 
} 
+0

はい。しかし、より多くの助けが必要な場合は、いくつかのコード(およびあなたがそれをやりたい言語)を表示してください。 – sschale

+0

ありがとう、私はスイフトを使用していますが、言語は私にとって重要ではありません。明日の簡単なコードで私の答えを更新します。 – apetrov

+0

何が問題なのですか? – Fogmeister

答えて

1

私はあなたがすべてのEventオブジェクトを取得しなければならないことを理解したが、正しい順序である。このような複雑な順序でそれを行うには、それは私の知る限りでは、あなたがすべてのイベントを取得し、その後NSArray's方法ここで

- (NSArray<ObjectType> *)sortedArrayUsingComparator:(NSComparator)cmptr 

を使用してそれらを並べ替えるコード

1の部分があるために持って、関係を含み。フェッチ

// get the right context here 
NSManagedObjectContext *yourContext; 

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Event"]; 
// extra line, predicate is nil by default, any other required predicate could be written here 
request.predicate = nil; 

__block NSArray *results = nil; 
[yourContext performBlockAndWait:^{ 

    NSError *error = nil; 
    results = [yourContext executeFetchRequest:request error:&error]; 

     if (error) { 
      // handle error here 
     } 
    }];

コアデータからフェッチコアメソッドを使用して手動で行われ、あなたはMagical Recordまたは行にそれを作るためにコアデータで動作する他のフレームワークを使用してもよいです。結果

__weak typeof(self) weakSelf = self; 

NSDate *now = [NSDate date]; 
NSArray *sortedResults = [results sortedArrayUsingComparator:^NSComparisonResult(Event *_Nonnull obj1, Event *_Nonnull obj2) { 

    BOOL isObj1InActivePromotion = [weakSelf date:now isBetweenDate:obj1.promotion.start andDate:obj1.promotion.end]; 
    BOOL isObj2InActivePromotion = [weakSelf date:now isBetweenDate:obj2.promotion.start andDate:obj2.promotion.end]; 

    // if they eather are in active promotion or no, just compare them by start date of the Event 
    if (isObj1InActivePromotion == isObj2InActivePromotion) { 
     return [obj1.start compare:obj2.start]; 
    } else { 
     return isObj1InActivePromotion ? NSOrderedAscending : NSOrderedDescending; 
    } 
}]; 

3. NSDate

で動作するように追加の方法は、この方法は、私がcould't方法

+ (BOOL)date:(NSDate *)date isBetweenDate:(NSDate *)beginDate andDate:(NSDate *)endDate 
{ 
    if ([date compare:beginDate] == NSOrderedAscending) { 
     return NO; 
    } 

    if ([date compare:endDate] == NSOrderedDescending) { 
     return NO; 
    } 

    return YES; 
} 

をソートに使用された

2.ソート明白な理由のためにコードをチェックしてください。

+0

ありがとう、本当にあなたの答えに感謝します。私はすでに第3の部分ライブラリ(CoreStore)を使用していますが、あなたのコードは明確で完全に読みやすいです。バッチごとにデータを取得していますので、新しいバッチがすべてフィルタされるたびにフィルタリングする必要があります。だからおそらく私は別の方向に取ると私の結果(ソートされた配列)のための別の構造を試してください。 – apetrov

1

アクティブなレコードを計算するために、プロモーションエンティティで "isActive"トランスセクションプロパティを作成することをお勧めします。その後

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Event"]; 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] 
            initWithKey:@“start” ascending:YES]; 
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
[fetchRequest setIncludesPropertyValues:YES]; 
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 

あなたは、ソートすることにより、結果としてフェッチフィルタリングすることができます:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@“isActive == %@", @1]; 
     NSMutableArray *finalResult = [NSMutableArray arrayWithArray:[results filteredArrayUsingPredicate:predicate]]; 

HTHを。

+0

フェッチされた結果にフィルタを適用することを考えました。しかし、私は限界(ページネーション)を持ってフェッチしています。もし私がこの権利を得ているならば、私は最後のバッチだけでなく、すでに持っているすべてのイベントにフィルターを適用するべきです。それは少し遅いかもしれませんが、私はそれを試してみましょう。 – apetrov

関連する問題