Poor network performance can lead to an unsatisfactory user experience and is often perceived by the user as a failure of the mobile application, so it’s important to examine the performance of the network and identify bottlenecks.

With Apigee App Monitoring, you can get an overview that displays the number of requests made by your app, a count of errors, and the response time for the requests. You can also get specific, in-depth raw data on network performance. For instance, you can examine the network performance for specific carriers (such as AT&T or Verizon) or network types (such as 3G or 4G).

Enabling network monitoring

The default SDK initializer enables automatic interception of network calls for performance tracking. This feature instruments all network calls made using NSURLConnection (directly or indirectly).

For more information on initializing the App Services SDK, see Installing the Apigee SDK for iOS.

Adding advanced networking

Although the SDK provides functionality to automatically capture network performance metrics for all calls made through NSURLConnection by default, you may decide that you want to selectively capture network performance metrics. To do this, Apigee App Monitoring provides categories for NSString, NSData, and NSURLConnection, as well as a subclass of NSURLConnection (ApigeeURLConnection). The overhead for recording the network latency is minimal. Timestamps are recorded for the calls, and forwarded to a background thread, which pushes the data to the portal.

ApigeeUIWebView

The UIWebView class has been extended to measure the latency of network calls made through this control. The UIWebView delegate records the start and finish times of the request. There are two ways to use this control:

  • Create a UIWebView instance programmatically and add it as a subview to your view controller's main view
  • Drag a UIWebView class into your view, go to the identity inspector, and change the class from UIWebView to ApigeeUIWebView.

No other calls are needed. Just use the control as you normally would, and latency metrics will be pushed to your portal for calls loaded through the control.

NSString

A category is provided on NSString for methods that initialize a string from a URL, while capturing latency metrics for the underlying network calls. The following methods are available through the category:

+ (id) stringWithTimedContentsOfURL:(NSURL *) url encoding:(NSStringEncoding) enc error:(NSError **) error;
+ (id) stringWithTimedContentsOfURL:(NSURL *) url usedEncoding:(NSStringEncoding *) enc error:(NSError **) error;
- (id) initWithTimedContentsOfURL:(NSURL *) url encoding:(NSStringEncoding) enc error:(NSError **) error;
- (id) initWithTimedContentsOfURL:(NSURL *) url usedEncoding:(NSStringEncoding *) enc error:(NSError **) error;
- (BOOL) timedWriteToURL:(NSURL *) url atomically:(BOOL) useAuxiliaryFile encoding:(NSStringEncoding) enc error:(NSError **) error;

NSData

A category is provided on NSData for methods that initialize raw data from a URL, while capturing latency metrics for the underlying network calls. The following methods are available through the category:

+ (id) timedDataWithContentsOfURL:(NSURL *) url options:(NSDataReadingOptions) readOptionsMask error:(NSError **) errorPtr;
+ (id) timedDataWithContentsOfURL:(NSURL *) url;
- (id) initWithTimedContentsOfURL:(NSURL *) url options:(NSDataReadingOptions) readOptionsMask error:(NSError **) errorPtr;
- (id) initWithTimedContentsOfURL:(NSURL *) url;
- (BOOL) timedWriteToURL:(NSURL *) url atomically:(BOOL) atomically;
- (BOOL) timedWriteToURL:(NSURL *) url options:(NSDataWritingOptions) writeOptionsMask error:(NSError **) errorPtr;

NSURLConnection

A category is provided on NSURLConnection for methods that make network requests, while capturing latency metrics for the underlying network calls. The following methods are available through the category:

+ (NSURLConnection*) timedConnectionWithRequest:(NSURLRequest *) request delegate:(id < NSURLConnectionDelegate >) delegate;
+ (NSData *) timedSendSynchronousRequest:(NSURLRequest *) request returningResponse:(NSURLResponse **) response error:(NSError **) error;
+ (void) timedSendAsynchronousRequest:(NSURLRequest *) request queue:(NSOperationQueue *) queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*)) handler;
- (id) initTimedConnectionWithRequest:(NSURLRequest *) request delegate:(id < NSURLConnectionDelegate >) delegate;
- (id) initTimedConnectionWithRequest:(NSURLRequest *) request delegate:(id < NSURLConnectionDelegate >) delegate startImmediately:(BOOL) startImmediately;

ApigeeURLConnection, a subclass of the NSURLConnection, is also provided. ApigeeURLConnection doesn't override any behavior of the parent class. Instead, it uses the NSURLConnectionDataDelegate protocol to capture metrics. The subclass calls the delegate set, and records information from the necessary callbacks in the protocol before forwarding the message to the original delegate. The delegate property on the subclass is optional.

To enable network monitoring, replace references to the Android HTTPClient class with the Apigee HTTPClient. For example:

New HTTP client

Change:

HttpClient client = new DefaultHttpClient()

To:

HttpClient client = AppMonNet.getHttpClient();

Existing HTTP client

