Skip to content

Commit

Permalink
Merge pull request #40 from adjust/disable_SDK
Browse files Browse the repository at this point in the history
V3.2.0 Disable SDK
  • Loading branch information
nonelse committed Apr 7, 2014
2 parents 79c13a1 + eaa2175 commit 14b308e
Show file tree
Hide file tree
Showing 14 changed files with 198 additions and 20 deletions.
2 changes: 2 additions & 0 deletions Adjust/AIActivityHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
withParameters:(NSDictionary *)parameters;

- (void)finishedTrackingWithResponse:(AIResponseData *)response;
- (void)setEnabled:(BOOL)enabled;
- (BOOL)isEnabled;

@end

Expand Down
53 changes: 47 additions & 6 deletions Adjust/AIActivityHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ @interface AIActivityHandler()
@property (nonatomic, copy) NSString *userAgent;
@property (nonatomic, copy) NSString *clientSdk;
@property (nonatomic, assign) BOOL trackingEnabled;
@property (nonatomic, assign) BOOL internalEnabled;

@end

Expand Down Expand Up @@ -70,6 +71,7 @@ - (id)initWithAppToken:(NSString *)yourAppToken {
// default values
self.environment = @"unknown";
self.trackMacMd5 = YES;
self.internalEnabled = YES;

dispatch_async(self.internalQueue, ^{
[self initInternal:yourAppToken];
Expand Down Expand Up @@ -119,6 +121,26 @@ - (void)finishedTrackingWithResponse:(AIResponseData *)response {
}
}

- (void)setEnabled:(BOOL)enabled {
self.internalEnabled = enabled;
if ([self checkActivityState:self.activityState]) {
self.activityState.enabled = enabled;
}
if (enabled) {
[self trackSubsessionStart];
} else {
[self trackSubsessionEnd];
}
}

- (BOOL)isEnabled {
if ([self checkActivityState:self.activityState]) {
return self.activityState.enabled;
} else {
return self.internalEnabled;
}
}

#pragma mark - internal
- (void)initInternal:(NSString *)yourAppToken {
if (![self checkAppTokenNotNil:yourAppToken]) return;
Expand All @@ -144,6 +166,11 @@ - (void)initInternal:(NSString *)yourAppToken {
- (void)startInternal {
if (![self checkAppTokenNotNil:self.appToken]) return;

if (self.activityState != nil
&& !self.activityState.enabled) {
return;
}

[self.packageHandler resumeSending];
[self startTimer];

Expand All @@ -157,6 +184,7 @@ - (void)startInternal {

[self transferSessionPackage];
[self.activityState resetSessionAttributes:now];
self.activityState.enabled = self.internalEnabled;
[self writeActivityState];
[self.logger info:@"First session"];
return;
Expand Down Expand Up @@ -200,7 +228,8 @@ - (void)endInternal {

[self.packageHandler pauseSending];
[self stopTimer];
[self updateActivityState];
double now = [NSDate.date timeIntervalSince1970];
[self updateActivityState:now];
[self writeActivityState];
}

Expand All @@ -212,12 +241,16 @@ - (void)eventInternal:(NSString *)eventToken
if (![self checkEventTokenNotNil:eventToken]) return;
if (![self checkEventTokenLength:eventToken]) return;

if (!self.activityState.enabled) {
return;
}

AIPackageBuilder *eventBuilder = [[AIPackageBuilder alloc] init];
eventBuilder.eventToken = eventToken;
eventBuilder.callbackParameters = parameters;

double now = [NSDate.date timeIntervalSince1970];
[self updateActivityState];
[self updateActivityState:now];
self.activityState.createdAt = now;
self.activityState.eventCount++;

Expand Down Expand Up @@ -247,13 +280,17 @@ - (void)revenueInternal:(double)amount
if (![self checkEventTokenLength:eventToken]) return;
if (![self checkTransactionId:transactionId]) return;

if (!self.activityState.enabled) {
return;
}

AIPackageBuilder *revenueBuilder = [[AIPackageBuilder alloc] init];
revenueBuilder.amountInCents = amount;
revenueBuilder.eventToken = eventToken;
revenueBuilder.callbackParameters = parameters;

double now = [NSDate.date timeIntervalSince1970];
[self updateActivityState];
[self updateActivityState:now];
self.activityState.createdAt = now;
self.activityState.eventCount++;

Expand All @@ -275,10 +312,9 @@ - (void)revenueInternal:(double)amount
#pragma mark - private

// returns whether or not the activity state should be written
- (BOOL)updateActivityState {
- (BOOL)updateActivityState:(double)now {
if (![self checkActivityState:self.activityState]) return NO;

double now = [NSDate.date timeIntervalSince1970];
double lastInterval = now - self.activityState.lastActivity;
if (lastInterval < 0) {
[self.logger error:@"Time travel!"];
Expand Down Expand Up @@ -375,8 +411,13 @@ - (void)stopTimer {
}

- (void)timerFired {
if (self.activityState != nil
&& !self.activityState.enabled) {
return;
}
[self.packageHandler sendFirstPackage];
if ([self updateActivityState]) {
double now = [NSDate.date timeIntervalSince1970];
if ([self updateActivityState:now]) {
[self writeActivityState];
}
}
Expand Down
1 change: 1 addition & 0 deletions Adjust/AIActivityState.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

// persistent data
@property (nonatomic, copy) NSString *uuid;
@property (nonatomic, assign) BOOL enabled;

// global counters
@property (nonatomic, assign) int eventCount;
Expand Down
7 changes: 7 additions & 0 deletions Adjust/AIActivityState.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ - (id)init {
self.createdAt = -1;
self.lastInterval = -1;
self.transactionIds = [NSMutableArray arrayWithCapacity:kTransactionIdCount];
self.enabled = YES;

return self;
}
Expand Down Expand Up @@ -92,6 +93,7 @@ - (id)initWithCoder:(NSCoder *)decoder {
self.lastActivity = [decoder decodeDoubleForKey:@"lastActivity"];
self.uuid = [decoder decodeObjectForKey:@"uuid"];
self.transactionIds = [decoder decodeObjectForKey:@"transactionIds"];
self.enabled = [decoder decodeBoolForKey:@"enabled"];

// create UUID for migrating devices
if (self.uuid == nil) {
Expand All @@ -102,6 +104,10 @@ - (id)initWithCoder:(NSCoder *)decoder {
self.transactionIds = [NSMutableArray arrayWithCapacity:kTransactionIdCount];
}

if (![decoder containsValueForKey:@"enabled"]) {
self.enabled = YES;
}

self.lastInterval = -1;

return self;
Expand All @@ -117,6 +123,7 @@ - (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeDouble:self.lastActivity forKey:@"lastActivity"];
[encoder encodeObject:self.uuid forKey:@"uuid"];
[encoder encodeObject:self.transactionIds forKey:@"transactionIds"];
[encoder encodeBool:self.enabled forKey:@"enabled"];
}


Expand Down
15 changes: 2 additions & 13 deletions Adjust/AIPackageBuilder.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
#import "AIPackageBuilder.h"
#import "AIActivityPackage.h"
#import "NSData+AIAdditions.h"

static NSString * const kDateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'Z";
static NSDateFormatter * dateFormat;
#import "AIUtil.h"

#pragma mark -
@implementation AIPackageBuilder
Expand Down Expand Up @@ -129,8 +127,7 @@ - (void)parameters:(NSMutableDictionary *)parameters setInt:(int)value forKey:(N
- (void)parameters:(NSMutableDictionary *)parameters setDate:(double)value forKey:(NSString *)key {
if (value < 0) return;

NSDate *date = [NSDate dateWithTimeIntervalSince1970:value];
NSString *dateString = [self.dateFormat stringFromDate:date];
NSString *dateString = [AIUtil dateFormat:value];
[self parameters:parameters setString:dateString forKey:key];
}

Expand All @@ -149,13 +146,5 @@ - (void)parameters:(NSMutableDictionary *)parameters setDictionary:(NSDictionary
[self parameters:parameters setString:dictionaryString forKey:key];
}

- (NSDateFormatter *)dateFormat {
if (dateFormat == nil) {
dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:kDateFormat];
}
return dateFormat;
}

@end

6 changes: 6 additions & 0 deletions Adjust/AIRequestHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ - (NSData *)bodyForParameters:(NSDictionary *)parameters {
[pairs addObject:pair];
}

double now = [NSDate.date timeIntervalSince1970];
NSString *dateString = [AIUtil dateFormat:now];
NSString *escapedDate = [dateString aiUrlEncode];
NSString *sentAtPair = [NSString stringWithFormat:@"%@=%@", @"sent_at", escapedDate];
[pairs addObject:sentAtPair];

NSString *bodyString = [pairs componentsJoinedByString:@"&"];
NSData *body = [NSData dataWithBytes:bodyString.UTF8String length:bodyString.length];
return body;
Expand Down
1 change: 1 addition & 0 deletions Adjust/AIUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
+ (NSString *)userAgent;

+ (void)excludeFromBackup:(NSString *)filename;
+ (NSString *)dateFormat:(double)value;

@end
14 changes: 14 additions & 0 deletions Adjust/AIUtil.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
static NSString * const kBaseUrl = @"https://app.adjust.io";
static NSString * const kClientSdk = @"ios3.1.0";

static NSString * const kDateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'Z";
static NSDateFormatter * dateFormat;


#pragma mark -
@implementation AIUtil
Expand Down Expand Up @@ -110,4 +113,15 @@ + (void)excludeFromBackup:(NSString *)path {
}
}

+ (NSString *)dateFormat:(double) value {
if (dateFormat == nil) {
dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:kDateFormat];
}

NSDate *date = [NSDate dateWithTimeIntervalSince1970:value];

return [dateFormat stringFromDate:date];
}

@end
12 changes: 12 additions & 0 deletions Adjust/Adjust.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,18 @@ static NSString * const AIEnvironmentProduction = @"production";
*/
+ (void)trackSubsessionEnd;

/**
* Enable or disable the adjust SDK
*
* @param enabled The flag to enable or disable the adjust SDK
*/
+ (void)setEnabled:(BOOL)enabled;

/**
* Check if the SDK is enabled or disabled
*/
+ (BOOL)isEnabled;

@end


Expand Down
8 changes: 8 additions & 0 deletions Adjust/Adjust.m
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,12 @@ + (void)trackSubsessionEnd {
[activityHandler trackSubsessionEnd];
}

+ (void)setEnabled:(BOOL)enabled {
[activityHandler setEnabled:enabled];
}

+ (BOOL)isEnabled {
return [activityHandler isEnabled];
}

@end
7 changes: 7 additions & 0 deletions AdjustTests/AIActivityHandlerMock.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ - (void)finishedTrackingWithResponse:(AIResponseData *)response {
[self.loggerMock test:[prefix stringByAppendingFormat:@"finishedTrackingWithResponse response:%@", response]];
}

- (void)setEnabled:(BOOL)enabled {
[self.loggerMock test:[prefix stringByAppendingFormat:@"setEnabled enabled:%d", enabled]];
}

- (BOOL)isEnabled {
[self.loggerMock test:[prefix stringByAppendingFormat:@"isEnabled"]];
return YES;
}

@end
76 changes: 76 additions & 0 deletions AdjustTests/AIActivityHandlerTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -416,4 +416,80 @@ - (void)testChecks {

}

- (void)testDisable {
// reseting to make the test order independent
[self reset];

// starting from a clean slate
XCTAssert([AITestsUtil deleteFile:@"AdjustIoActivityState" logger:self.loggerMock], @"%@", self.loggerMock);

// create handler to start the session
id<AIActivityHandler> activityHandler = [AIAdjustFactory activityHandlerWithAppToken:@"123456789012"];

// verify the default value
XCTAssert([activityHandler isEnabled], @"%@", self.loggerMock);

[activityHandler setEnabled:NO];

// check that the value is changed
XCTAssertFalse([activityHandler isEnabled], @"%@", self.loggerMock);

[activityHandler trackEvent:@"123456" withParameters:nil];
[activityHandler trackRevenue:0.1 transactionId:nil forEvent:nil withParameters:nil];
[activityHandler trackSubsessionEnd];
[activityHandler trackSubsessionStart];

[NSThread sleepForTimeInterval:2];

// verify the changed value after the activity handler is started
XCTAssertFalse([activityHandler isEnabled], @"%@", self.loggerMock);

// making sure the first session was sent
XCTAssert([self.loggerMock containsMessage:AILogLevelInfo beginsWith:@"First session"], @"%@", self.loggerMock);

// delete the first session package from the log
XCTAssert([self.loggerMock containsMessage:AILogLevelTest beginsWith:@"AIPackageHandler sendFirstPackage"], @"%@", self.loggerMock);

// making sure the timer fired did not call the package handler
XCTAssertFalse([self.loggerMock containsMessage:AILogLevelTest beginsWith:@"AIPackageHandler sendFirstPackage"], @"%@", self.loggerMock);

// test if the event was not triggered
XCTAssertFalse([self.loggerMock containsMessage:AILogLevelDebug beginsWith:@"Event 1"], @"%@", self.loggerMock);

// test if the revenue was not triggered
XCTAssertFalse([self.loggerMock containsMessage:AILogLevelDebug beginsWith:@"Event 1 (revenue)"], @"%@", self.loggerMock);

// verify that the application was paused
XCTAssert([self.loggerMock containsMessage:AILogLevelTest beginsWith:@"AIPackageHandler pauseSending"], @"%@", self.loggerMock);

// verify that it was not resumed
XCTAssertFalse([self.loggerMock containsMessage:AILogLevelTest beginsWith:@"AIPackageHandler resumeSending"], @"%@", self.loggerMock);

// enable again
[activityHandler setEnabled:YES];

[activityHandler trackEvent:@"123456" withParameters:nil];
[activityHandler trackRevenue:0.1 transactionId:nil forEvent:nil withParameters:nil];
[activityHandler trackSubsessionEnd];
[activityHandler trackSubsessionStart];

[NSThread sleepForTimeInterval:2];

// verify the changed value, when the activity state is started
XCTAssert([activityHandler isEnabled], @"%@", self.loggerMock);

// test that the event was triggered
XCTAssert([self.loggerMock containsMessage:AILogLevelDebug beginsWith:@"Event 1"], @"%@", self.loggerMock);

// test that the revenue was triggered
XCTAssert([self.loggerMock containsMessage:AILogLevelDebug beginsWith:@"Event 2 (revenue)"], @"%@", self.loggerMock);

// verify that the application was paused
XCTAssert([self.loggerMock containsMessage:AILogLevelTest beginsWith:@"AIPackageHandler pauseSending"], @"%@", self.loggerMock);

// verify that it was also resumed
XCTAssert([self.loggerMock containsMessage:AILogLevelTest beginsWith:@"AIPackageHandler resumeSending"], @"%@", self.loggerMock);

}

@end
Loading

0 comments on commit 14b308e

Please sign in to comment.