The overall design and implementation of iOS data without SDK

IOS no buried point data SDK practice of
iOS no buried point SDK RN page data collection

This article is the third article about the iOS buried point data collection SDK series, two articles before are just about one aspect of the content, this article will introduce SDK the overall design and the function of each module and the realization of ideas.

Overall design of SDK

First look at the overall design of a SDK map:

The overall design and implementation of iOS data without SDK

Seen from the above figure, SDK overall includes 4 parts: AOP, Event Collector, Event Cache, Event Upload. Among them, each part is a relatively independent function module, and the modules communicate with each other in the same way.

The main functions of the 4 modules in SDK are as follows:

  • AOP: the time required to provide data collection, that is, through the Method Swizzling to the corresponding hook class method, and then provide the way to Post Notification.
  • Event Collector: listen to the notification, perform the appropriate data collection for the current event, and submit the collected event data to the cache module.
  • Event Cache: responsible for the event data cache, serialization and read operations, including memory caching and disk cache.
  • Event Upload: report on the collected event data based on a reporting policy.

Then the specific implementation details of the 4 modules are introduced one by one.

AOP

The main function of this module is to provide the opportunity for SDK to perform data collection, and can be subdivided into 2 aspects:

  1. Implementation of AOP programming
  2. Hook class method

Implementation of AOP programming

In iOS to achieve AOP programming technology is based on the characteristics of Objective-C Runtime Method Swizzling. In Github, there has been a very good implementation of the AOP open source library -Aspects, which is also the realization of the use of Objective-C message forwarding mechanism and Method Swizzling black magic.

However, SDK did not use the Aspects library, although the Aspects package is very good and easy to use, but it can not fully meet the needs of the project, mainly in the following 2 aspects:

  1. Aspects cannot have a method that does not exist in the hook class, or an implementation that is not implemented.
  2. Aspects does not support class methods of the hook class.

As a result, SDK implements and encapsulates a class that is used to perform hook, which is also an extension of NSObject, similar to Aspects.

Hook method

In the first part of the article briefly mentioned, SDK in the realization of the basic event data collected automatically, the main hook method is divided into 3 categories:

  • Method of system class
  • Delegate method for system class
  • Custom class method

So, then on the detailed introduction, SDK in the event of the collection, the specific hook what kind of methods.

Interception of various types of events

For SDK, it is a very important part to collect all the user’s click behavior data. In addition, this part of the data for user behavior analysis and statistical path conversion rate, are critical.

So SDK for the user to collect various types of events, the main hook following some of the system class methods:

The overall design and implementation of iOS data without SDK

For the above, do some brief explanation:

  1. All types of UIControl controls, UITabBarButton and add custom in the navigation bar on the UIBarButtonItem click event, can be intercepted by the method of sendAction:to:from:forEvent: hook system UIApplication. However, this method does not intercept the navigation bar system automatically add back button click, so SDK and hook navigationBar:shouldPopItem: UINavigationController method to achieve the click to intercept.
  2. According to the related events and gesture, SDK initWithTarget:action: and addTarget:action: hook based system UIGestureRecognizer of the 2 methods to get the target object and the action method, action method and then go to hook target, which can intercept gesture related events.
  3. For UITableView, UICollectionView for a click, setDelegate: method, hook, to get the delegate object, the didSelectRowAtIndexPath: method can then go to the hook delegate.
  4. Click on the RN page, through the hook RN framework in the RCTUIManager class setJSResponder:blockNativeResponder: method, the specific reasons you can see this article in detail. In addition, in order to avoid the dependence of SDK RN framework, via NSClassFromString (@ RCTUIManager) to determine the current main project is the use of the RN framework, if no access to this, hook is not executed operation.
  5. Click on the system pop-up click, you need to intercept the UIAlertView, UIActionSheet and iOS8 on the new UIAlertController 3 pop click. For the first 2, only need hook their delegate method. As for the UIAlertController is not provided by the corresponding delegate method, here can be used by the hook class actionWithTitle:style:handler: class UIAlertAction method to intercept its click event.
Page event interception

For the collection of page events, mainly through the hook system class UIViewController life cycle approach to achieve specific look at the following figure:

