AFNetworkingを使用し、操作キュー (NSOperationQueue に似ています) を使用して、Clear Read APIへの一連の要求をキューに入れています。
私は基本的に URL の配列を持っており、それぞれに基づいて個別のリクエストを作成し、各リクエストをキューに入れ、リクエストをバッチで実行します。一度に 1 つずつ戻ってきて、タイムスタンプを付けてから、テーブル ビューのソースである Core Data に追加するので、テーブル ビューにデータが取り込まれます。
アイテムが正常に返されたときにのみ、タイムスタンプが発行されます。これは、アイテムが元の URL 配列の順序ではなく、いつ返されたかに基づいて並べ替えられることを意味します。そのため、返されるまでの時間が短い (API が処理するテキストが少ない) リクエストは、タイムスタンプが早く付けられ、テキストの量が多いため、後でタイムスタンプが付けられたアイテムよりも古いと見なされます。これは、正しい順序付けという点では明らかに当てはまりません。
最終的に、API 呼び出しの URL の配列が適切な順序になっているにもかかわらず、テーブル ビューは API がアイテムを返したタイミングに基づいて並べ替えられます。
これが私のコードです:
- (void)addArticlesFromURLs:(NSArray *)URLs fromSource:(NSString *)source {
// Restrict amount of operations that can occur at once
[[AFClearReadClient sharedClient].operationQueue setMaxConcurrentOperationCount:3];
// Create an array to hold all of our requests to make
NSMutableArray *requestOperations = [[NSMutableArray alloc] init];
for (NSString *URL in URLs) {
// Create the request from the article's URL
NSMutableURLRequest *request = [[AFClearReadClient sharedClient] requestWithMethod:@"GET" path:[NSString stringWithFormat:@"/v1/clear?url=%@&format=json", URL] parameters:nil];
// Create the request operation and specify behaviour on success and failure
AFHTTPRequestOperation *requestOperation = [[AFClearReadClient sharedClient] HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject) {
// Get the item NSDictionary from the JSON responseObject
NSDictionary *item = [responseObject objectForKey:@"item"];
// Get the values needed to create an article
NSString *title = [item objectForKey:@"title"];
NSString *URL = [item objectForKey:@"link"];
NSString *body = [item objectForKey:@"description"];
// Replace HTML entities with their actual characters
title = [title stringByReplacingOccurrencesOfString:@"&" withString:@"&"];
// Remove all HTML and formatting from body so only plain-text remains
body = [self removeHTMLAndFormatting:body];
// Add it to CoreData if there's actual content (easiest way to tell is checking body)
if (![body isEqualToString:@""]) {
NSManagedObjectContext *context = self.managedObjectContext;
ArticleInfo *articleInfo = [NSEntityDescription insertNewObjectForEntityForName:@"ArticleInfo" inManagedObjectContext:context];
articleInfo.source = source;
articleInfo.body = body;
articleInfo.title = title;
articleInfo.url = URL;
articleInfo.timeStamp = [NSDate date];
NSError *error;
[context save:&error];
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Request operation error: %@", error);
}];
// Save the request operation in an NSArray so all can be enqueued later
[requestOperations addObject:requestOperation];
}
// Enqueue the request operations
[[AFClearReadClient sharedClient] enqueueBatchOfHTTPRequestOperations:requestOperations progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
[self.tableView reloadData];
} completionBlock:^(NSArray *operations) {
[self.tableView reloadData];
}];
}
私のテーブルビューが正しい(一番上に新しい)アイテムを持つように、これを変更するにはどうすればよいですか?