Question

I am writing my first application objective-c for iOS 7.1. I'm probably something fundamentally do not understand why I have this question arose.

The application is quite simple: the client to communicate with an external service using web api. To send a http-requests I use NSURLSession. I have a simple architecture.

THETALETestViewController - this view controller. This class uses THETALEAPI.h THETALEAPI - is the realization of web api. I have highlighted in a separate class, to each external API method has been implemented in one place. Here is the formation of a query for each method. This class uses THETALEHttpHandler.h. THETALEHttpHandler - this class is directly responsible for sending http-request and receiving http-response.

Here is the code from THETALEHttpHandler.m to send POST - query.

-(void) sendPostToURL:(NSURL *)url withParams: (NSString *) inParams competion:(void     (^) (NSData *data)) completion
{
    NSLog(@"sendPostToURL");

    // _csrftoken a token in cookie
    NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
    [cookieProperties setObject:@"csrftoken" forKey:NSHTTPCookieName];
    [cookieProperties setObject:_csrftoken forKey:NSHTTPCookieValue];

    [cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];

    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
    [_httpCookieStorage setCookie:cookie];

    [_sessionConfig setHTTPCookieStorage:_httpCookieStorage];


    // tried and so
    // //   NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil //delegateQueue: [NSOperationQueue mainQueue]];   
    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:_sessionConfig];


    NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];

    // _csrftoken a token in the parameter
    NSString *params = [@[inParams, _csrftoken] componentsJoinedByString:@""];

    [urlRequest setHTTPMethod:@"POST"];
    [urlRequest setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];

    NSURLSessionDataTask * dataTask =[defaultSession dataTaskWithRequest:urlRequest
                                                   completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                    NSLog(@"Got response %@ with error %@.\n", response, error);
                                                       if(error == nil)
                                                       {
                                                           NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
                                                           NSLog(@"Data = %@",text);
                                                       }
                                                   completion(data);
                                                   }];
    [dataTask resume];

}

So, block completion is not running in main thread, and asynchronously, so while a request is sent and there is a reception and treatment response - main thread runs on. In principle, it is clear and logical, but I want to "login" using this method, respectively, by clicking on the "Login" I have to go after a successful request and response and processing the user should see the answer. What capabilities iOS achieve such behavior to main thread waiting for the completion of the asynchronous block and displays the appropriate information? Or maybe it is not worth waiting for, and it just somehow need to notify?

Unless, of course, does not make separate classes, and to do everything in viewController, then, assuming that delegates would come up, but I want to make a bit of modularity in its application.

Maybe I'm wrong designed system, then you can explain or show an example of how it is usually done?

I think that this requirement is rather banal and the answer is somewhere nearby, please explain, thanks in advance!

Was it helpful?

Solution

You can use AFNetworking for the API calls.Tutorial explaining in details how to use it the right way.Also you can use NSNotificationCenter to notify the view controller when the call is successful/fail

OTHER TIPS

Firstly, you can execute a block on the main thread using dispatch_sync. But that's not really the problem here. You're trying to do too much in one block of code.

Your flow needs to look something like this:

  1. Have you recorded a username/password?
  2. If not, ask for one
  3. Run your network request
  4. Error handling would include looking for invalid credentials, in which case the request would be cancelled and your code would jump to step 2.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top