Очередь многих запросов, а затем сортировка на основе добавленного времени, но элементы в конечном итоге сортируются на основе того, когда они получают от запроса

Я использую AFNetworking и использую очередь операций (аналогичную NSOperationQueue), чтобы поставить очередь запросов на Clear Clear API.

У меня в основном есть массив URL-адресов, и я создаю индивидуальные запросы, основанные на каждом из них, вставляя каждый запрос, а затем выполняю пакетные запросы. Они возвращаются, по одному за раз, затем меняют метку времени, а затем добавляем их в Core Data, который является источником для моего представления в таблице, поэтому представление таблицы заполняется.

Только, отметка времени выдается, когда элемент успешно возвращается. Это означает, что элементы сортируются на основе того, когда они возвращаются, а не в порядке исходного массива URL. Таким образом, запросы, которые требуют более короткого времени для возврата (меньше текста для API для обработки), отмечаются ранее и, таким образом, считаются старше, чем элементы, отмеченные позже, из-за большого количества текста. Это явно не относится к правильному порядку.

В конце концов, хотя у меня есть массив URL-адресов для вызовов API в правильном порядке, мое представление таблицы сортируется на основе того, когда 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 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 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] ***********************************:requestOperations progressBlock:^(********** numberOfFinishedOperations, ********** totalNumberOfOperations) {
 [self.tableView reloadData];
 } completionBlock:^(NSArray *operations) {
 [self.tableView reloadData];
 }];
}

Как я могу изменить это, чтобы в моем столе были элементы в их правильном (новейшем сверху) порядке?

2 ответа

Используйте userInfo.

AFHTTPRequestOperation подклассы AFURLConnectionOperation и AFURLConnectionOperation объявляет userInfo словарь, который проходит через без прикосновения. Его цель - предоставить вам возможность добавлять любые данные, необходимые для использования, когда операция завершается. Прежде чем добавить операцию в очередь, сделайте следующее:

[requestOperation setUserInfo:@{ @"timestamp" : [NSDate date] };

Получите это в своем блоке завершения, как

NSDate *timestamp = [operation userInfo][@"timestamp"];

Временные метки будут отражать порядок, в котором операции были добавлены в очередь.


Я действительно не знаю AFNetworking, но...

Вы могли бы просто взять временную метку перед созданием запроса (в цикле for):

NSDate* stamp = [NSDate date];
AFHTTPRequestOperation *requestOperation = ...

Затем в блоке успеха операции:

...
articleInfo.url = URL;
articleInfo.timeStamp = stamp;
...

Блок сохранит вам временную метку и установит ее на успех

licensed under cc by-sa 3.0 with attribution.