Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何使用AFNetworking中的EnqueueBatchOfHttPrequesStoperations在操作失败时重新添加操作_Iphone_Ios_Ipad_Afnetworking - Fatal编程技术网

Iphone 如何使用AFNetworking中的EnqueueBatchOfHttPrequesStoperations在操作失败时重新添加操作

Iphone 如何使用AFNetworking中的EnqueueBatchOfHttPrequesStoperations在操作失败时重新添加操作,iphone,ios,ipad,afnetworking,Iphone,Ios,Ipad,Afnetworking,我有一种方法,可以使用AFNetworking调用EnqueueBatchOfHttPrequesToOperations将文件列表从web服务器下载到iPad。每隔一段时间我就会遇到一次失败的操作(通常是当文件较大时)。历史上,我单独下载了每个文件,并简单地再次调用该操作,直到某个重试次数 我已经重构了代码以使用EnqueueBatchOfHttPrequesToOperations。这非常有效,但我不知道如何获取“特定”操作失败的通知,也不知道如果失败了,如何将它们重新添加到队列中 以下是我

我有一种方法,可以使用AFNetworking调用EnqueueBatchOfHttPrequesToOperations将文件列表从web服务器下载到iPad。每隔一段时间我就会遇到一次失败的操作(通常是当文件较大时)。历史上,我单独下载了每个文件,并简单地再次调用该操作,直到某个重试次数

我已经重构了代码以使用EnqueueBatchOfHttPrequesToOperations。这非常有效,但我不知道如何获取“特定”操作失败的通知,也不知道如果失败了,如何将它们重新添加到队列中

以下是我用来下载“n”个文件的代码:

    NSMutableArray *operationsArray = [[NSMutableArray alloc]init];
for (MINPageDefinition *currPage in [[MINPageStore sharedInstance] pageArray])
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *serverLibraryURL = [defaults objectForKey:kRootURL];
    serverLibraryURL = [serverLibraryURL stringByAppendingPathComponent:kPageDefinitionsDirectory];
    serverLibraryURL = [serverLibraryURL stringByAppendingPathComponent:currPage.pageImageName];

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:serverLibraryURL]];
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    operation.outputStream = [NSOutputStream outputStreamToFileAtPath:currPage.pageImageURL append:NO];

    [operationsArray addObject:operation];
}
if ([operationsArray count] > 0)
{
    AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@""]];
    void (^progressBlock)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations) = ^(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations) {
        NSLog(@"%d proccesses completed out of %d", numberOfCompletedOperations, totalNumberOfOperations);
    };
    void (^completionBlock)(NSArray *operations) = ^(NSArray *operations) {
        NSLog(@"All operations completed");
    };
    [client enqueueBatchOfHTTPRequestOperations:operationsArray
                                  progressBlock:progressBlock
                                completionBlock:completionBlock];
}

在此之前,我有一个执行该操作的方法。失败时,失败块将递归地调用自身。如果一个操作失败,我如何修改此代码以重试最多“n”次?

您不能像这样将单个失败的操作再次排队到该操作的失败块中吗

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
     [[APIClient sharedClient] enqueueHTTPRequestOperation:operation];
}];

其中,
[APIClient sharedClient]
是对
AFHTTPClient
子类(单例或非单例)的引用

您不能像这样将单个失败的操作再次排队到该操作的失败块中吗

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
     [[APIClient sharedClient] enqueueHTTPRequestOperation:operation];
}];

其中,
[APIClient sharedClient]
是对
AFHTTPClient
子类(单例或非单例)的引用

再次检查下面的代码@justlearning

[[WfServices sharedClient] GET:kGetAddress parameters:dicParam  success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"RESPONSE ::: %@",responseObject);
  }failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    }];


+ (WfServices *)sharedClient
{
    static WfServices * _sharedClient = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        _sharedClient = [[WfServices alloc] initWithBaseURL:[NSURL URLWithString:kWFBaseURLString]];
    });

    return _sharedClient;
}

再次检查以下代码@justlearning

[[WfServices sharedClient] GET:kGetAddress parameters:dicParam  success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"RESPONSE ::: %@",responseObject);
  }failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    }];


+ (WfServices *)sharedClient
{
    static WfServices * _sharedClient = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        _sharedClient = [[WfServices alloc] initWithBaseURL:[NSURL URLWithString:kWFBaseURLString]];
    });

    return _sharedClient;
}
我想可能会有帮助

