1

I am trying to execute a async http request. but the call back log is not working. please analyze the code and suggest me the cause of this issue. I have seen the class examples in many places. But here i am calling it from a main function.

@interface HTTP : NSObject

@property (nonatomic,retain) NSMutableData *receivedData;

- (void) get : (NSString *) urlString;

@end



@implementation HTTP

@synthesize receivedData;


- (void)get: (NSString *)urlString {

NSLog ( @"GET: %@", urlString );

self.receivedData = [[NSMutableData alloc] init];

NSURLRequest *request = [[NSURLRequest alloc]
                         initWithURL: [NSURL    URLWithString:urlString]
                         cachePolicy:  NSURLRequestReloadIgnoringLocalCacheData
                         timeoutInterval: 10
                         ];

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

[connection start];





}




- (void)connection:(NSURLConnection*) connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"Response recieved");
}

- (void)connection:(NSURLConnection*) connection didReceiveData:(NSData *)data
{
NSLog(@"Data recieved");    

NSString* responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

[receivedData appendData:responseString];



}



@end




int main(const int c , char *arg[]){

HTTP *http = [[HTTP alloc] init];

[http get:@"http://www.apple.com"];

return 0;
}
4

2 回答 2

4

Your program does not have a "run loop", therefore it terminates immediately after

[http get:@"http://www.apple.com"];

has returned, before any delegate functions are called. (Note that NSURLConnection works asynchronously.)

If this is for a stand-alone OS X application, you could to the following:

int main(const int c , char *arg[]){

    HTTP *http = [[HTTP alloc] init];

    [http get:@"http://www.apple.com"];

    NSRunLoop *theRL = [NSRunLoop currentRunLoop];
    while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);

    return 0;
}

where shouldKeepRunning is a (global) Boolean variable that is initially YES, and set to NO in

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    shouldKeepRunning = NO;
}

and also in connection:didFailWithError:. Or you add a Boolean property loading to your HTTP class.

If this is for an iOS application or a OS X Cocoa application, then you already have a run loop and don't have to add your own.

于 2013-04-04T13:50:28.393 回答
1

/* Till the application finishes loading, the main thread is kept alive so that the delegate methods are called. Hence the while loop below. */

while(!finished) {    
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}

Here is my working code.

@implementation HTTP
@synthesize receivedData,retStr,delegate;

- init {
    if ((self = [super init])) {
     receivedData = [[NSMutableData alloc] init];
    }
    return self;
}

- (void)get: (NSString *)urlString {

    NSLog ( @"GET: %@", urlString );

    self.receivedData = [[NSMutableData alloc] init];

    NSURLRequest *request = [[NSURLRequest alloc]
                             initWithURL: [NSURL URLWithString:urlString]
                             cachePolicy: NSURLRequestReloadIgnoringLocalCacheData
                             timeoutInterval: 10
                             ];


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

    while(!finished) {

        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }

    if(!connection) {
        NSLog(@"connection failed :(");
    } else {
        NSLog(@"connection succeeded  :)");
    }
}

 - (void)post:(NSString*)urlString: (NSString*)body: (NSObject*) sender {
    // POST
    NSMutableString* requestURL = [[NSMutableString alloc] init];
    [requestURL appendString:urlString];
    NSMutableString* requestBody = [[NSMutableString alloc] initWithString:body];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: [NSString stringWithString:requestURL]]];
    NSString* requestBodyString = [NSString stringWithString:requestBody];
    NSData *requestData = [NSData dataWithBytes: [requestBodyString UTF8String] length: [requestBodyString length]];

    [request setHTTPMethod: @"POST"];
    [request setValue:@"text/html; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody: requestData];
    NSURLConnection *postConn= [[NSURLConnection alloc] initWithRequest:request delegate:sender];

     /*
     Till the application finishes loading, the main thread is kept alive so that the delegate methods are called.
     Hence the while loop below.
     */
    while(!finished) {

        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];

    }

    if(!postConn) {
        NSLog(@"POST connection failed :(");
    } else {
        NSLog(@"POST connection succeeded  :)");

    }
   }    

// ====================
// Callbacks
// ====================

#pragma mark NSURLConnection delegate methods
- (NSURLRequest *)connection:(NSURLConnection *)connection
             willSendRequest:(NSURLRequest *)request
            redirectResponse:(NSURLResponse *)redirectResponse {

    NSLog(@"Connection received data, retain count");
    return request;
}


- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"Received response: %@", response);

    [receivedData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    NSLog(@"Received %lu bytes of data", [data length]); 

    [receivedData appendData:data];
    NSLog(@"Received data is now %lu bytes", [receivedData length]); 

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSRunAlertPanel(@"Error",[NSString stringWithFormat:@"Could not connect to server.Following error occured:\n\n%@", error], nil, nil, nil);
    NSLog(@"Error receiving response: %@", error);

}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // Once this method is invoked, "responseData" contains the complete result
    NSLog(@"Succeeded! Received %lu bytes of data", [receivedData length]); 

    NSString *dataStr=[[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding] ;

    retStr = [NSString stringWithString:dataStr];
        finished =TRUE;

//    [self returnDcString:dataStr];
   // NSLog(@"%@",dataStr);    

    if ([delegate respondsToSelector:@selector(didFinishDownload:)]) {
        NSLog(@"Calling the delegate"); 

        //NSString* dataAsString = [[[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding] autorelease];
//      [delegate performSelector:@selector(didFinishDownload:) withObject: dataStr];
    }


}
- (void)setDelegate:(id)val
{
    delegate = val;
}

- (id)delegate
{
    return delegate;

}


@end
于 2013-04-04T13:51:38.600 回答