IOS Stats Dot those things

Source: Internet
Author: User

1, statistical code buried so easy?

Statistics is a very important part of app development, the operation of the app, the effect of the revised, the user's various behaviors need to be targeted, there are a number of third-party libraries available for selection. Suppose the product has this requirement: when the user clicks the Buy button on the Details page, record the event. That's probably what we're going to achieve.

detailviewcontroller.m-(void) onbuybuttontapped: (UIButton *) button{//Do some stuff, maybe send a request to server [Xxxanalytics event:ksomeeventyoudefined];}

This requirement is easy to fix, but there are a lot of questions to think about:

    • There will be other buttons on the page, and you might want to put a piece of code on each button.

    • These statistics are actually not related to the specific business, there is no need to mix with the business code, not elegant.

    • When it comes to revision or refactoring, it's possible to forget to move the appropriate dot code over.

2, AOP implementation of business code and statistical Code decoupling

So a better way to do this is to use AOP (aspect-oriented-programming), which translates to "plane-oriented programming."

A technique for dynamically and uniformly adding functionality to a program without modifying the source code is implemented by pre-compiling and running-time dynamic proxies.

Simply put, you can dynamically insert a piece of code around a function call. IOS can use the aspects library developed by Pete Steinberger, which is based on the Swizzle method in the runtime layer.

Look at a little Demo.

[Uiviewcontroller aspect_hookselector: @selector (viewwillappear:) withoptions:aspectpositionafter usingBlock:^ (ID <AspectInfo> Aspectinfo, BOOL animated) {NSLog (@ "View Controller%@ would appear animated:%tu", Aspectinfo.insta NCE, animated);} Error:null];

So in the Uiviewcontroller of the viewwillappear: After being called, we will also adjust the block we defined, this log will be output. And that's exactly what happens when you're done doing something that's not business-related.

The above example, as we do with AOP, is probably the case.

detailviewcontroller.m-(void) onbuybuttontapped: (UIButton *) button{//Do some stuff, maybe send a request to server No need to call [Xxxanalytics event:]}//appdelegate.m-(void) setupanalytics{[Detailviewcontroller Aspect_hookS Elector: @selector (onbuybuttontapped:) withoptions:aspectpositionafter usingblock:^ (id<aspectinfo>    Aspectinfo, BOOL animated) {[Xxxanalytics event:ksomeeventyoudefined]; } Error:null];}

3. What about multiple Button events?

So the statistics code is stripped out of the business code. But there is a new problem, multiple button Event, is not to write a lot of lines such code, "Repeat" such things, as a programmer how to endure, simple, build a method

-(void) Trackeventwithclass: (Class) Klass selector: (SEL) Selector event: (NSString *) event{[Klass Aspect_hookselector:        @selector (selector) withoptions:aspectpositionafter usingblock:^ (id<aspectinfo> aspectinfo, BOOL animated) {    [Xxxanalytics event:event]; } Error:null];}

Use it like this.

-(void) setupanalytics{[self Trackeventwithclass:detailviewcontroller selector: @seletor (onbuybuttontapped:) Event:    Ksomeeventyoudefined]; [Self Trackeventwithclass:listviewcontroller selector: @seletor (followbuttontapped:) event:kanothereventyoudefined    ]; // ...}

4, statistical events have the choice of logic?

It looks clean again. At this point, the product manager also asked a demand: When this button click, if you have logged in, send Eventa, if not logged to send EVENTB, that is, no longer just [Xxxanalytics event:] So simple, but also need to add additional logic, it is difficult to pour us, Add a block.

-  (void) Trackeventwithclass: (Class) klass                    selector: (SEL) selector                eventhandler: (void  (^) (id<AspectInfo>  aspectinfo)) Eventhandler{    [klass aspect_hookselector: @selector (selector)  withoptions:aspectpositionafter usingblock:^ (id<aspectinfo> aspectinfo, bool  Animated)  {        if  (EventHandler)  {             eventhandler (Aspectinfo);         }    } error:null];}   Use [Self trackeventwithclass:detailviewcontroller selector: @seletor (onbuybuttontapped:)   eventhandler:^ (id<aspectinfo> aspectinfo) {&NBSP;&NBSP;&NBSP;&Nbsp;user.loggedin ? [xxxanalytics event:eventa] : [xxxanalytics event:eventb];}]; 

OK, now as long as it's not too complicated for the logic (those that need method context variables) we can handle, and then the product to accept the acceptance. Product moved a stool to sit around, then click Button, look at the Console, after several rounds of the ravages, the product also slowly accepted this way of acceptance. Then one day, suddenly found an item or a few data anomalies, and then found a development, glanced at: Oh, this method has been reconstructed. Or the new method forgot to add statistics. Only wait until the next version plus, if only the general statistics are good, and money related to the trouble.

5, how to avoid the statistical code is forgotten?

So is there an intuitive way to verify it? Of course, the programmer is omnipotent. An ideal situation is when a product opens the APP and a switch is turned on to see all the buttons that send the Event, like this

The numbers represent the EventID. How to achieve it? Remember when registering the event, we have passed in class and selector, generally we will have a baseviewcontroller, then you can in Baseviewcontroller viewdidappear: do some articles.

baseviewcontroller.m-(void) Viewdidappear: (BOOL) animated{[Super viewdidappear:animated];    Get the registered classes nsdictionary *registeredclasses = [Ouranalytics sharedinstance].registeredclasses; [Registeredclasses enumeratekeysandobjectsusingblock:^ (NSString *classname, Nsarray *selectors, BOOL *stop)        {if ([self iskindofclass:nsclassfromstring (className)]) {//How to find its host based on selector? }    }];}

So now the problem is left, how to find the corresponding button according to selector, here to note that some buttons may have to wait for the network request to complete before it appears, such as the Button in the Tableviewcell.

Did not think too convenient method, simple rough point is to set a Timer to sweep the subviews at intervals, if it is button or contain tapgesture, take their action contrast, if match can highlight that Button/vi EW.

EventID is also the same, before the registration also will pass a EventID come, here directly display can. For those who preach EventHandler.

So theoretically feasible, the performance will be slightly loss, especially when the structure of the subviews is more complex, but only for the internal validation, so this is not a problem.

6, how to solve the APP embedded code to issue the version of the problem?

It seems that the effect is good, is it possible to make the system more flexible? For example, can you make the rules from the backend? The client simply reads a configuration file, just like this

-(void) setupanalytics{//Analyticsrules is read from the configuration file [Analyticsrules enumerateobjectsusingblock:^ (Nsdictionary *ru        Les, Nsuinteger idx, BOOL *stop) {Class Klass = nsclassfromstring (rules[@ "Class"]);        SEL selector = nsselectorfromstring (rules[@ "selector"]);        NSString *eventid = rules[@ "EventID"];    [Self Trackeventwithclass:klass seletor:seletor event:eventid]; }];}

What if I fill in the wrong Class or Selector in the background? Fortunately there are objc_getclasslist and class_copymethodlist these two run-time methods, with them can be in the App to sweep through the registered classes (filter out the beginning of the Ui/ns), and then save their seletor also sent to the service Of course, this can only be done at the right time, such as when integrating packaging.

Now, the system is more complete. Of course, this is just some of my ideas, not tried in practice, so I will definitely step on all kinds of pits, but at least it seems to be a feasible solution.

7, Refer:

[1] IOS stats dot those things

Http://limboy.me/ios/2015/09/09/ios-analytics.html

IOS Stats Dot those things

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.