异步get代码,如何取回response data??

时间:2022-08-27 15:27:57
本人ios新手,最近处理网络通信代码,遇到一点问题
先上代码
httpcomm.h
#import <Foundation/Foundation.h>

@protocol httpDelegate <NSObject>


-(void) httpResponse:(NSHTTPURLResponse *)response;
-(void) httpFinish:(NSData *)data;
-(void) commError;
@end


@interface httpComm : NSObject{
@public
    id <httpDelegate> delegate;
@private
    NSURLConnection *conn;
    NSMutableData *receiveData;
}
@property (atomic) id <httpDelegate> delegate;
@property (atomic) NSURLConnection *conn;
@property (atomic) NSMutableData *receiveData;

-(Boolean) sendRequest:(NSString *) uri params:(NSDictionary *) data;
-(void) close;

@end


httpcomm.m


#import "httpComm.h"

@implementation httpComm
@synthesize delegate,receiveData,conn;

-(Boolean) sendRequest:(NSString *)uri params:(NSDictionary *)data{
    if (nil != self.conn) {
        return NO;
    }
    if (nil == uri) {
        return  NO;
    }
    NSMutableString *newUri=[[NSMutableString alloc]initWithString:uri];
    if (data) {
        Boolean firstParam=true;
        for (id key in data) {
            if (firstParam) {
                firstParam=NO;
                [newUri appendFormat:@"?%@=%@",key,[data objectForKey:key]];
            }else {
                [newUri appendFormat:@"&%@=%@",key,[data objectForKey:key]];
            }
        }
    }
    
    NSLog(@"%@", newUri);
    
    NSMutableURLRequest *request=[[NSMutableURLRequest alloc]init];
    [request setURL:[NSURL URLWithString:newUri]];
    [request setHTTPMethod:@"GET"];
    [request setTimeoutInterval:40];
    conn=[[NSURLConnection alloc]initWithRequest:request delegate:self];
    if (nil == conn) {
        return NO;
    }
    receiveData = [[NSMutableData alloc]initWithLength:0];
    return YES;
}
#pragma conn delegate
-(void) connection:(NSURLConnection *)theConnection didFailWithError:(NSError *)error{
    if (self.conn != theConnection)         return;
    [delegate commError];
}

-(void) connection:(NSURLConnection *)theConnection didReceiveResponse:(NSURLResponse *)response{
    if (self.conn != theConnection) return;
    [receiveData setLength:0];
    NSHTTPURLResponse *httpResponse=(NSHTTPURLResponse *)response;
    [delegate httpResponse:httpResponse];
}

-(void) connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data{
    if (self.conn != theConnection) return;
    [receiveData appendData:data];
    
    NSString *str = [[NSString alloc] initWithData:receiveData encoding:NSUTF8StringEncoding];
    NSLog(@"receive data: %@", str);    
}

-(void) connectionDidFinishLoading:(NSURLConnection *)theConnection{
    if (self.conn != theConnection) return;
    [delegate httpFinish:self.receiveData];
}

-(void)close{
    if (self.conn != nil) {
        [self.conn cancel];
        self.conn=nil;
    }
    self.receiveData = nil;
}

-(void) dealloc{
    self.delegate = nil;
    NSLog(@"------dealloc");
}

@end


主要代码在ViewController.m中
#import "ViewController.h"
#import "httpComm.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
  
    NSString *url = @"http://****/Index.asp";
    NSDictionary *dc = [NSDictionary dictionaryWithObject:@"mmmm" forKey:@"gmac"];
    
    NSString *tmp = [dc objectForKey:@"gmac"];
    NSLog(@"%@", tmp);
    
    httpComm *http=[[httpComm alloc]init];
    
    [http sendRequest:url params:dc];
    
        
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end


我想在ViewController里访问http.receivedata 数据,但是发现用if语句会发现receivedata还没有赋值。

在-(void) connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data里可以得到receivedata值,但我想传回给ViewController类,怎么实现呢?

9 个解决方案

#1


既然你吧http的请求单独封装在httpComm 里面,那么可以再httpComm 的
-(void) connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data
获取到receivedata后通过delegate 或者block 传回到自己需要的地方

#2


引用 1 楼 xxo1986cxm 的回复:
既然你吧http的请求单独封装在httpComm 里面,那么可以再httpComm 的
-(void) connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data
获取到receivedata后通过delegate 或者block 传回到自己需要的地方


就是不会用delegate回传阿,给点代码提示还行啊

#3


@interface ViewController ()<httpDelegate>


httpComm *http=[[httpComm alloc]init];
   http.delegate = self ; 
[http sendRequest:url params:dc];



-(void) httpFinish:(NSData *)data
{
 //获取数据
}



-(void) connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data{
    if (self.conn != theConnection) return;
    [receiveData appendData:data];     
    NSString *str = [[NSString alloc] initWithData:receiveData encoding:NSUTF8StringEncoding];
    NSLog(@"receive data: %@", str);    
     [delegate httpFinish:receiveData];
}


#4


我按你说的
我把-(void) httpFinish:(NSData *)data
{
 //获取数据
NSLog(...);
}
加在controler.m里了
 但是nslog并没有发现任何数据的到来阿。


-(void) connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data{
    if (self.conn != theConnection) return;
    [receiveData appendData:data];     
    NSString *str = [[NSString alloc] initWithData:receiveData encoding:NSUTF8StringEncoding];
    NSLog(@"receive data: %@", str);    
   <span style="color: #FF0000;">  [delegate httpFinish:receiveData];</span>
}这个仍然是放在httpcomm.m里的是吧

#5


