Resolved NSURLConnection missing data 1 out of 3/4 times. (In middle of response)

Discussion in 'iOS Programming' started by DennisBlah, Dec 30, 2014.

  1. DennisBlah, Dec 30, 2014
    Last edited: Dec 31, 2014

    DennisBlah macrumors 6502

    DennisBlah

    Joined:
    Dec 5, 2013
    Location:
    The Netherlands
    #1
    Hi all,

    I'm having an simple login in my app. When logged in it will go back to the main screen where it 'syncs' data.

    At the start of this 'sync' it checks if there is an udid set and an session.
    If so, we check this session, update it, and start the syncing.
    i.e. user profile data.

    Now, my NSURLConnection gives me an empty "session" value from my result once in the 3 or 4 times.

    Here is how I retrieve it:
    Code:
    NSString *storedSession = [[applicationData firstObject] objectAtIndex: indexOfSession];
        
        NSURL *url=[NSURL URLWithString:@"http://mydomain.com/myApp/sessions.php?action=session"];
        NSString *post = [NSString stringWithFormat: @"user_udid=%@&user_appSession=%@", [[applicationData firstObject] objectAtIndex: indexOfUDID], [[applicationData firstObject] objectAtIndex: indexOfSession]];
    
        NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
        
        NSString *postLength = [NSString stringWithFormat:@"%lu", [postData length]];
        
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
        [request setURL:url];
        [request setHTTPMethod:@"POST"];
        [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
        [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
        [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        [request setValue:@"Niesters-App" forHTTPHeaderField:@"User-Agent"];
        [request setHTTPBody:postData];
        //[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
        
        NSError *error = [[NSError alloc] init];
        NSHTTPURLResponse *response = nil;
        NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    
        if ([response statusCode] >=200 && [response statusCode] <300) {
            NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
            SBJsonParser *jsonParser = [SBJsonParser new];
            NSDictionary *jsonData = (NSDictionary *) [jsonParser objectWithString:responseData error:nil];
            NSInteger result = [(NSNumber *) [jsonData objectForKey:@"result"] integerValue];
            if(result == 0) {
                NSLog(@"No access.. incorrect session???");
                return NO;
            } else if(result == 1) {
                NSLog(@"Session check failed...");
                return NO;
            } else if(result == 2) {
                NSLog(@"Session check success!");
                NSString *session = [jsonData objectForKey: @"session"];
    
                NSLog(@"response: %@", responseData);
                //Cleanup data
                [appData truncatetable:@"userdata"];
                //Insert new data
    //an insert query with the udid and session for later use.
    //macrumors is kicking it out for security :-/
                [appData executeQuery:insertSession];
                return YES;
            } else {
                NSLog(@"Unknown... weird error...");
                return NO;
            }
        } else {
            serverConnection = NO;
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Connection Failed" message:@"Could not establish a connection with the server. The app data might not be up-to-date" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
            [alert show];
            return NO;
        }
    }
    
    
    The result I get 1 out of 3/4 times, in my xcode console :
    Code:
    Session check success!
    response: {"result":2,"session":"","userlevel":1}
    
    It still goes pass, because the old session and the udid passed the php script. (result == 2)
    But then still "session" is empty!?

    Here comes the php script. (I simplified it, to always give session 'asd')

    Code:
    
    header('Content-type: application/json');
    $result = '{"result":0}';
    
    
    				if(valueSet($_POST['user_appSession'])) {
    
    					$appSessionQ = $dbController->getQuery('user_id, user_level','dns_users','user_udid = "' . mysql_real_escape_string($_POST['user_udid']) . '" AND user_appSession = "' . mysql_real_escape_string($_POST['user_appSession']) . '"');
    					if($appSessionQ !== 'none') {
    						switch($action) {
    							case 'session':
    								$newSession = 'asd';//newAppSession();
    								
    								$updateQ = $dbController->updateQuery(array('user_appSession'),
    																array(mysql_real_escape_string($newSession)),
    																'users',
    																'user_udid = "' . mysql_real_escape_string($_POST['user_udid']) . '" AND user_appSession = "' . mysql_real_escape_string($_POST['user_appSession']) . '"');
    								if($updateQ !== 'error')
    									$result = '{"result":2,"session":"' . $newSession . '","userlevel":' . $appSessionQ->user_level . '}';
    								else
    									$result = '{"result":1}';
    							break;
    
    
    
    
    
    echo $result;
    
    (I kicked some things out. I also have an empty(action) : login)
    When user_appSession is set
    cases:
    'udid' (also updates the device udid with the new one provided. and a new session)
    'getAccount' (Will give me back my profile info)


    All these cases are not kicking in, and is not to be discussed.

    Is it possible that NSURLConnection sometimes does not get all information in the middle of the responseData ?

    Even with session = 'asd' it comes back blank 1 out of 3/4 times.

    However when I do this from my browser, it keeps working. I can keep bombing the page, but it keeps working.
     
  2. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #2
    I have no idea.

    Is it possible that you're getting back a cached response of some kind?
     
  3. mfram macrumors 65816

    Joined:
    Jan 23, 2010
    Location:
    San Diego, CA USA
    #3
    I don't see any kind of error handling for the sendSynchronousRequest. The return value is not checked for NULL and the error variable isn't examined. Is it possible the Request isn't succeeding? Or maybe you just took the error handling out when showing your sample code to simplify.
     
  4. DennisBlah, Dec 30, 2014
    Last edited: Dec 31, 2014

    DennisBlah thread starter macrumors 6502

    DennisBlah

    Joined:
    Dec 5, 2013
    Location:
    The Netherlands
    #4
    I don't see how I could get an cached result tho :s
    Even if.. Why is it empty? I NEVER have an empty session returned.
    Either I receive 'asd' or result = 0 or 1 without any more values

    Ehm no I do not actually :-$
    But.. I don't think it'll give me an error since the responsecode is fine and will not reach an else as it's within this range.
    Code:
     if ([response statusCode] >=200 && [response statusCode] <300) {
    
    So it will never reach:
    Code:
    } else {
        NSLog(@"Some connection issue");
        if (error) NSLog(@"Error: %@", error);
    }
    
    The return value, is not NULL, because the returned value is:
    {"result":2,"session":"","userlevel":1}

    That's the most strangest thing... Even tho, the PHP ALWAYS returns 'asd' in "session"

    If the return was NULL, xcode would not know that I'm in the if(result == 2) and would not give me an 'success' and the returned value.

    As you see in the PHP, my default result is 0

    So or.. I get an 0 back, when the 'request' is incorrect, 1 when it failed for example credentials failed or some sql injection, or a 2 which succeed, and will also give an userlevel and a session for my app.





    ----

    To be honest, I don't even know quite well why I'm doing it this way, except for the fact I need to POST vars to the script.

    like this
    Code:
    NSString *authURL = [NSString stringWithFormat: @"%@/checkAuth.php?udid=%@", theHost, UDID];
            NSData *authData = [NSData dataWithContentsOfURL: [NSURL URLWithString: authURL]];
            NSString *authResult = [[NSString alloc] initWithData: authData encoding: NSUTF8StringEncoding];
    Is something from another application I made, which authenticates the device to an simple file on a server based on UDID.

    I'm still kinda new into xCode, I got a lot to learn, even tho it's still obj-c

    Maybe there is a simpler way to send a POST call to an page ?
    I'm gonna give it a try with the RestKit library however it will increase the size of my app since the library alone is already 1.5mb

    Please advice


    -----


    My appologies for everyone who is looking into this topic.
    This is an PHP fault.

    On the moment the unit receives a new UDID, I do trigger a different case in php
    which will update the new udid to the user, and ofcourse a new session.

    However, the $newSession is never being set with a session in this php case.

    Thanks all!
     
  5. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #5
    I'm going to suggest that you need to spend a bit more time doing your own, independent debugging before requesting help here.
     

Share This Page