iphone - 如何返回从 objective-c (iPhone) 中的 Web 服务获取的数据?

标签 iphone objective-c ios

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

但我正在从事一个使用网络服务的项目。我可以连接到 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:
}

在此感谢任何帮助! 谢谢

最佳答案

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

  1. 创建一个委托(delegate)接口(interface)
  2. 使用积木

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

快速概述我给出的两个选项:

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。使用 block

此解决方案与第一个解决方案非常相似 - 但在我看来更优雅一些。在这里,我们将更改 RequestClass 以使用 block 而不是委托(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/

相关文章:

iphone - iPhone 上有多个 GPS 应用程序在后台运行?

ios - 不同 NSArray 对象的组合

ios - XCTest 无法找到文本字段

iphone - 可以将多个 NSUndoManager 与一个 Core-Data ManagedObjectContext 一起使用吗?

iphone - 屏幕分辨率和浏览器分辨率的区别

ios - CSSearchableItemAttributeSet 的 contentDescription 属性不支持换行格式

javascript - 在不影响测量的情况下测量在 javascript 中呈现的 html

ios - UICollectionViewCell - 不同大小类的不同布局

iphone - 需要传递什么值?http ://maps. google.com/maps/geo?q=%@&output=csv

ios - 如何在 iOS 版 Twitter 中上传动画 GIF?