Skip to content

Instantly share code, notes, and snippets.

@vikingosegundo
Created May 12, 2015 19:30
Show Gist options
  • Save vikingosegundo/0e4b30901b9498ae4b7b to your computer and use it in GitHub Desktop.
Save vikingosegundo/0e4b30901b9498ae4b7b to your computer and use it in GitHub Desktop.
AB Testing Prototype
A prototype to show how AOP might be used to changes attributes on the fly as seen in certain A/B-Testing SDKs
1. create objective-c based project in Xcode
2. add Podfile
3. run 'pod install'
4. open workspace
5. add sourcefiles
//
// ABController.h
// ABTestPrototype
//
// Created by Manuel Meyer on 12.05.15.
// Copyright (c) 2015 Manuel Meyer. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ABController : NSObject
@end
//
// ABController.m
// ABTestPrototype
//
// Created by Manuel Meyer on 12.05.15.
// Copyright (c) 2015 Manuel Meyer. All rights reserved.
//
#import "ABController.h"
#import <Aspects/Aspects.h>
#import <objc/runtime.h>
#import "UIViewController+Updating.h"
@import UIKit;
@implementation ABController
void _ab_register_ab_notificaction(id self, SEL _cmd)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:NSSelectorFromString(@"ab_notifaction") name:@"ABTestUpdate" object:nil];
}
void _ab_notificaction(id self, SEL _cmd)
{
NSLog(@"UPDATE %@", self);
}
+(void)load
{
class_addMethod([UIViewController class], NSSelectorFromString(@"ab_notifaction"), (IMP)_ab_notificaction, "v@:");
class_addMethod([UIViewController class], NSSelectorFromString(@"ab_register_notifaction"), (IMP)_ab_register_ab_notificaction, "v@:");
[UIViewController aspect_hookSelector:@selector(viewDidLoad)
withOptions:AspectPositionAfter
usingBlock:^(id<AspectInfo> aspectInfo) {
UIViewController *vc = aspectInfo.instance;
SEL selector = NSSelectorFromString(@"ab_register_notifaction");
IMP imp = [vc methodForSelector:selector];
void (*func)(id, SEL) = (void *)imp;
func(vc, selector);
} error:NULL];
[UIViewController aspect_hookSelector:NSSelectorFromString(@"ab_notifaction")
withOptions:AspectPositionAfter
usingBlock:^(id<AspectInfo> aspectInfo) {
UIViewController *vc = aspectInfo.instance;
[vc updateViewWithAttributes:@{@"backgroundColor": [UIColor orangeColor]}];
} error:NULL];
[UIViewController aspect_hookSelector:@selector(viewWillAppear:)
withOptions:AspectPositionAfter
usingBlock:^(id<AspectInfo> aspectInfo) {
UIViewController *vc = aspectInfo.instance;
[vc updateViewWithAttributes:@{@"backgroundColor": [UIColor blueColor]}];
} error:NULL];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"ABTestUpdate" object:nil];
});
}
@end
platform :ios, '8.0'
pod 'Aspects', '~> 1.4.1'
//
// UIViewController+Updating.h
// ABTestPrototype
//
// Created by Manuel Meyer on 12.05.15.
// Copyright (c) 2015 Manuel Meyer. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIViewController (Updating)
-(void)updateViewWithAttributes:(NSDictionary *)attributes;
@end
//
// UIViewController+Updating.m
// ABTestPrototype
//
// Created by Manuel Meyer on 12.05.15.
// Copyright (c) 2015 Manuel Meyer. All rights reserved.
//
#import "UIViewController+Updating.h"
@implementation UIViewController (Updating)
-(void)updateViewWithAttributes:(NSDictionary *)attributes
{
[[attributes allKeys] enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL *stop) {
if ([obj isEqualToString:@"backgroundColor"]) {
[self.view setBackgroundColor:attributes[obj]];
}
}];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment