1

Поэтому у меня есть некоторый код, например, так:NSURLConnection sendAsynchronousRequest: Как проверить готовый код состояния?

@interface RequestHandler() 

@property (nonatomic) NSInteger statusCode; 

@end 

@implementation RequestHandler 

- (bool)sendRequest:(NSString *)surveyorId withData:(NSData *)requestData 
{ 
    [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:true]; 

    if (self.statusCode == 200) 
    { 
     return YES; 
    } 

    return NO; 
} 

Очевидно, что процедура будет продолжать в if-else заявление до того, как запрос завершен. Поэтому self.statusCode не установлен должным образом в делегате didReceiveResponse перед его проверкой. Какой был бы лучший способ сделать это?

Я просто подумываю добавить еще одно свойство bool, которое будет установлено в connectionDidFinishLoading, а затем цикл, пока не будет установлено это свойство. Как только он это сделает, он проверит self.statusCode. Однако я думаю, что это заблокирует поток, не так ли? Он ничем не отличается от sendSynchronousRequest? Есть ли способ сделать это, не помещая его в фоновый поток?

ответ

1

Вы должны реализовать 2 методы делегата:

  1. код Статус: - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

  2. Полученные данные: - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

Пример использования:

Декларация

@interface RequestHandler : NSObject <NSURLConnectionDelegate> 
{ 
    NSMutableData *receivedData; 
} 

Запрос

- (void)sendRequest:(NSString *)surveyorId withData:(NSData *)requestData 
{ 

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 

    // Apply params in http body 
    if (requestData) { 
     [request setHTTPBody:requestData]; 
    } 

    [request setURL:url]; 
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
    [connection start]; 
} 

Делегаты

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    NSHTTPURLResponse *responseCode = (NSHTTPURLResponse *)response; 
    if ([self.delegate respondsToSelector:@selector(didReceiveResponseCode:)]) { 
     [self.delegate didReceiveResponseCode:responseCode]; 
    } 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    receivedData = [[NSMutableData alloc] initWithData:data]; 

    if ([self.delegate respondsToSelector:@selector(connectionSucceedWithData:)]) { 
     [self.delegate connectionSucceedWithData:receivedData]; 
    } 
} 
+0

Извините, возможно, я не дал понять это, но у меня есть эти два метода делегирования. Они работают так, как ожидалось, но в моем методе '' 'sendRequest'' оператор' '' if-else''' выполняется до вызова методов делегата. –

+0

Конечно, это происходит, потому что делегаты будут вызваны, когда запрос будет завершен (это асинхронно). Итак, это 'if clause' должно быть помещено в делегат:' - (void) connection: (NSURLConnection *) connection didReceiveResponse: (NSURLResponse *) response' –

+0

Но метод делегирования делегатов возвращает void. У меня есть другой класс, который вызывает этот класс '' RequestHandler''', который должен знать результат запроса. –

-1

Вы также можете проверить регистрируя эту returnString.

 NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 
     NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding]; 
     NSArray *arrpicResult = [returnString JSONValue]; 
+1

Я посылаю асинхронный запрос –

+1

Ok использовать этот [NSURLConnection sendAsynchronousRequest: очереди запроса: ноль completionHandler:^(NSURLResponse * ответ, NSData * данные, NSError * ConnectionError) { NSString * returnString = [[NSString Alloc] initWithData: данные кодирование: NSUTF8StringEncoding]; }]; –

1

Вместо вашего sendRequest:withData: метода возвращающего BOOL, указывающую успех/провал, было бы лучше для вашего RequestHandler иметь делегат. Затем он мог сообщить своему делегату об успехе/неудаче/остальном, когда асинхронный запрос завершился, вместо того, чтобы пытаться вернуть эту информацию из метода sendRequest:withData: (который, как вы выяснили, не работает так хорошо) ,

Таким образом, вы могли бы определить делегирование протокола что-то вроде этого (как пример - вы можете включить более подробную информацию в них):

@protocol RequestHandlerDelegate <NSObject> 

- (void)requestHandlerSuccessfullyCompletedRequest:(RequestHandler *)sender; 
- (void)requestHandlerFailedToCompletedRequest:(RequestHandler *)sender; 

@end 

Затем дайте RequestHandler делегат свойство чего-то что соответствует этому протоколу:

@property (nonatomic, weak) id<RequestHandlerDelegate> delegate; 

(Убедитесь, что вы установили что-то в качестве делегата!)

Затем, когда ваш асинхронный запрос завершается, вы можете отправить ваш делегат соответствующее сообщение, например:

[self.delegate requestHandlerSuccessfullyCompletedRequest:self]; 

Вам нужно реализовать NSURLConnection методы делегата в RequestHandler (из кода, я полагаю, вы уже это сделали), или, если вы ориентируетесь на iOS 7+, вы можете взглянуть на NSURLSession.

0

Вместо использования NSURLConnection с помощью методов делегатов вы можете использовать блок NSURLConnection sendAsynchronousRequest в своем коде. В этом примере вы можете проверить ошибку соединения и сравнить коды состояния.

NSURL *URL = [NSURL URLWithString:@"http://yourURLHere.com"]; 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:URL]; 

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *rspreportStatus, NSData *datareportStatus, NSError *e) 
{ 

    NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)rspreportStatus; 
    int code = [httpResponse statusCode]; 

    if (e == nil && code == 200) 
    { 
     // SUCCESS 
    } else { 
     // NOT SUCCESS 
    } 
}];