diff --git a/Adjust.podspec b/Adjust.podspec index c3a4d7400..31e40b7c3 100644 --- a/Adjust.podspec +++ b/Adjust.podspec @@ -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' diff --git a/Adjust/AIActivityHandler.h b/Adjust/AIActivityHandler.h index a9b22e678..8f72a09f2 100644 --- a/Adjust/AIActivityHandler.h +++ b/Adjust/AIActivityHandler.h @@ -14,6 +14,7 @@ @property (nonatomic, assign) BOOL bufferEvents; @property (nonatomic, assign) BOOL trackMacMd5; @property (nonatomic, assign) NSObject *delegate; +@property (nonatomic, assign) BOOL isIad; - (id)initWithAppToken:(NSString *)appToken; - (void)setSdkPrefix:(NSString *)sdkPrefix; @@ -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; diff --git a/Adjust/AIActivityHandler.m b/Adjust/AIActivityHandler.m index c3474312c..9afe5db54 100644 --- a/Adjust/AIActivityHandler.m +++ b/Adjust/AIActivityHandler.m @@ -17,9 +17,6 @@ #import "UIDevice+AIAdditions.h" #import "NSString+AIAdditions.h" #import "AIAdjustFactory.h" -#if !ADJUST_NO_IDA -#import -#endif static NSString * const kActivityStateFilename = @"AdjustIoActivityState"; static NSString * const kAdjustPrefix = @"adjust_"; @@ -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; @@ -61,6 +57,7 @@ @implementation AIActivityHandler @synthesize bufferEvents; @synthesize trackMacMd5; @synthesize delegate; +@synthesize isIad; + (id)handlerWithAppToken:(NSString *)appToken { return [[AIActivityHandler alloc] initWithAppToken:appToken]; @@ -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 { @@ -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]; diff --git a/Adjust/AIAdditions/UIDevice+AIAdditions.h b/Adjust/AIAdditions/UIDevice+AIAdditions.h index efd7f2f51..615e49c5b 100644 --- a/Adjust/AIAdditions/UIDevice+AIAdditions.h +++ b/Adjust/AIAdditions/UIDevice+AIAdditions.h @@ -7,6 +7,7 @@ // #import #import +#import "AIActivityHandler.h" @interface UIDevice(AIAdditions) @@ -18,5 +19,5 @@ - (NSString *)aiDeviceName; - (NSString *)aiCreateUuid; - (NSString *)aiVendorId; - +- (void)aiSetIad:(AIActivityHandler *)activityHandler; @end diff --git a/Adjust/AIAdditions/UIDevice+AIAdditions.m b/Adjust/AIAdditions/UIDevice+AIAdditions.m index 88a3c4b73..810811529 100644 --- a/Adjust/AIAdditions/UIDevice+AIAdditions.m +++ b/Adjust/AIAdditions/UIDevice+AIAdditions.m @@ -18,6 +18,10 @@ #import #endif +#if !ADJUST_NO_IDA +#import +#endif + @implementation UIDevice(AIAdditions) - (BOOL)aiTrackingEnabled { @@ -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 diff --git a/Adjust/AIPackageHandler.h b/Adjust/AIPackageHandler.h index c41b17b04..e01aa5d45 100644 --- a/Adjust/AIPackageHandler.h +++ b/Adjust/AIPackageHandler.h @@ -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 diff --git a/Adjust/AIPackageHandler.m b/Adjust/AIPackageHandler.m index 73b98125e..3885b85df 100644 --- a/Adjust/AIPackageHandler.m +++ b/Adjust/AIPackageHandler.m @@ -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]; } diff --git a/Adjust/AIRequestHandler.m b/Adjust/AIRequestHandler.m index c65ab95cd..8f143d1bd 100644 --- a/Adjust/AIRequestHandler.m +++ b/Adjust/AIRequestHandler.m @@ -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 @@ -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]; } @@ -127,5 +128,4 @@ - (NSData *)bodyForParameters:(NSDictionary *)parameters { NSData *body = [NSData dataWithBytes:bodyString.UTF8String length:bodyString.length]; return body; } - @end diff --git a/Adjust/AIResponseData.h b/Adjust/AIResponseData.h index 2db62873a..cb70ccec6 100644 --- a/Adjust/AIResponseData.h +++ b/Adjust/AIResponseData.h @@ -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 diff --git a/Adjust/AIResponseData.m b/Adjust/AIResponseData.m index 7884e99bf..7d4744388 100644 --- a/Adjust/AIResponseData.m +++ b/Adjust/AIResponseData.m @@ -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; } diff --git a/Adjust/AIUtil.h b/Adjust/AIUtil.h index 4b1145caa..120ab9298 100644 --- a/Adjust/AIUtil.h +++ b/Adjust/AIUtil.h @@ -15,5 +15,6 @@ + (void)excludeFromBackup:(NSString *)filename; + (NSString *)dateFormat:(double)value; ++ (NSDictionary *) buildJsonDict:(NSString *)jsonString; @end diff --git a/Adjust/AIUtil.m b/Adjust/AIUtil.m index 5b59ce37e..7211e6a69 100644 --- a/Adjust/AIUtil.m +++ b/Adjust/AIUtil.m @@ -10,11 +10,12 @@ #import "AILogger.h" #import "UIDevice+AIAdditions.h" #import "AIAdjustFactory.h" +#import "NSString+AIAdditions.h" #include 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; @@ -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 diff --git a/AdjustTests/AIActivityHandlerMock.m b/AdjustTests/AIActivityHandlerMock.m index 73b9f62cb..305de4ddf 100644 --- a/AdjustTests/AIActivityHandlerMock.m +++ b/AdjustTests/AIActivityHandlerMock.m @@ -24,6 +24,7 @@ @implementation AIActivityHandlerMock @synthesize bufferEvents; @synthesize trackMacMd5; @synthesize delegate; +@synthesize isIad; - (id)initWithAppToken:(NSString *)yourAppToken { self = [super init]; @@ -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]]; } diff --git a/AdjustTests/AIActivityHandlerTests.m b/AdjustTests/AIActivityHandlerTests.m index 21095ed65..3c272140f 100644 --- a/AdjustTests/AIActivityHandlerTests.m +++ b/AdjustTests/AIActivityHandlerTests.m @@ -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); @@ -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 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 diff --git a/AdjustTests/AIPackageHandlerMock.m b/AdjustTests/AIPackageHandlerMock.m index 279e4e596..adff8cced 100644 --- a/AdjustTests/AIPackageHandlerMock.m +++ b/AdjustTests/AIPackageHandlerMock.m @@ -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 { @@ -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; } diff --git a/AdjustTests/AIRequestHandlerMock.m b/AdjustTests/AIRequestHandlerMock.m index b320fc7ef..2574d2e0e 100644 --- a/AdjustTests/AIRequestHandlerMock.m +++ b/AdjustTests/AIRequestHandlerMock.m @@ -39,15 +39,17 @@ - (id)initWithPackageHandler:(id) 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]; diff --git a/AdjustTests/AIRequestHandlerTests.m b/AdjustTests/AIRequestHandlerTests.m index b68306778..d34e69e7d 100644 --- a/AdjustTests/AIRequestHandlerTests.m +++ b/AdjustTests/AIRequestHandlerTests.m @@ -85,9 +85,7 @@ - (void)testSendPackage @"%@", self.loggerMock); // check that the package handler was called to send the next package - XCTAssert([self.loggerMock containsMessage:AILogLevelTest beginsWith:@"AIPackageHandler sendNextPackage"], - @"%@", self.loggerMock); - + XCTAssert([self.loggerMock containsMessage:AILogLevelTest beginsWith:@"AIPackageHandler sendNextPackage"], @"%@", self.loggerMock); } - (void)testConnectionError { diff --git a/AdjustTests/NSURLConnection+NSURLConnectionSynchronousLoadingMocking.m b/AdjustTests/NSURLConnection+NSURLConnectionSynchronousLoadingMocking.m index 6bf895f26..39177ce24 100644 --- a/AdjustTests/NSURLConnection+NSURLConnectionSynchronousLoadingMocking.m +++ b/AdjustTests/NSURLConnection+NSURLConnectionSynchronousLoadingMocking.m @@ -26,22 +26,18 @@ + (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NS return nil; } NSInteger statusCode; - NSString * sResponseBase64; + NSString * sResponse; if (triggerResponseError) { statusCode = 0; - // encoded from "{"error":"response error"}" - sResponseBase64 = @"eyJlcnJvciI6InJlc3BvbnNlIGVycm9yIn0="; + sResponse = @"{\"error\":\"response error\"}"; } else { statusCode = 200; - // encoded from "{"tracker_token":"token","tracker_name":"name", "network":"network", "campaign":"campaign", "adgroup":"adgroup", "creative":"creative"}" - sResponseBase64 = @"eyJ0cmFja2VyX3Rva2VuIjoidG9rZW4iLCJ0cmFja2VyX25hbWUiOiJuYW1lIiwgIm5ldHdvcmsiOiJuZXR3b3JrIiwgImNhbXBhaWduIjoiY2FtcGFpZ24iLCAiYWRncm91cCI6ImFkZ3JvdXAiLCAiY3JlYXRpdmUiOiJjcmVhdGl2ZSJ9"; + sResponse = @"{\"tracker_token\":\"token\",\"tracker_name\":\"name\", \"network\":\"network\",\"campaign\":\"campaign\", \"adgroup\":\"adgroup\",\"creative\":\"creative\",\"deeplink\":\"testApp://\"}"; } // build response (*response) = [[NSHTTPURLResponse alloc] initWithURL:[[NSURL alloc] init] statusCode:statusCode HTTPVersion:@"" headerFields:nil]; - NSData *responseData = [[NSData alloc] - initWithBase64EncodedString:sResponseBase64 - options:NSDataBase64DecodingIgnoreUnknownCharacters]; + NSData *responseData = [sResponse dataUsingEncoding:NSUTF8StringEncoding]; return responseData; } diff --git a/README.md b/README.md index 050a193be..904b56768 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ If you're using [CocoaPods][cocoapods], you can add the following line to your `Podfile` and continue with [step 3](#step3): ```ruby -pod 'Adjust', :git => 'git://github.com/adjust/ios_sdk.git', :tag => 'v3.3.4' +pod 'Adjust', :git => 'git://github.com/adjust/ios_sdk.git', :tag => 'v3.4.0' ``` ### 1. Get the SDK diff --git a/VERSION b/VERSION index fa7adc7ac..18091983f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.3.5 +3.4.0 diff --git a/doc/migrate.md b/doc/migrate.md index 6c8517dcd..df6e41af9 100644 --- a/doc/migrate.md +++ b/doc/migrate.md @@ -1,4 +1,4 @@ -## Migrate your adjust SDK for iOS to v3.3.5 from v3.0.0 +## Migrate your adjust SDK for iOS to v3.4.0 from v3.0.0 We added an optional parameter `transactionId` to our `trackRevenue` methods. If you are tracking In-App Purchases you might want to pass in the transaction identifier provided by Apple to avoid duplicate revenue tracking. It should look roughly like this: @@ -36,14 +36,14 @@ all adjust SDK calls. ![][rename] -3. Download version v3.3.5 and drag the new folder `Adjust` into your Xcode +3. Download version v3.4.0 and drag the new folder `Adjust` into your Xcode Project Navigator. ![][drag] 4. Build your project to confirm that everything is properly connected again. -The adjust SDK v3.3.5 added delegate callbacks. Check out the [README] for +The adjust SDK v3.4.0 added delegate callbacks. Check out the [README] for details. @@ -99,7 +99,7 @@ meaningful at all times! Especially if you are tracking revenue. 1. The `appDidLaunch` method now expects your App Token instead of your App ID. You can find your App Token in your [dashboard]. -2. The adjust SDK for iOS 3.3.5 uses [ARC][arc]. If you haven't done already, +2. The adjust SDK for iOS 3.4.0 uses [ARC][arc]. If you haven't done already, we recommend [transitioning your project to use ARC][transition] as well. If you don't want to use ARC, you have to enable ARC for all files of the adjust SDK. Please consult the [README] for details.