简体   繁体   English

NSURLConnection sendAsynchronousRequest:如何检查完成的状态码?

[英]NSURLConnection sendAsynchronousRequest: How to check finished status code?

So I have some code like so: 所以我有一些这样的代码:

@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;
}

Clearly the routine will carry on into the if-else statement before the request has finished. 显然,例程将在请求完成之前继续执行if-else语句。 Therefore, self.statusCode is not set properly in the delegate didReceiveResponse before it is checked. 因此, self.statusCode没有正确委托设置didReceiveResponse检查之前。 What would be the best way of doing this? 最好的方法是什么?

I am just thinking of adding another bool property that will be set in connectionDidFinishLoading and then loop until this property is set. 我只是想添加将在connectionDidFinishLoading设置的另一个bool属性,然后循环直到设置了该属性。 Once it has done that, then it will check self.statusCode . 完成此操作后,将检查self.statusCode However I am thinking this will block the thread will it not? 但是我在想这会阻塞线程吗? It will be no different from a sendSynchronousRequest right? 它与sendSynchronousRequest没什么不同,对吗? Is there any way to do this without putting it into a background thread? 有没有办法将其放入后台线程?

Instead of your sendRequest:withData: method returning a BOOL indicating success/failure, it would be better for your RequestHandler to have a delegate. 代替您的sendRequest:withData:方法返回指示成功/失败的BOOL的方法,最好让RequestHandler拥有一个委托。 It could then let its delegate know about the success/failure/whatever else when the asynchronous request has finished, instead of trying to return this information from the sendRequest:withData: method (which, as you've found out, doesn't work so well). 然后,它可以让其委托人知道成功/失败/异步请求完成后的所有其他信息,而不是尝试从sendRequest:withData:方法返回此信息(如您sendRequest:withData: ,该方法不起作用)很好)。

So, you could define you delegate protocol something like this (just as an example - you might want to include some more information in these): 因此,您可以定义类似这样的委托协议(仅作为示例-您可能希望在其中包含更多信息):

@protocol RequestHandlerDelegate <NSObject>

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

@end

Then, give your RequestHandler a delegate property of something that conforms to this protocol: 然后,为您的RequestHandler提供一个符合此协议的委托属性:

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

(Make sure you set something as the delegate!) (确保您将某些内容设置为委托人!)

Then, when your asynchronous request completes, you can send your delegate the appropriate message, eg: 然后,当您的异步请求完成时,可以向您的委托发送适当的消息,例如:

[self.delegate requestHandlerSuccessfullyCompletedRequest:self];

You'll need to implement the NSURLConnection delegate methods in RequestHandler (from your code, I assume you've already done that), or, if your are targeting iOS 7+, you could take a look at NSURLSession instead. 您将需要在RequestHandler实现NSURLConnection委托方法(从您的代码中,我认为您已经完成了),或者,如果您的目标是iOS 7+,则可以NSURLSession

You have to implement 2 delegate methods: 您必须实现2个委托方法:

  1. Status code : - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 状态码 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

  2. Received data : - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 接收到的数据 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

Example usage: 用法示例:

Declaration 宣言

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

Request 请求

- (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];
} 

Delegates 代表们

- (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];
    }
}

Instead of using NSURLConnection with delegate methods you can use NSURLConnection sendAsynchronousRequest block in your code. 可以在代码中使用NSURLConnection sendAsynchronousRequest块,而不是将NSURLConnection与委托方法一起使用。 In the example you can check connection error and compare status codes. 在示例中,您可以检查连接错误并比较状态代码。

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
    }
}];

You can also check by logging this returnString. 您也可以通过记录此returnString进行检查。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM