Lyd
Lyd

Reputation: 2096

How to correctly distribute methods in Objective C

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

Answers (2)

FluffulousChimp
FluffulousChimp

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

Toploulou
Toploulou

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

Related Questions