how can I use NSURLConnection Asynchronously?

2019-09-21 19:19发布

I am using this code to load data to my App, can you tell me how can I make this asynchronously?

NSMutableURLRequest *request2 = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:requestString] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0];


NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request2 delegate:self];
if (connection)
{
    NSLog(@"NSURLConnection connection==true");
    NSURLResponse *response;
    NSError *err;
    NSData *responseData = [NSURLConnection sendSynchronousRequest:request2 returningResponse:&response error:&err];
    self.news =[NSJSONSerialization JSONObjectWithData:responseData options:nil error:nil];
    NSLog(@"responseData: %@", self.news);
}
else
{
    NSLog(@"NSURLConnection connection==false");
};

5条回答
女痞
2楼-- · 2019-09-21 19:25

I think you should be bothered reading the documentation. There's a sendAsynchronousRequest:queue:completionHandler: method.

查看更多
【Aperson】
3楼-- · 2019-09-21 19:28

Check this out: HTTPCachedController

It will help you send POST and GET requests, while it will cache the response and after that it will return the cached data when no internet connection is available.

HTTPCachedController *ctrl = [[[HTTPCachedController alloc] initWithRequestType:1 andDelegate:self] autorelease];
[ctrl getRequestToURL:@"https://api.github.com/orgs/twitter/repos?page=1&per_page=10"];

You will get notified when the data are fetched through a delegate method:

-(void)connectionFinishedWithData:(NSString*)data andRequestType:(int)reqType
查看更多
戒情不戒烟
4楼-- · 2019-09-21 19:30

Block code is your friend. I have created a class which does this for you

Objective-C Block code. Create this class here

Interface class

#import <Foundation/Foundation.h>
#import "WebCall.h"

@interface WebCall : NSObject
{
    void(^webCallDidFinish)(NSString *response);

}

@property (nonatomic, retain) NSMutableData *responseData;

-(void)setWebCallDidFinish:(void (^)(NSString *))wcdf;

-(void)webServiceCall :(NSString *)sURL_p : (NSMutableArray *)valueList_p : (NSMutableArray *)keyList_p;

@end

Implementation class

#import "WebCall.h"
#import "AppDelegate.h"
@implementation WebCall

@synthesize responseData;

-(void)setWebCallDidFinish:(void (^)(NSString *))wcdf
{
    webCallDidFinish = [wcdf copy];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
    int responseStatusCode = [httpResponse statusCode];

    NSLog(@"Response Code = %i", responseStatusCode);
    if(responseStatusCode < 200 || responseStatusCode > 300)
    {
        webCallDidFinish(@"failure");
    }



    [responseData setLength:0];
}

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{

    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [responseData appendData:data]; 
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{

    NSLog(@"WebCall Error: %@", error);
    webCallDidFinish(@"failure");
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{

        NSString *response = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
        response = [response stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        webCallDidFinish(response);

}

-(void)webServiceCall :(NSString *)sURL_p : (NSMutableArray *)valueList_p : (NSMutableArray *)keyList_p
{
    NSMutableString *sPost = [[NSMutableString alloc] init];

    //If any variables need passed in - append them to the POST
    //E.g. if keyList object is username and valueList object is adam will append like
    //http://test.jsp?username=adam
    if([valueList_p count] > 0)
    {
        for(int i = 0; i < [valueList_p count]; i++)
        {
            if(i == 0)
            {
                    [sPost appendFormat:@"%@=%@", [valueList_p objectAtIndex:i],[keyList_p objectAtIndex:i]];
            }
            else
            {

                    [sPost appendFormat:@"&%@=%@", [valueList_p objectAtIndex:i], [keyList_p objectAtIndex:i]];
            }
        }
    }


    NSData * postData = [sPost dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
    NSString * postLength = [NSString stringWithFormat:@"%d",[postData length]];



    NSURL * url = [NSURL URLWithString:sURL_p];
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody:postData];

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];

    if (theConnection)
    {
        self.responseData = [NSMutableData data];
    }


}

@end

Then you to make this web call, you call it like this

     WebCall *webCall = [[WebCall alloc] init];


        [webCall setWebCallDidFinish:^(NSString *response){

            //This method is called as as soon as the web call is finished

NSString *trimmedString = [response stringByTrimmingCharactersInSet:
                                   [NSCharacterSet whitespaceAndNewlineCharacterSet]];
        if([trimmedString rangeOfString:@"failure"].location == NSNotFound)
        {
           //Successful web call
        }
        else
        {
           //If the webcall failed due to an error
        }

        }];


        //Make web call here
        [webCall webServiceCall:@"http://www.bbc.co.uk/" :nil :nil];

See the setWebCallDidFinish method, it will not be called until the webcall has finished.

Hope that helps!!

查看更多
成全新的幸福
5楼-- · 2019-09-21 19:31

Here is some code which I am using in my app:

            NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:yourURL]];
        [NSURLConnection sendAsynchronousRequest:request
                                           queue:[NSOperationQueue mainQueue]
                               completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                                   if (error) {
                                       NSLog(@"Error loading data from %@. Error Userinfo: %@",yourURL, [error userInfo]);
                                   } else {
                                   NSDictionary *dataFromServer = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
                                   contentAsString = [[[dataFromServer objectForKey:@"page"] objectForKey:@"content"] stripHtml];
                                   completionHandler(contentAsString);
                               }];

fyi: stripHTML is a NSString Category to remove HTML tags from JSON --> Found it Here

you can call your content in your class like that:

[yourClass getDataWithcompletionHandler:^(NSString *content) {
    yourObject.content = content;
    [yourClass saveManagedObjectContext];
}];

if you implement it once, you won't want to use synchronous connection again...

查看更多
够拽才男人
6楼-- · 2019-09-21 19:49

Create the connection with initWithRequest:delegate:startImmediately:, set yourself as its delegate and implement the delegate methods.

查看更多
登录 后发表回答