首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何防止恢复重复的NSURLSessionTask

如何防止恢复重复的NSURLSessionTask
EN

Stack Overflow用户
提问于 2015-08-07 10:02:11
回答 1查看 1.8K关注 0票数 0

我正在尝试在我的项目中使用NSURLSession。情况是这样的,我想检查是否已经存在具有相同请求的任务。因此,我使用getTasksWithCompletionHandler进行检查,如果没有,则恢复块中的任务。但当我这样做时,数组中总是没有其他任务。

我错过了什么吗?

下面是我的代码:

代码语言:javascript
复制
#import "HttpRequestHelper.h"


@implementation HttpRequestHelper

+(NSURLSession *)sharedDefaultSession{
static dispatch_once_t once;
static NSURLSession * defaultSession;
dispatch_once(&once, ^{
    NSURLSessionConfiguration * configure = [NSURLSessionConfiguration defaultSessionConfiguration];
    configure.HTTPMaximumConnectionsPerHost = 5;
    configure.timeoutIntervalForRequest = kTimeOutInterval;
    configure.timeoutIntervalForResource = kTimeOutInterval;
    defaultSession = [NSURLSession sessionWithConfiguration:configure delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
});

return defaultSession;
}

+(void)resultFromRequest:(NSURLRequest *)request withCompleter:(downloadCompleter)completer{

NSURLSessionDataTask * dataTask = [[self sharedDefaultSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
//            NSLog(@"response %@",response);
//            NSLog(@"url:%@\nData:%@",request.URL,[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
    if (!error) {
        NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response;
        if (httpResponse.statusCode == 200) {
            completer([self jsonObjectFromData:data]);
        } else {
            completer(nil);
            // handle http error
        }
    } else {
        completer(nil);
        NSLog(@"network error %@",error.localizedDescription);
        // handle network error
    }
}];

NSLog(@"check %@",dataTask);
[self checkAndResumeTask:dataTask];
}

+(void)checkAndResumeTask:(NSURLSessionTask *)task{
[[self sharedDefaultSession] getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
    BOOL isNewTask = (![self containTask:task inTaskArray:dataTasks]&&![self containTask:task inTaskArray:downloadTasks]);
    NSLog(@"isNewTask : %d %@",isNewTask,[self sharedDefaultSession] );
    if (isNewTask) {
        if (!IS_LOWER_IOS8) {
            task.priority = NSURLSessionTaskPriorityHigh;
        }
        NSLog(@"%@ resume",task);
        [task resume];
    } else {
        [task cancel];
    }
}];
}

+(BOOL)containTask:(NSURLSessionTask *)task inTaskArray:(NSArray *)taskArray{
NSString * taskIndepentId = [task.originalRequest valueForHTTPHeaderField:IndependentID]?:@"";
NSString * taskUrlString = task.originalRequest.URL.absoluteString;
for (NSURLSessionTask * oldTask in taskArray) {
    if (!IS_LOWER_IOS8) {
        oldTask.priority = NSURLSessionTaskPriorityDefault;
    }

    NSString * oldTaskIndepentId = [oldTask.originalRequest valueForHTTPHeaderField:IndependentID]?:@"";
    NSString * oldTaskUrlString = oldTask.originalRequest.URL.absoluteString;
    if ([taskIndepentId isEqualToString:oldTaskIndepentId] && [taskUrlString isEqualToString:oldTaskUrlString] && oldTask!=task) {
        return YES;
    }
}
return NO;
}

+(id)jsonObjectFromData:(NSData*)data{

NSError * dataError;
NSDictionary * dic =   [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&dataError];
if (dataError) {
    NSLog(@"json data error : %@",dataError);
}
return dic;
}

+(void)cancelTaskForRequest:(NSURLRequest *)request{
[[self sharedDefaultSession] getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
    [self cancelRequest:request ForArrayTasks:dataTasks];
    [self cancelRequest:request ForArrayTasks:uploadTasks];
    [self cancelRequest:request ForArrayTasks:downloadTasks];
}];
}

+(void)cancelRequest:(NSURLRequest *)request ForArrayTasks:(NSArray *)arrayTasks{
for (NSURLSessionTask * task in arrayTasks) {
    NSLog(@"task %@",task);
    NSURLRequest * requestTask = task.originalRequest;
    BOOL isSameURL = [requestTask.URL.absoluteString isEqualToString:request.URL.absoluteString];
    BOOL isSameID = [[requestTask valueForHTTPHeaderField:IndependentID] isEqualToString:[request valueForHTTPHeaderField:IndependentID]];
    if (isSameURL && isSameID) {
        [task cancel];
    }
}
}

@end

我已经尝试在检查checkAndResumeTask:之前添加[dataTask resume];,任务将在getTasksWithCompletionHandler中的数组中,但我如何在恢复之前进行检查?

这是正确的做法吗?

我将感谢任何意见,谢谢。

-编辑

@dgatwood :我确定另一个任务正在运行