Alternatively, you can wrap an existing HTTP client. This approach is useful if you have a custom HTTP client, or if you need to initialize an HTTP client in a special way.

You can wrap an HTTP client like this:

HttpClient wrappedHTTPClient = AppMonNet.wrap(originalClient);

HttpURLConnection

If you're using HttpURLConnection, change:

java.net.URL url = new java.net.URL(uri);

To:

com.apigee.sdk.apm.android.URLWrapper url = AppMonNet.urlForUri(uri);

Our URLWrapper class provides the same interface as java.net.URL, so you can use it as though it were a normal URL object. For example, you can call openConnection on it.

WebView

If you're using a WebView, simply set our custom class for the client:

webView.setWebViewClient(new com.apigee.sdk.apm.android.ApigeeWebViewClient(this));

This call would be made in your onActivityCreated method (Fragment) or your onCreate method (Activity).

The default SDK initializer enables automatic interception of network calls for performance tracking.

For more information on initializing the App Services SDK, see Installing the Apigee SDK for JavaScript.

Viewing network monitoring data

To display network performance data for your app, select 'Monitoring' in the main menu of the App Services admin portal, then select 'API Performance' in the sidebar.

Here are the various ways you can view network performance data. For each view, you get:

  • A graph that plots network performance data for given points in time during a specified time period.
  • A summary table of the network performance data over the time period.
  • A table that lists the raw network performance data over the time period captured for each point in time.
Network performance view What it displays
Overview Total number of network requests, number of network errors, and response time.
By Network Types Data for each network type, such as 3G, 4G, and WiFi.
By Carriers Data by carrier, such as AT&T, Sprint, and Verizon.
By Platforms Data by device platform, such as iOS and Android.
By OS Versions Data by the OS version being run on the device.
By Domain Data by the target domain of the network request.

Displaying a time comparison

You can also display a view that compares network performance data for the currently selected time period with the same period yesterday or last week. This is useful for identifying network types or carriers that are particularly slow or whose performance is degrading over time.

To view a time comparison, click the 'Compare last week' or 'Compare yesterday' button above the graph.

Viewing raw data

Raw data can be very valuable in isolating performance bottlenecks. For example, by looking for slow response times and their corresponding URLs, you can determine which web services are performance inhibitors.

Below the graph and the network metrics summary, you’ll see a table that lists the data captured for each recorded point in time over the currently selected time period. Each data point covers one or more network requests to a specific URL for a specific network type and carrier. The columns of the table list the following information:

  • Status code: The HTTP status code of the response.
  • Timestamp: The time stamp of the data capture.
  • URL: The URL of the web service for the requests.
  • Response Time: The response time for the requests in milliseconds.
  • Platform: The platform for the device, such as iOS or Android.
  • Network Type: The type of the network, such as 3g, 4g, and wifi.
  • Carrier: The carrier, such as AT&T, Sprint, and Verizon.

Disabling Network Monitoring

To disable network monitoring, go to 'Configure' > 'Default Configs' in the App Services admin portal, then deselect the 'Enable Network Monitoring' checkbox.

Alternately, you can disable network monitoring programmatically by following the steps below.

If you want to disable the automatic network instrumentation feature, do the following when you initialize the ApigeeClient class in AppDelegate.m:

  1. Instantiate ApigeeMonitoringOptions and set interceptNetworkCalls:NO:

    ApigeeMonitoringOptions *monitoringOptions = [[ApigeeMonitoringClient alloc]init];
    monitoringOptions.interceptNetworkCalls = NO;
    				
  2. Send monitoringOptions as the value of the options parameter when you initialize the ApigeeClient class:

    		
    appDelegate.apigeeClient = [[ApigeeClient alloc]
                                initWithOrganizationId:orgName
                                applicationId:appName
                                options:monitoringOptions];
    				

For more information on initializing the ApigeeClient class, see Installing the Apigee SDK for iOS.

The App Monitoring feature of App Services does not automatically intercept network calls. To disable any network monitoring, simply remove any sections of your code that implement any of the network monitoring features described in 'Enabling network monitoring' above.

Do the following when you initialize the Apigee.Client class:

Note that proceeding with this step will disable all Apigee App Monitoring functionality in your app, including app usage, network, crash and error monitoring:

Set disableAnalytics:true when you initialize Apigee.Client:

var client_creds = {
	orgName:'your-org',
	appName:'your-app',
	disableAnalytics:true
}

dataClient = new Apigee.Client(client_creds);			 
		 

Refreshing network monitoring configuration

If your App Monitoring settings change while your app is running, you will need to manually refresh your App Monitoring configuration file. This will cause any changes, such as disabling app usage monitoring, disabling network monitoring, or changes to custom logging to take effect immediately.

For information on how to refresh your configuration file, see Refreshing app monitoring configuration.

Help or comments?

  • Something's not working: See Apigee Support
  • Something's wrong with the docs: Click Send Feedback in the lower right.
    (Incorrect? Unclear? Broken link? Typo?)