How to obtain the returned value of an uncalled method in Objective-C
I'm using ASIHTTPRequest to perform an asynchronous URL request using a method named submitUserCredentials from my iOS application. The request is being sent just fine, but the problem is that when the response is returned from the server, ASIHTTPRequest is set up so that another method, requestFinished, receives and returns it.
When submitUserCredentials is the method that I开发者_开发技巧'm running from my view controller in the first place, how do I get hold of the server response that requestFinished returns?
You set up your ViewController to conform to the ASIHTTPRequestDelegate protocol:
@interface MyViewController : UIViewController <ASIHTTPRequestDelegate>
Then, you implement the
-(void) requestFinished(ASIHTTPRequest *)request;
method in your ViewController's implementation. Now when the request is finished the requestFinished: method in your ViewController will be called. If you need to pass information along with the request and have it be available in the requestFinished: method, you can set the ASIHTTPRequest's userInfo property to whatever you like, and it will be available in the request parameter in requestFinished:
Response to comment:
If you are willing to block your thread until the response is received, you can use the startSynchronous method (code from the ASI site http://allseeing-i.com/ASIHTTPRequest/How-to-use):
[request startSynchronous];
NSError *error = [request error];
if (!error) {
NSString *response = [request responseString];
}
This way your submitUserCredentials method would sit and wait while the server responds, but it would return the server response to that method. If blocking your UI while waiting a response won't work for you (and it probably won't) you can spin up a new thread to run your submitUserCredentials method and then call startSynchronous from there:
[NSThread detachNewThreadSelector:@selector(submitUserCredentials:)
toTarget:self withObject: credentials];
There are a few different things that you could be asking for here. I don't know which one it is. So I will just try to answer all of them.
Is it that you don't know when requestFinished
gets called? Did you set the request's delegate like so?
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
If you did that, then you should implement the requestFinished:
method for whatever it is that self
refers to above.
Are you not sure how to get the response string in requestFinished:
? In that case, the solution is simple:
- (void)requestFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
// Use when fetching binary data
NSData *responseData = [request responseData];
}
i.e. the request's responseString
or responseData
will give you what you are looking for.
Or are you saying that you want to somehow handle the response in submitUserCredentials
(maybe because there's a lot of context in this method's local variables)? If so, then your best bet is probably to use blocks:
- (IBAction)grabURLInBackground:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setCompletionBlock:^{
// Use when fetching text data
NSString *responseString = [request responseString];
// Use when fetching binary data
NSData *responseData = [request responseData];
}];
[request setFailedBlock:^{
NSError *error = [request error];
}];
[request startAsynchronous];
}
Or maybe the problem is that you expect ASIHTTPRequest to work in a synchronous manner? In that case, you can just do this:
- (IBAction)grabURL:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request startSynchronous];
NSError *error = [request error];
if (!error) {
NSString *response = [request responseString];
}
}
But its not recommended that you do this. Doing so will hang the main thread of your application (assuming you make the call in the main thread) which is not a good thing. If this really is the answer you were looking for, then you probably need to read up on event driven programming.
Note: All the code examples above were copied from the excellent "How to use it" documentation page of ASIHTTPRequest.
精彩评论