Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Adjust.podspec
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Pod::Spec.new do |s|
s.name = "Adjust"
s.version = "3.3.5"
s.version = "3.4.0"
s.summary = "This is the iOS SDK of adjust. You can read more about it at http://adjust.com."
s.homepage = "http://adjust.com"
s.license = { :type => 'MIT', :file => 'MIT-LICENSE' }
s.author = { "Christian Wellenbrock" => "welle@adjust.com" }
s.source = { :git => "https://github.com/adjust/ios_sdk.git", :tag => "v3.3.5" }
s.source = { :git => "https://github.com/adjust/ios_sdk.git", :tag => "v3.4.0" }
s.platform = :ios, '4.3'
s.framework = 'SystemConfiguration'
s.weak_framework = 'AdSupport', 'iAd'
Expand Down
3 changes: 2 additions & 1 deletion Adjust/AIActivityHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
@property (nonatomic, assign) BOOL bufferEvents;
@property (nonatomic, assign) BOOL trackMacMd5;
@property (nonatomic, assign) NSObject<AdjustDelegate> *delegate;
@property (nonatomic, assign) BOOL isIad;

- (id)initWithAppToken:(NSString *)appToken;
- (void)setSdkPrefix:(NSString *)sdkPrefix;
Expand All @@ -29,7 +30,7 @@
forEvent:(NSString *)eventToken
withParameters:(NSDictionary *)parameters;

- (void)finishedTrackingWithResponse:(AIResponseData *)response;
- (void)finishedTrackingWithResponse:(AIResponseData *)response deepLink:(NSString *)deepLink;
- (void)setEnabled:(BOOL)enabled;
- (BOOL)isEnabled;
- (void)readOpenUrl:(NSURL*)url;
Expand Down
47 changes: 32 additions & 15 deletions Adjust/AIActivityHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@
#import "UIDevice+AIAdditions.h"
#import "NSString+AIAdditions.h"
#import "AIAdjustFactory.h"
#if !ADJUST_NO_IDA
#import <iAd/iAd.h>
#endif

static NSString * const kActivityStateFilename = @"AdjustIoActivityState";
static NSString * const kAdjustPrefix = @"adjust_";
Expand Down Expand Up @@ -47,7 +44,6 @@ @interface AIActivityHandler()
@property (nonatomic, copy) NSString *clientSdk;
@property (nonatomic, assign) BOOL trackingEnabled;
@property (nonatomic, assign) BOOL internalEnabled;
@property (nonatomic, assign) BOOL isIad;
@property (nonatomic, copy) NSString *vendorId;
@property (nonatomic, copy) NSString *pushToken;

Expand All @@ -61,6 +57,7 @@ @implementation AIActivityHandler
@synthesize bufferEvents;
@synthesize trackMacMd5;
@synthesize delegate;
@synthesize isIad;

+ (id<AIActivityHandler>)handlerWithAppToken:(NSString *)appToken {
return [[AIActivityHandler alloc] initWithAppToken:appToken];
Expand Down Expand Up @@ -121,11 +118,37 @@ - (void)trackRevenue:(double)amount
});
}

- (void)finishedTrackingWithResponse:(AIResponseData *)response {
if ([self.delegate respondsToSelector:@selector(adjustFinishedTrackingWithResponse:)]) {
[self.delegate performSelectorOnMainThread:@selector(adjustFinishedTrackingWithResponse:)
withObject:response waitUntilDone:NO];
- (void)finishedTrackingWithResponse:(AIResponseData *)response deepLink:(NSString *)deepLink{
[self runDelegate:response];
[self launchDeepLink:deepLink];
}

- (void)runDelegate:(AIResponseData *)response {
if (![self.delegate respondsToSelector:@selector(adjustFinishedTrackingWithResponse:)]) {
return;
}
if (response == nil) {
return;
}
[self.delegate performSelectorOnMainThread:@selector(adjustFinishedTrackingWithResponse:)
withObject:response waitUntilDone:NO];

}

- (void)launchDeepLink:(NSString *) deepLink{
if (deepLink == nil) return;

NSURL* deepLinkUrl = [NSURL URLWithString:deepLink];

if (![[UIApplication sharedApplication]
canOpenURL:deepLinkUrl]) {
[self.logger error:@"Unable to open deep link (%@)", deepLink];
return;
}

[self.logger info:@"Open deep link (%@)", deepLink];

[[UIApplication sharedApplication] openURL:deepLinkUrl];
}

- (void)setEnabled:(BOOL)enabled {
Expand Down Expand Up @@ -177,13 +200,7 @@ - (void)initInternal:(NSString *)yourAppToken {
self.userAgent = AIUtil.userAgent;
self.vendorId = UIDevice.currentDevice.aiVendorId;

#if !ADJUST_NO_IDA
if (NSClassFromString(@"ADClient")) {
[ADClient.sharedClient determineAppInstallationAttributionWithCompletionHandler:^(BOOL appInstallationWasAttributedToiAd) {
self.isIad = appInstallationWasAttributedToiAd;
}];
}
#endif
[[UIDevice currentDevice] aiSetIad:self];

self.packageHandler = [AIAdjustFactory packageHandlerForActivityHandler:self];
[self readActivityState];
Expand Down
3 changes: 2 additions & 1 deletion Adjust/AIAdditions/UIDevice+AIAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "AIActivityHandler.h"

@interface UIDevice(AIAdditions)

Expand All @@ -18,5 +19,5 @@
- (NSString *)aiDeviceName;
- (NSString *)aiCreateUuid;
- (NSString *)aiVendorId;

- (void)aiSetIad:(AIActivityHandler *)activityHandler;
@end
25 changes: 25 additions & 0 deletions Adjust/AIAdditions/UIDevice+AIAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
#import <AdSupport/ASIdentifierManager.h>
#endif

#if !ADJUST_NO_IDA
#import <iAd/iAd.h>
#endif

@implementation UIDevice(AIAdditions)

- (BOOL)aiTrackingEnabled {
Expand Down Expand Up @@ -165,4 +169,25 @@ - (NSString *)aiVendorId {
return @"";
}

- (void) aiSetIad:(AIActivityHandler *) activityHandler{
#if !ADJUST_NO_IDA
Class ADClientClass = NSClassFromString(@"ADClient");
if (ADClientClass) {
@try {
SEL sharedClientSelector = NSSelectorFromString(@"sharedClient");
SEL iadSelector = NSSelectorFromString(@"determineAppInstallationAttributionWithCompletionHandler:");
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
id ADClientSharedClientInstance = [ADClientClass performSelector:sharedClientSelector];

[ADClientSharedClientInstance performSelector:iadSelector withObject:^(BOOL appInstallationWasAttributedToiAd) {
activityHandler.isIad = appInstallationWasAttributedToiAd;
}];
#pragma clang diagnostic pop
}
@catch (NSException *exception) {
}
}
#endif
}
@end
2 changes: 1 addition & 1 deletion Adjust/AIPackageHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
- (void)pauseSending;
- (void)resumeSending;

- (void)finishedTrackingActivity:(AIActivityPackage *)activityPackage withResponse:(AIResponseData *)response;
- (void)finishedTrackingActivity:(AIActivityPackage *)activityPackage withResponse:(AIResponseData *)response jsonDict:(NSDictionary *)jsonDict;

@end

Expand Down
12 changes: 10 additions & 2 deletions Adjust/AIPackageHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,17 @@ - (void)resumeSending {
self.paused = NO;
}

- (void)finishedTrackingActivity:(AIActivityPackage *)activityPackage withResponse:(AIResponseData *)response {
- (void)finishedTrackingActivity:(AIActivityPackage *)activityPackage withResponse:(AIResponseData *)response jsonDict:(NSDictionary *)jsonDict{

response.activityKind = activityPackage.activityKind;
[self.activityHandler finishedTrackingWithResponse:response];

NSString * deepLink = nil;

if (jsonDict != nil) {
deepLink = [jsonDict objectForKey:@"deeplink"];
}

[self.activityHandler finishedTrackingWithResponse:response deepLink:deepLink];
}


Expand Down
8 changes: 4 additions & 4 deletions Adjust/AIRequestHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,14 @@ - (void)sendInternal:(AIActivityPackage *)package {
AIResponseData *responseData = [AIResponseData dataWithError:error.localizedDescription];
responseData.willRetry = YES;
[self.logger error:@"%@. (%@) Will retry later.", package.failureMessage, responseData.error];
[self.packageHandler finishedTrackingActivity:package withResponse:responseData];
[self.packageHandler finishedTrackingActivity:package withResponse:responseData jsonDict:nil];
[self.packageHandler closeFirstPackage];
return;
}

NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
AIResponseData *responseData = [AIResponseData dataWithJsonString:responseString];
NSDictionary *jsonDict = [AIUtil buildJsonDict:responseString];
AIResponseData *responseData = [AIResponseData dataWithJsonDict:jsonDict jsonString:responseString];

if (response.statusCode == 200) {
// success
Expand All @@ -89,7 +90,7 @@ - (void)sendInternal:(AIActivityPackage *)package {
[self.logger error:@"%@. (%@)", package.failureMessage, responseData.error];
}

[self.packageHandler finishedTrackingActivity:package withResponse:responseData];
[self.packageHandler finishedTrackingActivity:package withResponse:responseData jsonDict:jsonDict];
[self.packageHandler sendNextPackage];
}

Expand Down Expand Up @@ -127,5 +128,4 @@ - (NSData *)bodyForParameters:(NSDictionary *)parameters {
NSData *body = [NSData dataWithBytes:bodyString.UTF8String length:bodyString.length];
return body;
}

@end
4 changes: 2 additions & 2 deletions Adjust/AIResponseData.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@

#pragma mark internals

+ (AIResponseData *)dataWithJsonString:(NSString *)string;
+ (AIResponseData *)dataWithJsonDict:(NSDictionary *)jsonDict jsonString:(NSString *)jsonString;
+ (AIResponseData *)dataWithError:(NSString *)error;

- (id)initWithJsonString:(NSString *)string;
- (id)initWithJsonDict:(NSDictionary *)jsonDict jsonString:(NSString *)jsonString;
- (id)initWithError:(NSString *)error;

@end
11 changes: 4 additions & 7 deletions Adjust/AIResponseData.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,19 @@

@implementation AIResponseData

+ (AIResponseData *)dataWithJsonString:(NSString *)string {
return [[AIResponseData alloc] initWithJsonString:string];
+ (AIResponseData *)dataWithJsonDict:(NSDictionary *)jsonDict jsonString:(NSString *)jsonString {
return [[AIResponseData alloc] initWithJsonDict:jsonDict jsonString:jsonString];
}

+ (AIResponseData *)dataWithError:(NSString *)error {
return [[AIResponseData alloc] initWithError:error];
}

- (id)initWithJsonString:(NSString *)jsonString {
- (id)initWithJsonDict:(NSDictionary *)jsonDict jsonString:(NSString *)jsonString {
self = [super init];
if (self == nil) return nil;

NSError *error = nil;
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
if (error != nil) {
if (jsonDict == nil) {
self.error = [NSString stringWithFormat:@"Failed to parse json response: %@", jsonString.aiTrim];
return self;
}
Expand Down
1 change: 1 addition & 0 deletions Adjust/AIUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@

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

@end
15 changes: 14 additions & 1 deletion Adjust/AIUtil.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
#import "AILogger.h"
#import "UIDevice+AIAdditions.h"
#import "AIAdjustFactory.h"
#import "NSString+AIAdditions.h"

#include <sys/xattr.h>

static NSString * const kBaseUrl = @"https://app.adjust.io";
static NSString * const kClientSdk = @"ios3.3.5";
static NSString * const kClientSdk = @"ios3.4.0";

static NSString * const kDateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'Z";
static NSDateFormatter * dateFormat;
Expand Down Expand Up @@ -124,4 +125,16 @@ + (NSString *)dateFormat:(double) value {
return [dateFormat stringFromDate:date];
}

+ (NSDictionary *)buildJsonDict:(NSString *)jsonString {
NSError *error = nil;
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];

if (error != nil) {
return nil;
}

return jsonDict;
}

@end
3 changes: 2 additions & 1 deletion AdjustTests/AIActivityHandlerMock.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ @implementation AIActivityHandlerMock
@synthesize bufferEvents;
@synthesize trackMacMd5;
@synthesize delegate;
@synthesize isIad;

- (id)initWithAppToken:(NSString *)yourAppToken {
self = [super init];
Expand Down Expand Up @@ -59,7 +60,7 @@ - (void)trackRevenue:(double)amount
[self.loggerMock test:[prefix stringByAppendingFormat:@"trackRevenue amount:%f eventToken:%@ parameters:%@", amount, eventToken, parameters]];
}

- (void)finishedTrackingWithResponse:(AIResponseData *)response {
- (void)finishedTrackingWithResponse:(AIResponseData *)response deepLink:(NSString *)deepLink{
[self.loggerMock test:[prefix stringByAppendingFormat:@"finishedTrackingWithResponse response:%@", response]];
}

Expand Down
19 changes: 18 additions & 1 deletion AdjustTests/AIActivityHandlerTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ - (void)testFirstRun
AIActivityPackage *activityPackage = (AIActivityPackage *) self.packageHandlerMock.packageQueue[0];

// check the Sdk version is being tested
XCTAssertEqual(@"ios3.3.5", activityPackage.clientSdk, @"%@", activityPackage.extendedString);
XCTAssertEqual(@"ios3.4.0", activityPackage.clientSdk, @"%@", activityPackage.extendedString);

// check the server url
XCTAssertEqual(@"https://app.adjust.io", AIUtil.baseUrl);
Expand Down Expand Up @@ -605,4 +605,21 @@ - (void)testConversions {
XCTAssertEqual(AILogLevelError, [AILogger LogLevelFromString:@"error"]);
XCTAssertEqual(AILogLevelAssert, [AILogger LogLevelFromString:@"assert"]);
}

- (void)testfinishedTrackingWithResponse {
// 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"];

[activityHandler finishedTrackingWithResponse:nil deepLink:@"testfinishedTrackingWithResponse://"];

// check the deep link from the response
XCTAssert([self.loggerMock containsMessage:AILogLevelError beginsWith:@"Unable to open deep link (testfinishedTrackingWithResponse://)"],
@"%@", self.loggerMock);
}
@end
4 changes: 2 additions & 2 deletions AdjustTests/AIPackageHandlerMock.m
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ - (void)addPackage:(AIActivityPackage *)package {

- (void)sendFirstPackage {
[self.loggerMock test:[prefix stringByAppendingString:@"sendFirstPackage"]];
[self.activityHandler finishedTrackingWithResponse:[[AIResponseData alloc] init]];
[self.activityHandler finishedTrackingWithResponse:[[AIResponseData alloc] init] deepLink:nil];
}

- (void)sendNextPackage {
Expand All @@ -67,7 +67,7 @@ - (void)resumeSending {
[self.loggerMock test:[prefix stringByAppendingString:@"resumeSending"]];
}

- (void)finishedTrackingActivity:(AIActivityPackage *)activityPackage withResponse:(AIResponseData *)response {
- (void)finishedTrackingActivity:(AIActivityPackage *)activityPackage withResponse:(AIResponseData *)response jsonDict:(NSDictionary *)jsonDict {
[self.loggerMock test:[prefix stringByAppendingString:@"finishedTrackingActivity"]];
self.responseData = response;
}
Expand Down
8 changes: 5 additions & 3 deletions AdjustTests/AIRequestHandlerMock.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,17 @@ - (id)initWithPackageHandler:(id<AIPackageHandler>) packageHandler {
- (void)sendPackage:(AIActivityPackage *)activityPackage {
[self.loggerMock test:[prefix stringByAppendingString:@"sendPackage"]];

NSDictionary *jsonDict;
AIResponseData *responseData;

if (self.connectionError) {
jsonDict = nil;
responseData = [[AIResponseData alloc] initWithError:@"connection error"];
} else {
responseData = [[AIResponseData alloc] initWithJsonString:@"{\"tracker_token\":\"token\",\"tracker_name\":\"name\"}"];
jsonDict = @{@"tracker_token": @"token",@"tracker_name":@"name"};
responseData = [[AIResponseData alloc] initWithJsonDict:jsonDict jsonString:@"{\"tracker_token\":\"token\",\"tracker_name\":\"name\"}"];
}

[self.packageHandler finishedTrackingActivity:activityPackage withResponse:responseData];
[self.packageHandler finishedTrackingActivity:activityPackage withResponse:responseData jsonDict:jsonDict];

if (self.connectionError) {
[self.packageHandler closeFirstPackage];
Expand Down
Loading