Reputation: 2096
I'm beginning to work on iPhone and iPad apps and still don't know how to do some things.
I'm developing an app which has login screen. When I develop in another app language, I have a class named WebService
where I do all the work to communicate with a Web Service and return the output or a boolean.
But in Objective C
I don't know how to do it.
Here is my code:
ViewController.m
- (IBAction)login:(id)sender {
/* Verify if username and password are correct */
Boolean loginCorrecto = [[WebService alloc] login:self.textFieldUsername.text password:self.textFieldPassword.text];
/* If login is correct, go to another view */
if (loginCorrecto) {
CupsViewController *cupsView = [self.storyboard instantiateViewControllerWithIdentifier:@"cupsViewController"];
[self.navigationController pushViewController:cupsView animated:YES];
}
/* If not, show an error message */
else {
}
}
WebService.m
- (Boolean)login:(NSString *)username password:(NSString *)password
{
/* HTTP POST */
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString:URL_CUPS]];
[request setHTTPMethod:@"POST"];
NSString *postString = [NSString stringWithFormat: @"username=%@&password=%@", username, password];
[request setValue:[NSString stringWithFormat:@"%d", [postString length]] forHTTPHeaderField:@"Content-length"];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData {
NSDictionary* jsonArray=[NSJSONSerialization
JSONObjectWithData:theData
options:0
error:nil];
//Get values of response of web service
status = [jsonArray objectForKey:@"status"];
message = [jsonArray objectForKey:@"message"];
if([status isEqualToString:@"Ok"]) {
id results = [jsonArray objectForKey:@"results"];
if(results != [NSNull null]) {
for(int r = 0; r < [results count]; r++) {
//Get more values
}
}
}
else {
//Show error
}
}
GOAL
So what I want is in login method of WebService.m
, return true if status
equals "Ok". But when that method finishes, status is still nil
. What do I have to do? Is there some way for doing that with classes I have or do I have to do Http Post
in ViewController.m
?
Upvotes: 0
Views: 88
Reputation: 9185
The design shouldn't be any different in Objective-C than any other language with which you're more familiar.
With few exceptions, interactions over the network should be asynchronous to avoid blocking the UI. You've already implemented the asynchronous NSURLConnection
API in your controller. Part of your question may relate to which class should be making calls to the web service. In general, I avoid having the view controller make these calls directly. It leads to bloated view controller classes. Instead, like your WebService
service class in whatever language you develop in, I would deal with making such calls there. Then, you need a way of reporting the response status back to the controller. As another answerer suggested, you might declare a WebServiceDelegate
protocol and implement that protocol in your controller. So, your WebService
instance acts as delegate of the NSURLConnection
instance you created to interact with the web service and the view controller acts as delegate of the WebService
instance that it spawns. Everything remains asynchronous; and you avoid making the view controller directly responsible for dealing with the web service. That said, some developers don't object to implementing web service calls directly in the view controller implementation.
Alternatively, you could declare a completion block on your WebService
class and execute that block when the NSURLConnection
completes (or fails, or times out, etc.) e.g.
Finally, your implementation of NSURLConnectionDelegate
protocol in the code you posted doesn't take into consideration the possibility that connection:didReceiveData:
may be called multiple times with chunks of data that you must assemble. Better to create an NSMutableData
ivar, appending data to it each time connection:didReceiveData:
is called. Finally, you can do your processing in connectionDidFinishLoading
. (And implement connection:didFailWithError:
.)
Upvotes: 1
Reputation: 1220
The [[NSURLConnection alloc] initWithRequest:request delegate:self];
will fire an asynchronous connection. you should declare a protocol (equivalent for interface in java) and implement it in your ViewController. When your async method is done, call one of the method of your protocol and pass any data you want
Upvotes: 0