这可能是个愚蠢的问题。对不起,如果是的话。
但我正在从事一个使用网络服务的项目。我可以连接到 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。使用 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/