2

I was wondering why in NSURLResponse in a sendSynchronousRequest would not receive information every time even though no change has occurred. It looks like there is NSData being received but it is not getting converted into a string and then not getting converted to an NSArray via my json call. The code is below. The code below is all in a single function but dont feel the name is necessary.

NSURL *searchURL = [NSURL URLWithString:@"website"];
NSString *searchedItem = searchFood.text;
NSString *post = [NSString stringWithFormat:@"a=ajax_food_search3&u_id=*******&value=%@", searchedItem];
NSData *pData = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *pLength = [NSString stringWithFormat:@"%d", [pData length]];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setURL:searchURL];
[request setHTTPMethod:@"POST"];
[request setValue:pLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:pData];
//[request setTimeoutInterval:30];

NSURLResponse *response = nil;
NSError *err = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *sData = [NSString stringWithUTF8String:[data bytes]];

NSArray *jsonFoodArr = [sData objectFromJSONString];
if(jsonFoodArr != nil){
    NSDictionary *jsonDic = [jsonFoodArr objectAtIndex: 0];
    NSDictionary *jsonDat = [jsonDic objectForKey:@"dat"];
    NSArray *jsonFoodList = [jsonDat objectForKey:@"file"];

    for (int i = 0; i < [jsonFoodList count]; i++) {
        NSDictionary *fill = [jsonFoodList objectAtIndex:i];
        NSDictionary *foodDat = [fill objectForKey:@"fdat"];
        [foodResults addObject:[foodDat objectForKey:@"f_name"]];
    }

    NSLog(@"%@\n", foodResults);
}else {
    NSLog(@"Failed to read information");
}

I wanted to add that my NSData object gives me the same bytes when the connection fails as well as when it works. I am not sure if it is because they are using the same memory address, which I feel would be completely unlikely for the fact that there is no way for the computer to be that lucky when I restart the app. Either way, I receive no error, I do receive a response and I do receive some sort of data but the NSString is not converting it every time to give me a json that is not nil.

I have found after doing 1000 calls to the server that the string that is coming from the connection converted into an NSString is giving me this when it fails.

    [
          {
            "cmd": null,
            "dat": {
              "file": [
                {
                  "name": "Rob's Doc",
                  "f_id": "6",
                  "user_id": "******",
                  "ts": "1329488441"
                },
                {
                  "name": "Objective C",
                  "f_id": "566",
                  "user_id": "******",
                  "ts": "1328116043"
                },
                {
                  "name": "Football Challenge",
                  "f_id": "314",
                  "user_id": "******",
                  "ts": "1326396493"
                }
              ],
              "view_id": null
            }
          }
        ]
    ll}}]
0=0 Pragma: no-cache Connection: close Transfer-Encoding: chunked Content-Type: text/html
     10c [
      {
        "cmd": null,
        "dat": {
          "file": [
            {
              "name": "**** Doc",
              "f_id": "6",
              "user_id": "******",
              "ts": "1329488441"
            },
            {
              "name": "Objective C",
              "f_id": "566",
              "user_id": "******",
              "ts": "1328116043"
            },
            {
              "name": "Football Challenge",
              "f_id": "314",
              "user_id": "******",
              "ts": "1326396493"
            }
          ],
          "view_id": null
        }
      }
    ] 0

The NSHTTPResponse status code for fail and pass is 200, so the page is loading still as well but this response occurs when I can not retrieve a json. I can make multiple calls via the browser and have this work just fine. Android does not fail to obtain a json in the entire time I was coding with them. So two systems do not give me this response.

ANSWER:

The answer to this problem pertains to the NSString that is being used to convert NSData what should be there is

NSString *sData = [[NSString alloc] initWithData: data encoding: NSUTF8String]

This is because the original way in the code has a chance that the string will try to access and store information from memory addresses outside the size of the data that would still be in NSUTF8String format. When you allocate the string ,the string is only the size of the data and thus will only convert the data to that size and only store the data at that size.

This caused my server response to always have the correct string to then access the JSON objects from. Basically, it was a pointer issue for lack of better words in the sense that the original code was trying to access more then it was supposed to because it was an open ended size and copy and was being a little too greedy alloc will not allow string to be greedy.

shareef
  • 9,255
  • 13
  • 58
  • 89
Rob
  • 426
  • 8
  • 23
  • You're passing err by reference, but not checking it afterward. Add something like this after your sendSynchronousRequest: `if (err) NSLog(@"Error: %@", [err localizedDescription]);` – bneely Feb 20 '12 at 17:23
  • 1
    err is nil and is not firing anything. So when I put that in the code it will not say anything. I just tried it to double check cause I was getting nil before but thought maybe your call did something different. – Rob Feb 20 '12 at 17:51
  • 1
    Code looks correctly for me at the first sight. I would chec, whether your website/server is the devil by writing a little script that makes thousand calls and checking whether there are glitches. – Paul Feb 20 '12 at 20:48
  • I will try that. I do have the issue of this working on android and yet partially fails here :-) Find that more interesting then not. I hope the server is not the devil so crossing fingers that this will not glitch. – Rob Feb 20 '12 at 20:55
  • There might be an issue with people logging on at the same time cause it seems to fail more when I continue to login via the internet since the browser handles the wait while this does not seem to get put into the queue and just denies it. – Rob Feb 20 '12 at 21:12
  • @Paul Engstler. You were correct there is an issue with the server. I went back in and tested my Android code, though it was not failing a lot it is failing with a jsonexception error. The string comes in but then can not be converted because the edit above shows what comes back, which is not in json format. – Rob Feb 22 '12 at 16:58
  • If you've answered your own question, please ad it as an answer and accept it. This will help others who have a similar question and will also remove this question from the Unanswered list. Cheers. – Jeff Wolski Apr 12 '12 at 21:12
  • Sorry didn't know if that was Kosher or not, so thank you for the information I greatly appreciate it. – Rob Apr 13 '12 at 13:12

1 Answers1

1

ANSWER:

The answer to this problem pertains to the NSString that is being used to convert NSData what should be there is

NSString *sData = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]

This is because the original way in the code has a chance that the string will try to access and store information from memory addresses outside the size of the data that would still be in NSUTF8String format. When you alloc the string the string is only the size of the data and thus will only convert the data to that size and only store the data at that size. This caused my server response to always have the correct string to then access the JSON objects from. Basically, it was a pointer issue for lack of better words in the sense that the original code was trying to access more then it was supposed to because it was an open ended size and copy and was being a little too greedy alloc will not allow string to be greedy.

Mihir Oza
  • 2,768
  • 3
  • 35
  • 61
Rob
  • 426
  • 8
  • 23