три20 TTURLRequest отправить - PullRequest
       8

три20 TTURLRequest отправить

2 голосов
/ 05 октября 2010

У меня есть служба REST, которая использует auth_token, срок действия которого истекает очень часто.при сбое запроса я хочу повторно пройти аутентификацию (что я могу сделать), а затем повторно отправить точно такой же TTURLRequest следующим общим способом:

- (void)request:(TTURLRequest*)request didFailLoadWithError:
(NSError*)error {
       NSLog(@"error %@ %@ %@", [error localizedDescription], [error
localizedFailureReason], [error localizedRecoverySuggestion]
                 );


       if (numRetries == 0) {
               [self authenticateUser:nil];

               request.urlPath = [request.urlPath
stringByReplacingOccurrencesOfRegex:@"access_token=([\\w-]+)"
withString:[NSString stringWithFormat:@"access_token=%@",
accessToken]];

               NSLog(@"URL: %@", request.urlPath);
               [request   send];

               numRetries++;

       }

}

все мои TTURLRequests использовать тот же делегат, который использует этот метод отказа.но по какой-то причине, когда я вызываю [request send], запрос переходит в фазу «загрузки», но, кажется, никогда не завершается.Однако, если я выполняю ручное обновление (перетаскивая вниз представление таблицы), он заново генерирует TTURLRequest с нуля и, кажется, работает нормально.

Как правильно отправить этот запрос повторно?

1 Ответ

0 голосов
/ 06 октября 2010

Недавно я столкнулся с той же проблемой. Я не изучил Three20 достаточно глубоко, чтобы понять, предназначена ли повторная попытка неудачных запросов, но я нашел проблему и надежное (и простое) исправление.

После повторного вызова [request send] экземпляр TTURLRequest освобождается до завершения загрузки. Если вы посмотрите на TTURLRequestModel.m в Three20Network, то увидите, что последний запрос модели (_loadingRequest) освобождается до сохранения нового запроса. Если последний запрос совпадает с новым запросом (как и в вашем случае), то его счетчик сохранения возвращается к 0, и он получает dealloc'd:

/////////////////////////////////////////////////////////////////////////////
- (void)requestDidStartLoad:(TTURLRequest*)request {
  [_loadingRequest release];
  _loadingRequest = [request retain];
  [self didStartLoad];
}

Я решил эту проблему, создав подкласс TTURLRequestModel.m и переопределив этот метод следующим образом:

/////////////////////////////////////////////////////////////////////////////////
- (void)requestDidStartLoad:(TTURLRequest*)request {
  [request retain];
  [_loadingRequest release];
  _loadingRequest = request;
  [self didStartLoad];
}

Это сработало в моем тестировании и, похоже, ни на что не должно отрицательно повлиять.

Примечание : Если вы используете TTURLJSONResponse для объекта ответа вашего запроса, вам нужно будет выделить новый экземпляр и установить его для request.response перед повторным вызовом send. Если вы посмотрите на TTURLJSONResponse.m в extThree20JSON, то увидите, что метод processResponse утверждает (nil == _rootObject). Это не удастся, если экземпляр ответа ранее использовался в запросе.

...