代码语言:javascript
复制
+(void)checkAndResumeTask:(NSURLSessionTask *)task{
NSLog(@"\ncheck task %@ \nfor URL %@ \nin thread %@",task,task.originalRequest.URL.absoluteString,[NSOperationQueue currentQueue]);
[[self sharedDefaultSession] getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
    NSLog(@"\ncheck task %@ \nfor URL %@ \nin thread %@ \n\n old tasks: %@,\n%@",task,task.originalRequest.URL.absoluteString,[NSOperationQueue currentQueue],dataTasks,downloadTasks);
    BOOL isNewTask = (![self containTask:task inTaskArray:dataTasks]&&![self containTask:task inTaskArray:downloadTasks]);
    NSLog(@"isNewTask : %d %@",isNewTask,[self sharedDefaultSession] );
    if (isNewTask) {
        if (!IS_LOWER_IOS8) {
            task.priority = NSURLSessionTaskPriorityHigh;
        }
        [task resume];
        NSLog(@"\nresume task :%@",task);
    } else {
        [task cancel];
    }
}];
}

我在代码中打印信息,在块之前、块之后和恢复任务之后。

我用同样的请求调用了三个任务。

下面是我的结果

您可以在2015-09-04 01:59:45.216 XXX[26387:1632660] **resume task :<__NSCFLocalDataTask: 0x7fa428e81a40>{ taskIdentifier: 1 } { running }**之后看到此任务正在运行,但在此之后返回的块在数组中仍然没有任务。

这是因为在第一个任务恢复之前,块已经获得了数组吗?或者是我做错了什么?

代码语言:javascript
复制
2015-09-04 01:59:45.130 XXX[26387:1632660] 
check task <__NSCFLocalDataTask: 0x7fa428e81a40>{ taskIdentifier: 1 } { suspended } 
for URL https://XXX/AppApi/api/account/BonusDetails 
in thread <NSOperationQueue: 0x7fa428d05f70>{name = 'NSOperationQueue Main Queue'}
2015-09-04 01:59:45.131 XXX[26387:1632660] 
check task <__NSCFLocalDataTask: 0x7fa42b034e70>{ taskIdentifier: 2 } { suspended } 
for URL https://XXX/AppApi/api/account/BonusDetails 
in thread <NSOperationQueue: 0x7fa428d05f70>{name = 'NSOperationQueue Main Queue'}
2015-09-04 01:59:45.132 XXX[26387:1632660] 
check task <__NSCFLocalDataTask: 0x7fa42b037180>{ taskIdentifier: 3 } { suspended } 
for URL https://XXX/AppApi/api/account/BonusDetails 
in thread <NSOperationQueue: 0x7fa428d05f70>{name = 'NSOperationQueue Main Queue'}
2015-09-04 01:59:45.215 XXX[26387:1632660] 
check task <__NSCFLocalDataTask: 0x7fa428e81a40>{ taskIdentifier: 1 } { suspended } 
for URL https://XXX/AppApi/api/account/BonusDetails 
in thread <NSOperationQueue: 0x7fa428d05f70>{name = 'NSOperationQueue Main Queue'} 

 old tasks: (
),
(
)
2015-09-04 01:59:45.216 XXX1632660] isNewTask : 1 <__NSURLSessionLocal: 0x7fa428e80d80>
2015-09-04 01:59:45.216 XXX[26387:1632660] 
**resume task :<__NSCFLocalDataTask: 0x7fa428e81a40>{ taskIdentifier: 1 } { running }**
2015-09-04 01:59:45.255 XXX[26387:1632660] 
check task <__NSCFLocalDataTask: 0x7fa42b034e70>{ taskIdentifier: 2 } { suspended } 
for URL XXX/AppApi/api/account/BonusDetails 
in thread <NSOperationQueue: 0x7fa428d05f70>{name = 'NSOperationQueue Main Queue'} 

 old tasks: (
),
(
)
2015-09-04 01:59:45.255 XXX[26387:1632660] isNewTask : 1 <__NSURLSessionLocal: 0x7fa428e80d80>
2015-09-04 01:59:45.255 XXX[26387:1632660] 
resume task :<__NSCFLocalDataTask: 0x7fa42b034e70>{ taskIdentifier: 2 } { running }
2015-09-04 01:59:45.256 XXX[26387:1632660] 
check task <__NSCFLocalDataTask: 0x7fa42b037180>{ taskIdentifier: 3 } { suspended } 
for URL https://XXX/AppApi/api/account/BonusDetails 
in thread <NSOperationQueue: 0x7fa428d05f70>{name = 'NSOperationQueue Main Queue'} 

 old tasks: (
),
(
)
EN

回答 1

Stack Overflow用户

发布于 2015-08-23 14:51:53

是否确定其他任务仍在运行?一旦任务完成,它就不会出现在对getTasksWithCompletionHandler的调用中。如果您需要检查以前的请求是否存在,甚至在它们完成之后,您将需要将原始URL或URL请求存储在NSSet或类似的文件中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31868595

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档