views:

451

answers:

3

I've really struggled to figure out why my web service call is riddled with junk data.

I have a UITableViewController that calls the web service and also acts as the NSURLConnectionDelegate.

Here is the delegate method of interest, note the NSLog statements.

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    NSLog(@"data %@", [[NSString alloc] initWithUTF8String: [data bytes]]);
    NSLog(@"before %@", [NSString stringWithUTF8String: self.rawData.bytes]);
    [self.rawData appendData:data];
    NSLog(@"after %@", [NSString stringWithUTF8String: self.rawData.bytes]);
}

Here is the resulting log after a number of attempts:

2009-07-10 09:04:20.339 SundialInvoice[91493:20b] data {"items": [], "request": 

"/inventory/delivered.json"}
2009-07-10 09:04:20.339 SundialInvoice[91493:20b] before 
2009-07-10 09:04:20.340 SundialInvoice[91493:20b] after {"items": [], "request": "/inventory/delivered.json"} SundialInvoice] [PID 

2009-07-10 09:04:23.153 SundialInvoice[91493:20b] data {"items": [], "request": "/inventory/delivered.json"}l 4] [Mes
2009-07-10 09:04:23.154 SundialInvoice[91493:20b] before 
2009-07-10 09:04:23.154 SundialInvoice[91493:20b] after {"items": [], "request": "/inventory/delivered.json"} SundialInvoice] [PID 

2009-07-10 09:04:27.913 SundialInvoice[91493:20b] data (null)
2009-07-10 09:04:27.913 SundialInvoice[91493:20b] before 
2009-07-10 09:04:27.914 SundialInvoice[91493:20b] after {"items": [], "request": "/inventory/delivered.json"} SundialInvoice] [PID 

2009-07-10 09:04:30.486 SundialInvoice[91493:20b] data {"items": [], "request": "/inventory/delivered.json"}ice/1.0 CFN
2009-07-10 09:04:30.487 SundialInvoice[91493:20b] before 
2009-07-10 09:04:30.487 SundialInvoice[91493:20b] after {"items": [], "request": "/inventory/delivered.json"} SundialInvoice] [PID

Where is the trailing garbage data coming from? I have run the web service with curl several times and the garbage is not coming from it.

+1  A: 

try the following:

 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [rawData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"%@",rawData);
}

Also what have you declared rawData as???

zPesk
+3  A: 

I think the garbage comes from the logging:

[NSString stringWithUTF8String:self.rawData.bytes]

Here you are saying that you want an NSString from this C-string (= array of bytes terminated by zero). The problem is that the bytes method of NSData does not return data terminated by a zero, because it’s an ordinary array, not a C-string. Therefore the NSString initializer grabs even the bytes after the end of the received NSData, until it reaches some zero byte previously stored in memory.

zoul
+3  A: 

To create an NSString from an NSData, you should use initWithData:encoding:, like the following:

NSString *str = [[NSString alloc] initWithData:self.rawData
                                      encoding:NSUTF8StringEncoding];
NSLog(@"Before: %@", str);
[str release];

Treating NSData bytes as C string might cause some security vulnerabilities.

notnoop