How many urlRequests are handled by nsurlconnectio

2019-04-02 17:57发布

问题:

I have to call 20 urlReqests at a time after going through many websites i have found that 4 urlRequsts are handled after that next undergoing requests will encounter error that is timeout error.when i call 5 webservices in a loop first 4 webservices are executing and 5th gets timeout error.How to handle this situation Any help would be appreciated

回答1:

You can use NSOperationQueue for such tasks. Here is the sample code-

Code for RequestManager.h :-

#import <Foundation/Foundation.h>

@protocol RequestManagerDelegate <NSObject>

@optional
- (void)requestForURL:(NSURL *)url tag:(NSString *)tag type:(NSString *)type
        didComplete:(NSData *)data;

- (void)requestForURL:(NSURL *)url tag:(NSString *)tag type:(NSString *)type
   didFailWithError:(NSError *)error;

@end



@interface RequestManager : NSObject

+ (RequestManager *) instance;

- (void)requestForURL:(NSURL *)url tag:(NSString *)tag delegate:(id<RequestManagerDelegate >)delegate;

@end

Code for RequestManager.m :-

#import "RequestManager.h"

@interface RequestManager () {
    NSOperationQueue *requestQueue;
}

@end

@implementation RequestManager

static RequestManager *singletonInstance = nil;

- (id)init {
    if(self = [super init]) {
        requestQueue = [[NSOperationQueue alloc] init];
        requestQueue.maxConcurrentOperationCount = 2;//Here you can select maximum concurrent operations
    }
   return self;
  }


+ (RequestManager *) instance {
    @synchronized(self) {
        if(!singletonInstance) {
            singletonInstance = [[RequestManager alloc] init];
        }
    }
    return singletonInstance;
  }


- (void)requestForURL:(NSURL *)url tag:(NSString *)tag delegate:(id<RequestManagerDelegate >)delegate {
    [requestQueue setSuspended:YES];
    RequestOperation *newOperation = [[RequestOperation alloc] initWithURL:url tag:tag delegate:delegate];
    newOperation.queuePriority = NSOperationQueuePriorityVeryHigh;

    [requestQueue addOperation:newOperation];

    NSArray *operations = requestQueue.operations;

    long operationsCount = operations.count;
    RequestOperation *operation;

    NSOperationQueuePriority priority = NSOperationQueuePriorityVeryHigh;
    for(long i = (operationsCount - 1); i >= 0; i--) {
        operation = [operations objectAtIndex:i];

        if((operation.isExecuting || operation.isCancelled || operation.isFinished) == NO) {
            [operation setQueuePriority:priority];
            priority = [self nextPriorityLowerThan:priority];
        }
    }

    [requestQueue setSuspended:NO];
}

- (NSOperationQueuePriority)nextPriorityLowerThan:(NSOperationQueuePriority)priority {
NSOperationQueuePriority lowerPriority = NSOperationQueuePriorityVeryLow;

switch (priority) {
    case NSOperationQueuePriorityVeryHigh:
        lowerPriority = NSOperationQueuePriorityHigh;
        break;

    case NSOperationQueuePriorityHigh:
        lowerPriority = NSOperationQueuePriorityNormal;
        break;

    case NSOperationQueuePriorityNormal:
        lowerPriority = NSOperationQueuePriorityLow;
        break;

    case NSOperationQueuePriorityLow:
        lowerPriority = NSOperationQueuePriorityVeryLow;
        break;

    default:
        break;
 }

 return lowerPriority;
}

@end

Now RequestOperation.h ->

#import <Foundation/Foundation.h>


@interface RequestOperation : NSOperation

@property(readonly, copy) NSURL *url;
@property(strong , readonly) NSString *tag;
@property(strong , readonly) id<RequestManagerDelegate > *delagate;

- (id)initWithURL:(NSURL *)url tag:(NSString *)tag delegate:(id<RequestManagerDelegate >) delegate;

@end

Now RequestOperation.m

#import "RequestOperation.h"


@interface RequestOperation ()
{
   NSURLConnection *connection;

}
@property (nonatomic) long long int expectedContentLength;
@property (nonatomic, readwrite) NSError* error;
@property (nonatomic) BOOL isExecuting;
@property (nonatomic) BOOL isConcurrent;
@property (nonatomic) BOOL isFinished;
@end



@implementation RequestOperation

- (id)initWithURL:(NSURL *)url tag:(NSString *)tag delegate:(id<RequestManagerDelegate >) delegate{
    if ((self=[super init])) {
    _url = url;
    _tag = tag;
    _delagate=delagate;

   }
   return self;
 }


- (void)start
  {
   NSURLRequest* request = [NSURLRequest requestWithURL:_url];
   //handle here for your request type (post or get)
   self.isExecuting = YES;
   self.isConcurrent = YES;
   self.isFinished = NO;
   [[NSOperationQueue mainQueue] addOperationWithBlock:^
     {
     connection = [NSURLConnection connectionWithRequest:request delegate:self];
     }];
  }

- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response {
    return request;
  }

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
  {

  }

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
  {

  }


  - (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
    return cachedResponse;

  }

 - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
      self.isExecuting = NO;
      self.isFinished = YES;
   }

 - (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
   {
     self.error = error;
     self.isExecuting = NO;
     self.isFinished = YES;
   }

 - (void)setIsExecuting:(BOOL)isExecuting
   {
     [self willChangeValueForKey:@"isExecuting"];
     _isExecuting = isExecuting;
     [self didChangeValueForKey:@"isExecuting"];
   }

 - (void)setIsFinished:(BOOL)isFinished
   {
    [self willChangeValueForKey:@"isFinished"];
    _isFinished = isFinished;
    [self didChangeValueForKey:@"isFinished"];
   }

 - (void)cancel
   {
    [super cancel];
    [connection cancel];
    self.isFinished = YES;
    self.isExecuting = NO;
   }

@end

I given you the my code , this is how i managed multiple concurrent request asynchrounously. You can use this it is very effective. You can request the url using method declare in RequestManager.h and can handle the result using delegates.