簡體   English   中英

AFNetworking:重試操作時訪問完成處理程序

[英]AFNetworking: Access to completion handlers when retrying operation

給出一些上下文:我正在嘗試為身份驗證錯誤(使用令牌身份驗證,而不是基本身份)實現全局錯誤處理程序,它應該嘗試重新進行身份驗證,然后重復原始失敗請求(請參閱我之前的問題: AFNetworking:Handle全局錯誤並重復請求

當前的方法是注冊AFNetworkingOperationDidFinishNotification的觀察者,該觀察者進行重新認證並且(如果auth成功)重復原始請求:

- (void)operationDidFinish:(NSNotification *)notification
{
    AFHTTPRequestOperation *operation = (AFHTTPRequestOperation *)[notification object];

    if(![operation isKindOfClass:[AFHTTPRequestOperation class]]) {
        return;
    }

    if(403 == [operation.response statusCode]) {
        // try to re-authenticate and repeat the original request
        [[UserManager sharedUserManager] authenticateWithCredentials...
            success:^{
                // repeat original request

                // AFHTTPRequestOperation *newOperation = [operation copy]; // copies too much stuff, eg. response (although the docs suggest otherwise)
                AFHTTPRequestOperation *newOperation = [[AFHTTPRequestOperation alloc] initWithRequest:operation.request];

                // PROBLEM 1: newOperation has no completion blocks. How to use the original success/failure blocks here?

                [self enqueueHTTPRequestOperation:newOperation];
            }
            failure:^(NSError *error) {
                // PROBLEM 2: How to invoke failure block of original operation?
            }
        ];
    }
}

但是,我偶然發現了一些有關請求操作完成塊的問題:

  • 重復原始請求時,我顯然希望執行完成塊。 但是, AFHTTPRequestOperation不保留對傳遞的成功和失敗塊的引用(請參閱setCompletionBlockWithSuccess:failure: NSOperation並且復制NSOperationcompletionBlock可能不是一個好主意,因為AFURLConnectionOperation的文檔指出:

    操作副本不包括completionBlock completionBlock通常會強烈捕獲對self的引用,這可能會令人驚訝地指向復制時的原始操作。

  • 如果重新驗證失敗,我想調用原始請求的失敗塊。 所以,再一次,我需要直接訪問它。

我在這里錯過了什么嗎? 任何替代方法的想法? 我應該提交功能請求嗎?

我在Art.sy的投資組合應用程序中提出了這個問題。 我最終的結論是創建了一個NSOperationQueue子類,它具有在失敗后創建各種AFNetworking HTTP操作的副本的功能(並且在放棄之前每個URL最多執行三次)。

你試過以下嗎?

// set success / failure block of original operation
[newOperation setCompletionBlock:[operation.completionBlock copy]];
[operation setCompletionBlock:nil];

請注意,如果在原始完成/失敗塊中捕獲self(即訪問任何ivars),則在執行newOperation的完成塊時實際訪問原始操作實例。 但這實際上是你想要的,對吧?

通知處理程序在操作的完成塊之前執行。 因此,您應將原始操作的完成塊設置為nil,以防止它執行兩次。

請注意,完成塊在執行后設置為nil(請參閱AFURLConnectionOperation)。

在authenticateWithCredentials失敗塊中,您不應該執行任何操作。 原始操作已經完成,並且已經執行了其故障塊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM