这可能是一个愚蠢的问题。对不起,如果是。

但是我正在开发一个使用Web服务的项目。我可以连接到Web服务并获得我需要的数据。

我想要一个方法,将从Web服务获得的数据返回给调用方。唯一的问题是,只能在ConnectionDidFinishLoading方法内部获取数据,而无法从我的方法访问此数据。

这是我的代码,可以正常工作:

- (NSData *) dataForMethod:(NSString *)webMethod withPostString:(NSString *)postString
{
    NSURL *url = [NSURL URLWithString:[SigameWebServiceAddress stringByAppendingFormat:@"%@%@", @"/", webMethod]];
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
    NSString *msgLength = [NSString stringWithFormat:@"%d", [postString length]];

    [req addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [req addValue:msgLength forHTTPHeaderField:@"Content-Length"];
    [req setHTTPMethod:@"POST"];
    [req setHTTPBody: [postString dataUsingEncoding:NSUTF8StringEncoding]];

    conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
    if (conn)
    {
        webData = [NSMutableData data];
    }

    // I WOULD LIKE TO RETURN WEBDATA TO THE CALLER HERE, BUT WEBDATA IS EMPTY NOW, THE
    //connectionDidFinishLoading ONLY GETS CALLED WITH THE DATA I WANT AFTER THE COMPILER
    //IS DONE EXECUTING MY METHOD.
}

-(void) connection:(NSURLConnection *) connection didReceiveResponse:(NSURLResponse *) response
{
    [webData setLength: 0];
}

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

-(void) connection:(NSURLConnection *) connection didFailWithError:(NSError *) error
{
    NSLog(@"FATAL ERROR");
}

-(void) connectionDidFinishLoading:(NSURLConnection *) connection
{
    NSLog(@"DONE. Received Bytes: %d", [webData length]);

    NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];

    //---shows the XML---
    NSLog(@"%@", theXML);  //NOW, THIS IS THE DATA I WANT. BUT HOW CAN I RETURN THIS TO
                           //THE CALLER. I MEAN, THE CALLER THAT CALLED MY METHOD
                           //+ (NSData *) dataForMethod: withPostString:
}

感谢您的任何帮助!
谢谢

最佳答案

确实有两种方法可以解决此问题。

  • 创建委托(delegate)接口(interface)
  • 使用块

  • 我强烈建议您不要使用同步方法-除非您已经/已经围绕它们创建了自己的异步框架(即您正在手动启动另一个线程并在该线程上执行同步请求)。从长远来看,您将意识到您需要异步的请求,并且您必须对所有请求进行重新处理。

    为了快速概述我提供的两个选项:

    1.创建一个委托(delegate)接口(interface)

    这里的想法是创建一个执行请求的类,并创建调用者必须实现的协议(protocol)。请求完成后,您将使用数据在委托(delegate)上调用指定的方法:

    该协议(protocol)可能看起来像这样:
    @protocol RequestClassDelegate <NSObject>
    
    - (void)requestCompleted:(ResponseClass *)data;
    - (void)requestError:(NSError *)error;
    
    @end
    

    发出请求的类可能如下所示:
    @interface RequestClass : NSObject
    
    - (void)makeRequest:(id<RequestClassDelegate>)delegate;
    
    @end
    

    除了连接逻辑之外,请求类的实现可能还包含以下一些内容:
    @implementation RequestClass
    {
        __weak id<RequestClassDelegate> _delegate;
    }
    
    // Connection Logic, etc.
    
    - (void)makeRequest:(id<RequestClassDelegate>)delegate
    {
        _delegate = delegate;
        // Initiate the request...
    }
    
    -(void) connectionDidFinishLoading:(NSURLConnection *) connection
    {
        NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
    
        // Processing, etc.
    
        // Here we'll call the delegate with the result:
        [_delegate requestCompleted:theResult];
    }
    
    @end
    

    2.使用块

    此解决方案与第一个解决方案大致相同-但在我看来有点优雅。在这里,我们将RequestClass更改为使用块而不是委托(delegate):
    typedef void (^requestCompletedBlock)(id);
    typedef void (^requestErrorBlock)(NSError *);
    @interface RequestClass : NSObject
    
    @property (nonatomic, copy) requestCompletedBlock completed;
    @property (nonatomic, copy) requestErrorBlock errored;
    
    - (void)makeRequest:(requestCompletedBlock)completed error:(requestErrorBlock)error;
    
    @end
    

    那样的实现可能看起来像这样:
    @implementation RequestClass
    
    @synthesize completed = _completed;
    @synthesize errored = _errored;
    
    // Connection Logic, etc.
    
    - (void)makeRequest:(requestCompletedBlock)completed error:(requestErrorBlock)error
    {
        self.completed = completed;
        self.errored = error;
        // Initiate the request...
    }
    
    -(void) connectionDidFinishLoading:(NSURLConnection *) connection
    {
        NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
    
        // Processing, etc.
    
        // Here we'll call the delegate with the result:
        self.completed(theResult);
    }
    
    @end
    

    关于iphone - 如何返回从Objective-C(iPhone)的Web服务获取的数据?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8864699/

    10-11 20:12
    查看更多