或者,您可以在AFHTTPClient中重写以下方法

考虑需要重新添加到队列中的resumeTasksArray=操作数组

NSMutableArray *resumeTasksArray; before @implementation AFHTTPClient 

- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request
                                                success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                                                failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure {

void(^authFailBlock)(AFHTTPRequestOperation *opr, NSError *err) = ^(AFHTTPRequestOperation *opr, NSError *err){
    [resumeTasksArray addObject:request];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        //now, queue up and execute the original task
        for (NSURLRequest *previousRequest in resumeTasksArray) {
            NSLog(@"^^^^^^^^^^^^^^^^^^^^^^^^^^^^Resume Task URL - %@", previousRequest.URL);
            NSMutableURLRequest *newRequest = [previousRequest mutableCopy];
            [newRequest setValue:[NSString stringWithFormat:@"Bearer %@", AppSingleton.access_token] forHTTPHeaderField:@"Authorization"];
            AFHTTPRequestOperation *opera10n = [[AFHTTPRequestOperation alloc]initWithRequest:newRequest];
            opera10n.responseSerializer = self.responseSerializer;
            [opera10n setCompletionBlockWithSuccess:success failure:failure];
            if (![[self.operationQueue operations] containsObject:opera10n]) {
                [[self operationQueue] addOperation:opera10n];
                [opera10n start];
            }
        }
        [resumeTasksArray removeAllObjects];
    });
};
AFHTTPRequestOperation *operation = [super HTTPRequestOperationWithRequest:request success:success failure:authFailBlock];
return operation;
}
我想可能会有帮助

或者,您可以在AFHTTPClient中重写以下方法

考虑需要重新添加到队列中的resumeTasksArray=操作数组

NSMutableArray *resumeTasksArray; before @implementation AFHTTPClient 

- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request
                                                success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                                                failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure {

void(^authFailBlock)(AFHTTPRequestOperation *opr, NSError *err) = ^(AFHTTPRequestOperation *opr, NSError *err){
    [resumeTasksArray addObject:request];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        //now, queue up and execute the original task
        for (NSURLRequest *previousRequest in resumeTasksArray) {
            NSLog(@"^^^^^^^^^^^^^^^^^^^^^^^^^^^^Resume Task URL - %@", previousRequest.URL);
            NSMutableURLRequest *newRequest = [previousRequest mutableCopy];
            [newRequest setValue:[NSString stringWithFormat:@"Bearer %@", AppSingleton.access_token] forHTTPHeaderField:@"Authorization"];
            AFHTTPRequestOperation *opera10n = [[AFHTTPRequestOperation alloc]initWithRequest:newRequest];
            opera10n.responseSerializer = self.responseSerializer;
            [opera10n setCompletionBlockWithSuccess:success failure:failure];
            if (![[self.operationQueue operations] containsObject:opera10n]) {
                [[self operationQueue] addOperation:opera10n];
                [opera10n start];
            }
        }
        [resumeTasksArray removeAllObjects];
    });
};
AFHTTPRequestOperation *operation = [super HTTPRequestOperationWithRequest:request success:success failure:authFailBlock];
return operation;
}

非常接近。。。您还可以检查,实际上,在我最初的实现中,这正是我所做的。如果操作失败,我递归调用封装该操作的方法。我现在遇到的问题是,我已经使用EnqueueBatchOfHttPrequesStoperations将实现改为排队操作。此方法通过“n”个操作进行迭代。我知道我可以迭代处理程序中的操作。但我如何重新添加这些操作,然后重新排队?非常接近。。。您还可以检查,实际上,在我最初的实现中,这正是我所做的。如果操作失败,我递归调用封装该操作的方法。我现在遇到的问题是,我已经使用EnqueueBatchOfHttPrequesStoperations将实现改为排队操作。此方法通过“n”个操作进行迭代。我知道我可以迭代处理程序中的操作。但我如何重新添加这些操作,然后将其重新排队?不,因为无法将已完成的操作添加到操作队列中。如果您尝试,它将抛出一个
NSInvalidArgumentException
。即使请求在网络级别失败,操作本身也已完成。否,因为无法将已完成的操作添加到操作队列。如果您尝试,它将抛出一个
NSInvalidArgumentException
。即使请求在网络级别失败,操作本身也已完成。