WARNING
This page supports the iOS agent prior to version 4.0. If you are still using this version, please upgrade as soon as possible. This version is no longer updated.
Introduction
The embedded agent is a bridge between your mobile application and the App47 service. It provides an easy to use API for recording session times and durations, log messages and performance events. Once you've added your iOS App to the App47 Dashboard, be sure to record the App ID as it will be used to configure the agent after installation.
iOS Agent Version 2
Download the iOS Embedded Agent, install and configure it in your iOS mobile App.
Note: If you are using a version prior to 2.0, please consult the legacy page for additional information. Please upgrade at your earliest convenience to the latest iOS agent.
Required steps:
-
Download the embedded agent
-
Include the agent library in your project
-
Configure the embedded agent
Optional steps:
-
Add EmbeddedAgentSettings.plist file to set additional configuration parameters
- Sending Cached Data
-
Add Crash Log Management
-
Add logging statements to capture both debug and error conditions
-
Adding timed events to your App (to capture performance data)
-
Adding generic events to your App (to capture user behavior)
-
Using configuration groups
All of the above steps are explained in the corresponding subsections below.
Embedded Agent Performance
The goal of the embedded agent is to provide a valuable management capability to your App without getting in the way of the App it is managing. Although nothing is free, we did try to limit the amount of resources we consume during the execution. Three key points were measure and the results are listed below.
Metric | Description | Measurement |
---|---|---|
Delay on startup | The time it takes for the agent to startup and return control back to the main thread. All remaining operations are done in background threads. | Average delay in seconds: iPhone 3g - 0.052, iPhone 4 - 0.017, iPad 2 - 0.026 |
Memory | The amount additional memory the agent consumes at a steady state. | 116KB |
Network traffic | Although the specific amount of network traffic depends on how you use the service, most packets sent to the service are less than 2KB. | Less than 2KB |
Library file size | The net increase in your App’s image size as a result of including the embedded agent. | 1.3MB |
The Required Steps -- Explained
1. Download the embedded agent
- Download the embedded agent compressed disk image (DMG file) from: App47 Resource center
- Once you have downloaded the file, open the DMG file and you should see the following files:
File descriptions
File | Description | Required? |
---|---|---|
EmbeddedAgent.h | Header file for the embedded agent | Yes |
EmbeddedAgentSettings.plist | Additional settings for configuring the embedded agent. | No |
GoogleToolbox | Required files from Google Toolbox open source project to support capturing crash logs. | Yes if the UncaughExceptionHandler is used and GoogleToolbox is not already included in the project. |
JSON | (Required for agent versions lower than 1.9) SBJSON library used for messaging to the service. | Yes if the SBJSON library is not already included in your project. |
libEmbeddedAgent.a | Compiled fat (i386, armv6, armv7, armv7s) library of the embedded agent. This library uses a UUID generator to create a unique identifier for each app instance, use this if deploying through the iTunes App Store. | Yes if you want geo location information sent by the embedded agent. The CoreLocation.framework must be linked included in your project. |
libEmbeddedAgentWithNo CoreLocation.a | Compiled fat (i386, armv6, armv7, armv7s) library of the embedded agent with no CoreLocation.Framework. This library uses a UUID generator to create a unique identifier for each app instance, use this if deploying through the iTunes App Store. | Yes if you do not need geo location information. |
libGMStackStrace.a | Compiled fat (i386, armv6, armv7, armv7s) library of the Google Stack Trace Toolkit, include this library if you are working in an ARC configured project. | Yes only if you are working in an ARC configured project and do not already have the google toolkit included. |
2. Include the embedded agent library in your project
- Create a folder in your project and copy the contents of the DMG file to the newly created folder
- Add these files to your project by right clicking on the project, or on a folder of your choosing.
Note: copy either the libEmbeddedAgent.a or libEmbeddedAgentWithNoCoreLocation.a to this directory.
- Select the App47 directory and click Add.
Note: If you already use either the SBJSON or GoogleToolbox library in your application, do not include these directories.
File Check List
There are several ways to include App47 into you iOS app, please make sure that you have selected only one option in each group below.
App47 Library
Select one of the libEmbeddedAgent libraries only, selecting more than one will cause compilation errors.
-
libEmbeddedAgent.a - Use this if you are going through iTunes and want GEO data.
-
libEmbeddedAgentWithNoCoreLocation.a - Use this if you are going through iTunes and do NOT want GEO data.
Google Toolbox Library
Include either the GoogleToolbox directory OR the libGMStackTrace.a file, but not both.
If you have an ARC project and using the GoogleToolbox directory, make sure you exclude the files form the ARC compiler, please read this article on how to do exclude them.
If you are using the libGMStackTrace.a file, please include the -all_load flag in the linker flag.
3. Configure the embedded agent
The simplest way to configure the embedded agent is to include the “EmbeddedAgent.h” file and use the configureAgentWithAppID: selector with the App ID obtained from the App47 Dashboard. This configuration will record session start, duration, location and capture relevant device and App information.
#import "MyAppAppDelegate.h" #import "MyAppViewController.h" #import "EmbeddedAgent.h" @implementation MyAppAppDelegate @synthesize window=_window; @synthesize viewController=_viewController; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. [EmbeddedAgent configureAgentWithAppID:@"4d556ab4530a69fb4b000002"]; self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; return YES; }
The Optional Steps -- Explained
Add EmbeddedAgentSettings.plist file to set additional configuration parameters
The agent can also be configured with the included EmbeddedAgentSettings.plist file that includes the App ID as well as additional parameters for the embedded agent.
Configuration parameters
Name | Type | Description | Default | Required? |
---|---|---|---|---|
application id | String | The App ID provided in your dashboard. | None | Yes |
configuration update frequency | Number | The amount of time in days the agent should update it’s configuration with the service. A value of 0.5 will cause the agent to update its configuration once every 12 hours. | 1 | No |
delay data upload interval | Number | The number of seconds to wait after startup before sending data to the service. This allows your App to startup and be responsive without competing for valuable cpu and network resources. | 1 | No |
send actual device identifier | Boolean | No longer used, please remove from your plist file. | NO | No |
show network activity | Boolean | If the network indicator in the status bar should be turned on when sending data to the service. If this value is set to YES, the network activity indicator is turned on and off when sending data, otherwise the indicator is not updated when sending data. | YES | No |
configuration endpoint | String | The fully qualified url for the configuration end point for the API service. | App47 production api server | No |
agent logging level | String | Logging level for the agent. It will only log information when running in a simulator, not on a device. Valid values are “debug”, “info”, “warn”, “error”. | error | No |
send events immediately | Boolean | If generic and timed events should be sent immediately, or batched together and sent at the start of the next session like log and session data. | YES | No |
upload on exit | Boolean | Attempt to upload session, log, and any remaining event data on exit. Requires iOS 4.0. When the application is put into the background, the agent will attempt to upload it's data to the server using the iOS backgrounding task. | No | No |
capture crashes | Boolean | Deprecated (see capture crash format option): Configuration option to capture crash logs via the agent, used instead of InstallExceptionHandlers, do not use both methods. | No | No |
capture crash format | String | Configure the agent to capture crash using either the “GTM” or “symbolicate” method. | Don't capture crash logs | No |
When using the EmbeddedAgentSettings.plist, the following configuration selector must be used.
#import "MyAppAppDelegate.h" #import "MyAppViewController.h" #import "EmbeddedAgent.h" @implementation MyAppAppDelegate @synthesize window=_window; @synthesize viewController=_viewController; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. [EmbeddedAgent configureAgent]; self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; return YES; }
Sending Cached Data
The Embedded Agent can be configured to send data at the beginning of session, or at the end. However if you want to force the sending of any cached data, use the following command anywhere in your mobile app.
[EmbeddedAgent sendCachedData];
Add Crash Log Management
There are three ways to capture crash log information for your iOS application, please choose one of the methods below, do not implement multiple methods within the sam application.
Manual capture
If you want crash log information captured and send to the App47 service, add the following “handleUncaughException” handler to your application delegate. This will capture any crash log information locally. The crash log information will then be uploaded the next time application is started. This will use the Google Toolkit Method of capturing crash logs.
void handleUncaughtException(NSException *exception) { EALogCrashException(exception, @"Application Crashed"); } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. [EmbeddedAgent configureAgent]; NSSetUncaughtExceptionHandler(&handleUncaughtException); self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; return YES; }
GTM capture
To capture all crash exceptions, use the InstallExceptionHandlers method to register default handlers for uncaught exceptions and signal handlers. This is the same as setting “GTM” as the “capture crash format” in the EmbeddedAgentSettings.plist file.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. [EmbeddedAgent configureAgent]; [EmbeddedAgent InstallExceptionHandlers]; self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; return YES; }
Symbolicate Capture
To capture the crash log in the iOS crash log format, and have it symbolicated by the service. Configure the EmbeddedAgentSettings.plist file with the setting “capture crash format” ⇒ “symbolicate”.
This will use the PL Crash Reporter Library to capture the crash locally on the device. The crash log will be uploaded to the server the next time the application is started. It does not prompt the user to upload the crash log.
If your crash log is not fully symbolicated, please see our iOS symbolication trouble shooting guide.
Adding logging statements to your App (to capture both debug and error conditions)
Additional level logging can be added to your App to capture debug, info, warn, error and crash log information. Log information is recorded locally and then uploaded to the service the next time the application resumes the active state or is started. Examples of logging statements:
// // MyAppViewController.m // MyApp // // #import "MyAppViewController.h" #import "EmbeddedAgent.h" @implementation MyAppViewController - (void)dealloc { [super dealloc]; } - (void)didReceiveMemoryWarning { // Warn level log statement EALogWarn(@"Received memory warning"); // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } #pragma mark - View lifecycle // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad { // List of tags can be added to log statements for additional // search criteria in the web app. EALogInfoWithTags([NSArray arrayWithObject:@"MyTag"], @"View is being loaded"); [super viewDidLoad]; } - (void)viewDidUnload { [super viewDidUnload===== Level 2 Headline ===== ]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // All log macros allow for standard string format replacements // found in NSLog and stringWithFormat EALogDebug(@"View is being asked to rotate to interface orientation %d", interfaceOrientation); // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } @end
Adding timed events to your App (to capture performance data)
Timed events allow you to measure and record events in your application along with the duration of the event. Timed events are sent to the service immediately upon completion. If the agent is unable to send the event immediately, it is cached locally and then sent at the next App startup or activation. However, Timed Events are not written to disk. So if an application crashes, or is stopped, all cached time events are removed. A simple example of using timed events in your application would look like the following code:
- (void) performMyTransaction{ NSString *eventID = [EmbeddedAgent startTimedEvent:@"Transaction"]; // Perform some business logic to complete the transaction // … // [EmbeddedAgent endTimedEvent:eventID]; }
Timed events can be cleared before sending to the service using the clearTimedEvent: method or clear all events using the clearTimedEventsOlderThanTimeInterval: method.
- (void) performMyTransaction{ BOOL successful = NO; NSString *eventID = [EmbeddedAgent startTimedEvent:@"Transaction"]; // Perform some business logic to complete the transaction // … // if (successful) [EmbeddedAgent endTimedEvent:eventID]; else [EmbeddedAgent clearTimedEvent:eventID]; }
… OR …
- (void) clearAllTimedEvents { [EmbeddedAgent clearTimedEventsOlderThanTimeInterval:0]; }
Adding generic events to your App (to capture user behavior)
Generic Events are like Timed Events, but with no duration. Generic Events are sent to the service immediately upon request. If the agent is unable to send the event immediately, it is cached locally and then sent at the next App startup or activation. A simple example of using Generic Events in your application would look like the following code:
- (void) handleMyEvent{ [EmbeddedAgent sendGenericEvent:@"myEventName"]; // Perform some business logic to handle the event // … // }
Using Configuration Groups in your App
Configuration Groups allows you to set a collection of key value pairs through the main web interface that are then downloaded by the agent at initial startup, and then subsequently at a frequency set by the “configuration update frequency” parameter in the EmbeddedAgentSettings.plist file. Configuration items must be requested by group name and key name. A default value may be given to be used in the event that the configuration group does not contain an item with the requested key name. If a default value is not given, and the key does not exist in the group, the value nil is returned. Configuration groups can be assigned to agents based on app version, os version and platform.
A simple example of using Configuration Groups in your application would look like the following code:
(void) myMethod{ NSString *serverURLString = [EmbeddedAgent configurationStringForKey:@"server url" group:@”Server Info” defaultValue:@”http://myserver.abc.com/restapi”]; // Use the serverURLString to perform additional work... // … // }
Receiving Configuration Group Notifications
The Embedded Agent will send notifications using NSNotificationCenter when new configuration settings are received from the service. The following messages are sent when the configuration change are received.
Name | Description |
---|---|
EmbeddedAgentAppConfigurationGroupDidInsert | A configuration group was added. The name of the group is included in the userInfo notification object with the key: EmbeddedAgentAppConfigurationGroupNameKey. |
EmbeddedAgentAppConfigurationGroupDidUpdate | A configuration group was updated. The name of the group is included in the userInfo notification object with the key: EmbeddedAgentAppConfigurationGroupNameKey. |
EmbeddedAgentAppConfigurationGroupDidDelete | A configuration group was deleted. The name of the group is included in the userInfo notification object with the key: EmbeddedAgentAppConfigurationGroupNameKey. |
EmbeddedAgentAppConfigurationGroupNameKey | A configuration group was changed, either added, updated or deleted. |
(void) updateViewFromConfigurationChange:(NSNotification *) notification{ NSDictionary *userInfo = [notification userInfo]; NSString *groupName = [[userInfo valueForKey:EmbeddedAgentAppConfigurationGroupNameKey]]; // // Update view based on groupName // ... } (void) viewDidLoad{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateViewFromConfigurationChange:) name:EmbeddedAgentAppConfigurationGroupDidUpdate object:nil]; [super viewDidLoad]; }
The Embedded Agent can be configured to send data at the beginning of session, or at the end. However if you want to force the sending of any cached data, use the following command anywhere in your mobile app.
[EmbeddedAgent sendCachedData];
Releases
2.4.1
-
Fixed bug MAM-128 to remove white spaces from the EmbeddedAgentSettings.plist file before using any values.
2.4
-
Added iOS crash log symbolication capability
2.3
-
Fixed bug when the agent was reporting app version number. Please upgrade as soon as possible if you are using 2.1 or 2.2.
2.0
-
Changed the way devices are unique identified to comply with Apple APIs, now the same library works for both Enterprise and B2C customers without any issues.
Comments
0 comments
Please sign in to leave a comment.