帮帮忙阿
-(void) httpFinish:(NSData *)data
{
 //获取数据
}
究竟何时被调用阿,data是传入的参数阿,我想把数据传出去怎么办呢

#6


ViewController 的定义需要修改
@interface ViewController ()<httpDelegate>
然后httpComm 实例的时候需要设置delegate
httpComm *http=[[httpComm alloc]init];
http.delegate = self ;
[http sendRequest:url params:dc];

然后实现httpDelegate
-(void) httpResponse:(NSHTTPURLResponse *)response
{}
-(void) httpFinish:(NSData *)data
{}
-(void) commError
{}

httpcomm.m修改
在 httpcomm 里面合适的地方分别 调用
[delegate httpResponse:httpResponse];
[delegate httpFinish:self.receiveData];
[delegate commError];

比如你说"-(void) connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data里可以得到receivedata值"
那么
-(void) connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data
{
…………
[delegate httpFinish:data];
}
那么在ViewController.m实现httpDelegate的
-(void) httpFinish:(NSData *)data
{
//这里可以拿到data
}

#7


@xxo1986cxm:你说的这些我都实现了.现在的问题是:

-(void) httpFinish:(NSData *)data
{
}里头获得的data如何传给 ViewController的viewdidload()??
因为我的sendrequest是在里头实现的,我想接收response。获取data数据,以便进行下面的操作。

我现在暂时改用同步get做的,异步情况下,怎么把data如何传给 ViewController的viewdidload()??或者说传到sendrequest的主逻辑代码处??

#8


异步的时候传给viewdidload ()里面使用? 那就很难实现了
你可以换一种实现方法,把
httpComm *http=[[httpComm alloc]init];     
[http sendRequest:url params:dc];
单独封装出来,放在其他地方实现,等请求完成后也就是
-(void) httpFinish:(NSData *)data
{
ViewController *vc =[ [ViewController alloc] init]
// 然后再给vc设置一个属性,赋值data,这样viewdidload ()里面就可以获取的到服务器的返回数据了 
}

#9


@xxo1986cxm:


谢啦:)

#1


既然你吧http的请求单独封装在httpComm 里面,那么可以再httpComm 的
-(void) connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data
获取到receivedata后通过delegate 或者block 传回到自己需要的地方

#2


引用 1 楼 xxo1986cxm 的回复:
既然你吧http的请求单独封装在httpComm 里面,那么可以再httpComm 的
-(void) connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data
获取到receivedata后通过delegate 或者block 传回到自己需要的地方


就是不会用delegate回传阿,给点代码提示还行啊

#3


@interface ViewController ()<httpDelegate>


httpComm *http=[[httpComm alloc]init];
   http.delegate = self ; 
[http sendRequest:url params:dc];



-(void) httpFinish:(NSData *)data
{
 //获取数据
}



-(void) connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data{
    if (self.conn != theConnection) return;
    [receiveData appendData:data];     
    NSString *str = [[NSString alloc] initWithData:receiveData encoding:NSUTF8StringEncoding];
    NSLog(@"receive data: %@", str);    
     [delegate httpFinish:receiveData];
}


#4


我按你说的
我把-(void) httpFinish:(NSData *)data
{
 //获取数据
NSLog(...);
}
加在controler.m里了
 但是nslog并没有发现任何数据的到来阿。


-(void) connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data{
    if (self.conn != theConnection) return;
    [receiveData appendData:data];     
    NSString *str = [[NSString alloc] initWithData:receiveData encoding:NSUTF8StringEncoding];
    NSLog(@"receive data: %@", str);    
   <span style="color: #FF0000;">  [delegate httpFinish:receiveData];</span>
}这个仍然是放在httpcomm.m里的是吧

#5


帮帮忙阿
-(void) httpFinish:(NSData *)data
{
 //获取数据
}
究竟何时被调用阿,data是传入的参数阿,我想把数据传出去怎么办呢

#6


ViewController 的定义需要修改
@interface ViewController ()<httpDelegate>
然后httpComm 实例的时候需要设置delegate
httpComm *http=[[httpComm alloc]init];
http.delegate = self ;
[http sendRequest:url params:dc];

然后实现httpDelegate
-(void) httpResponse:(NSHTTPURLResponse *)response
{}
-(void) httpFinish:(NSData *)data
{}
-(void) commError
{}

httpcomm.m修改
在 httpcomm 里面合适的地方分别 调用
[delegate httpResponse:httpResponse];
[delegate httpFinish:self.receiveData];
[delegate commError];

比如你说"-(void) connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data里可以得到receivedata值"
那么
-(void) connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data
{
…………
[delegate httpFinish:data];
}
那么在ViewController.m实现httpDelegate的
-(void) httpFinish:(NSData *)data
{
//这里可以拿到data
}

#7


@xxo1986cxm:你说的这些我都实现了.现在的问题是:

-(void) httpFinish:(NSData *)data
{
}里头获得的data如何传给 ViewController的viewdidload()??
因为我的sendrequest是在里头实现的,我想接收response。获取data数据,以便进行下面的操作。

我现在暂时改用同步get做的,异步情况下,怎么把data如何传给 ViewController的viewdidload()??或者说传到sendrequest的主逻辑代码处??

#8


异步的时候传给viewdidload ()里面使用? 那就很难实现了
你可以换一种实现方法,把
httpComm *http=[[httpComm alloc]init];     
[http sendRequest:url params:dc];
单独封装出来,放在其他地方实现,等请求完成后也就是
-(void) httpFinish:(NSData *)data
{
ViewController *vc =[ [ViewController alloc] init]
// 然后再给vc设置一个属性,赋值data,这样viewdidload ()里面就可以获取的到服务器的返回数据了 
}

#9


@xxo1986cxm:


谢啦:)