The overall design and implementation of iOS data without SDK
Sliding event & UIWebView loading event

For iOS in the event of sliding, UIWebView loading event collection, SDK main hook method and UIScrollViewDelegate, UIWebViewDelegate in the method of setDelegate. Its principle is similar to that of UITableView. See below for details:

The overall design and implementation of iOS data without SDK

Event Collector

SDK can be got through the AOP layer executes the event data collection time, next is the implementation of real data collection, including the click event collection, event collection, sliding event collection.

These events to collect data contains some basic information, such as: eventName, appKey, eventTime, sessionId, deviceId, etc.. In addition, there are some specific events, such as the view click event, also need to collect relevant information and view; for the list for click, click on the indexPath for collecting information is needed; and for webView loading events need to collect the URL and error information.

Then the main focus on the SDK click event collection.

First of all, for the UIControl control with the addition of UITapGestureRecognizer view, in the collection of their click event data, the focus of the collection of 2 parts: pageName, viewInfo. Among them, pageName is that click event in which page, usually expressed by viewController class name; viewInfo refers to the relevant information, click on the view: viewClass, viewPath, frame, title and viewId (if any). The viewPath is the most critical information that can uniquely identify the current view.

Secondly, the navigation bar on the click of the event collection, and the information to be collected is almost the same, but in the collection of pageName data is not the same. The default pageName for the navigation bar’s click event is UINavigationController, but in order to better analyze the user behavior, the App is currently showing the page as its pageName.

Similarly, when you click on the pop-up system events, App will also be displayed as the page pageName. In addition, because there may be multiple popups with a page, button text information they may have, for example, often with “OK”, “Cancel” the words, then simply rely on the button title can not distinguish between these different pop, in order to solve this problem, and also joined the system popups the Title (title, message).

Finally, talk about the SDK in viewPath to achieve the logic, as shown in the following figure:

The overall design and implementation of iOS data without SDK

Event Cache

This module is mainly responsible for the access and serialization of all event data, which can be divided into the following 3 parts:

  1. The data is stored in memory by using double buffer structure. The specific implementation, will add new events to the global data stored in the array eventArray, etc. to meet the data reporting conditions, read a portion of the data and randomly generate a unique eventsID from eventArray, which is in the form of key-value stored in the global dictionary popedEventDict, etc. this part of the data uploaded successfully after eventsID the corresponding items removed from popedEventDict.
  2. In some cases (App is about to be killed, the program throws an exception), the memory of the data stored in the form of a file to the disk in order to prevent data loss.
  3. The protobuf serialization operation is performed by reading data from memory or file for subsequent data upload operation.

In addition, in order to ensure the multi thread security of data access, all of the above operations are executed in the same serial queue.

Event Upload

The main function of this module is to report all the data that has been collected according to a certain data reporting strategy. The data report mainly includes the 2 parts of the memory data and the local file. The following are the strategies and the realization of the report.

Real time reporting of memory data

First, there are 2 reporting strategies for memory data:

  1. Every 30 seconds
  2. Each cumulative 10 data.

When the above conditions are met, the data is read from the memory and the upload operation is performed. For the memory data upload, created a separate queue, and limit the maximum number of concurrent 10, in case of frequent data due to the number of threads caused by the open too much.

Local file data upload

In order to upload the local file as soon as possible, in order to prevent the user from unloading App caused by the loss of local data, for the local file upload strategy has the following 3:

  1. App cold start
  2. App into the foreground
  3. App into the background

Here to create a separate serial queue, to achieve the local file upload one by one, that is, after the success of a file upload, and then trigger the next file upload. Therefore, the above 3 trigger time does not cause the file to repeat the upload, and to complete the local file upload at a lower cost.

The process of data access and uploading

In fact, the above has talked about the realization of the general idea, which is designed to use the GCD queue to control the data upload and ensure multi-threaded security. In order to more clearly show the realization of the logic of these 2 parts, a simple draw a flow chart to show:

The overall design and implementation of iOS data without SDK

END

This article mainly introduces the overall design of embedded data without SDK, and the function of each module and the realization of ideas, which focuses on the specific implementation method of event collection required hook, implementation process and access data and reporting function. If you have any questions, please leave a comment.