5

How to track usage of data sent and received through my app?

I just want to record bytes sent and received when my app is running. If I can get separate info for Wifi and Cellular network then it would be great but its not a priority.

I know how to find total usage of device - https://stackoverflow.com/a/8014012/427969

Also, I know I can use Instruments to collect network activity data but I want to record this data in my app so need a programmatic way to do this.

I tried to search this but all I find is device's network usage and not a particular app's usage.

The following is the screenshot of Whatsapp's Settings -> Usage page, which would give a better idea of what I am trying to do:

enter image description here

I am using AFNetworking for HTTP request and response as follows:

NSData* requestData = [NSJSONSerialization dataWithJSONObject:info options: NSJSONWritingPrettyPrinted error:&error];
if(error != nil) {
    NSLog(@"Error: converting JSON: %@, %@", error, error.userInfo);
}

[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
[request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody: requestData];

/*
    ################### ----------------- ###################
    WILL [requestData length] BE THE NUMBER OF BYTES SEND ???
    ################### ----------------- ###################
*/
NSLog(@"data bytes: %d", [requestData length]); 

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL .....];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest: request                                                                                 
    success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {

    } failure: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {

}];
[operation start];

I have updated my question.

Can somebody please answer: Is [requestData length] the number of bytes SEND for one request?

Community
  • 1
  • 1
user427969
  • 3,836
  • 6
  • 50
  • 75
  • 1
    The answer likely depends on what API you're using to do your networking... sockets? CFNetworking? NSURLRequest? A third-party solution? But the basic idea would probably be to track the transfers in and out and log them to disc somewhere. – Carl Veazey Jan 22 '13 at 02:42
  • @CarlVeazey Veazey I am using AFNetworking – user427969 Jan 22 '13 at 03:02
  • Any idea or suggestion on how to implement this? – user427969 Jan 23 '13 at 23:36

2 Answers2

1

There are several Methods depending on which class you are using to Download with AFNetworking

AFHTTPRequestOperation for example has the following method:

setDownloadProgressBlock:^(NSInteger bytesRead, NSInteger totalBytesRead, NSInteger totalBytesExpectedToRead)

For the other way around, there is a method like this:

setUploadProgressBlock:^(NSInteger bytesWritten,long long totalBytesWritten,long long totalBytesExpectedToWrite)

With this to methods you should try to keep track of all your uploaded and downloaded data.

AFJSONRequestOperation is a subclass of AFHTTPRequestOperation, so those method should work in either class.

And please be aware that only sending a "json request" to a webserver doesn't mean that you are not downloading. For sure you have to get the content - the json - which would be your data downloaded.

Further you qre questioning if [requestData length]is telling you the proper size sent to the server. That's not the exact size, because within your requestData you do not have the additional Headers for the HTTP request, therefore your size will be a little bit smaller than the original bytes sent.

Every time one of the methods above is executed you should add the result of bytes read and add it to the bytes you read before this method was executed. For sure you have to save the current bytesRead permanently in coredata for example or any other persistence store.

Alexander
  • 7,178
  • 8
  • 45
  • 75
  • thanks for reply. I have updated my answer. I am using `AFJSONRequestOperation` – user427969 Jan 22 '13 at 22:27
  • Also, I am not sure if that matters but I am not downloading a file. I send request to a web server and get a response back in JSON. – user427969 Jan 22 '13 at 22:33
  • Thanks for your reply. You mentioned that there are several methods depending on class I use. Could you please suggest some method that I can look into ? I already saw setDownloadProgressBlock but I am not downloading anything, I am sending a request to web server. I hope you can suggest something. – user427969 Jan 24 '13 at 01:36
  • If you are sending a Request to a server you are indeed downloading something. As well if you are only requesting a website, the content has to be delivered. AFJSONRequestOperation is a subclass of AFHTTPRequestOperation, so you could try using the method I mentioned above. For the other case, uploading something, you could try to save the bytes u are going to send to the server. See my edits, there are two methods to go with – Alexander Jan 24 '13 at 07:30
  • Thanks a lot it worked well. Please excuse my knowledge regarding downloading and uploading data. When I searched about the methods I only found uses regarding a file and that made me confused. Thanks again. – user427969 Feb 13 '13 at 05:18
1

I used the methods mentioned by Alexander as follows:

AFJSONRequestOperation *operation = [[AFJSONRequestOperation alloc] initWithRequest: request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    // success
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    // failure
}];

[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
    // bytes received - saved bytesRead variable to NSUserDefaults
}];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
    // bytes sent - saved bytesWritten variable to NSUserDefaults
}];
[operation start];
user427969
  • 3,836
  • 6
  • 50
  • 75