iOS Technical Reference


Requirements

The SDK was built with the Apple LLVM 4.x compiler for the iOS 4.2 deployment target and the following architectures: ARMv7, ARMv7S and i386. The SDK is supported on iPhone 3GS with iOS 4.2+ as well as all later devices and OS versions, including all iPad devices. The SDK is also supported on the iOS Simulator running on the i386 architecture.


SDK Architecture

The diagram below illustrates the high level architecture of the SDK.

ios_sdk_ architecture


Threading Model

The SDK methods are thread-safe so your application can call them on different threads. The SDK itself does not use threads and relies on asynchronous callbacks to perform some of its tasks.


Internal buffer capacity

One very important aspect of the SDK is how it behaves when the internal buffer capacity limit on number of events is reached. The current limit is 5,000 events. This limit approximately equates to a 1MB database, assuming 100 characters on average per event.

When the internal buffer capacity limit is reached, the SDK will purge or throw out a small number of the oldest events to make room for new events. This results in data loss but should only happen in extreme situations such as when events cannot be flushed to Medio due to prolonged lack of data connectivity or a misbehaving application logging too many events and disabling flushing.


Flushing events

By default, the SDK automatically flushes events to the Medio Data Collection Service (DCS). You can also flush events on demand by calling the flushEvents selector.

The SDK sends events to the Medio DCS over an HTTP Post request. Once the Medio DCS successfully acknowledges receipt of the events, the SDK removes the events from iOS Core Data. If the HTTP request fails for any reason, then the events are not removed. The SDK does not retry failed requests immediately. Events that are not sent to the Medio DCS successfully remain queued up (stored persistently) in the database to be sent on the next call to flushEvents. The SDK will ignore new calls to flushEvents if it is currently performing a flush.

Flushing events assumes that a data connection is available and relies on the iOS HTTP implementation to fail gracefully when a data connection is not available.

Flushing events and application behavior

The SDK’s automatic flush behavior may not meet every application’s requirements. For example, if you find Auto-Flush affecting critical application processing like game play, then you can disable automatic flushing temporarily during these critical processing points using the disableAutomaticFlushing: selector. Auto-Flush can be re-enabled again using the enableAutomaticFlushing: selector once the critical processing section is complete. Note your application can still flush events on demand using the flushEvents selector while automatic flushing is disabled or enabled.

In extreme cases, you may disable automatic flushing entirely for the life of your application. In this case, we recommend calling the flushEvents selector when you perform some other networking activity (if any). If your application does not have any networking activity, then we recommend calling flushEvents during pauses in user interaction. For example, in the case of a game, you may wish to flush events in a “Game Over” screen or a “Main Menu” screen.

If you choose to flush events on demand instead of or in addition to automatic flushing, your application should not call flushEvents too frequently to avoid compromising battery life. On the other hand, you also don’t want to take the risk of losing data by calling flushEvents too infrequently, a old events are purged to allow for new ones when the internal buffer capacity limit is reached.


Session management

The SDK manages sessions according to the rules in the following sequence. Refer to the diagram below to see each step in sequence.

  1. The first time your application calls openSession, the SDK will create a new session (labeled as Session_A in the diagram below).
  2. When your application calls closeSession, the SDK may expire the current session.
  3. If your application calls openSession within 10 seconds of the last call to closeSession, then the SDK will resume the previous session. This behavior means that the SDK will resume the previous session if the user accidentally exits your application and restarts it.
  4. Your application makes the final call to closeSession for Session_A.
  5. If your application calls openSession more than 10 seconds after the last call to closeSession, the SDK will create a new session (labeled as Session_B in the diagram below).



ios_sdk_sessions


Performance and resources

Effect on application size

The SDK only adds an additional 130KB to your application size once your integrate it. This does not include any additional instrumentation code or event logging code that you may add to your application.

Performance measurements

We collected the following performance measurements on an iPhone 4 running iOS 5.

openSession and closeSession

The average execution time of the openSession call is 50ms. The average execution time of the closeSession call (after adding 5,000 events) is 50ms.

Average time to persist an event

The average execution time of the logEvent call is 7ms based on logging 4,000 events (average size 58 characters including the event name and key-value pairs). Note that the execution time increases as the size of the event increases as shown in the chart below.

ios_sdk_logEvent_performance

When the database is full (when it contains 5,000 events), the average execution time of the logEvent call is 17ms based on logging an additional 4,000 events (average size 58 characters including the event name and key-value pairs). In this case, the call is slower because the SDK has to delete older events periodically to make sure that there is enough room for newer events.

CPU utilization

Our stress tests logged 10 events per second with auto-flush enabled and on-demand flushing of events to the Medio DCS done after every 500 events logged. Each event in the test was comprised of the data shown below, equating to an average of 58 characters.

  • Event name: select_next
  • Key-value pair 1: page = stop_page_x
  • Key-value pair 2: select_next = redirect_id_value_x



The blue horizontal line in the chart below shows the average CPU utilization (approximately 8%) of the SDK during these tests.

ios_sdk_cpu_utilization

RAM consumption

We measure RAM usage using Xcode Instruments. A demo application without an SDK session being opened consumed 6.41 MB of real memory. The same application with an SDK session open consumed 6.45 MB.

We have also estimated that a typical logEvent call consumes approximately 140 KB of RAM, so in our demo application, memory consumption goes up to 6.55 MB. However, since we create our own short-living auto-release pool when required, and don’t use the main auto-release pool, this memory is reclaimed immediately.

The chart below illustrates the SDK’s memory utilization for a scenario when we log 1000 events with an on-demand flush done at the end. The memory spike that you see on the right of the chart is when memory consumption goes up because of the flush events process. Here memory consumption temporarily increases by 1.5 MB to process 1000 events.

ios_sdk_ram_consumption

Internal buffer size

We calculated the average size of a single event in the SDK internal buffer and found the following:

  • 25 characters in an Event occupies approximately 110 bytes.
  • 50 characters in an Event occupies approximately 143 bytes.
  • 100 characters in an Event occupies approximately 211 bytes.
  • 150 characters in an Event occupies approximately 281 bytes.
  • 200 characters in an Event occupies approximately 349 bytes.