Skip to content

Commit 81948fa

Browse files
authored
Merge pull request #782 from adjust/v551
Version 5.5.1
2 parents 20c877e + 2b66679 commit 81948fa

25 files changed

+376
-197
lines changed

Adjust.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Pod::Spec.new do |s|
22
s.name = "Adjust"
33
s.module_name = "AdjustSdk"
4-
s.version = "5.5.0"
4+
s.version = "5.5.1"
55
s.summary = "This is the iOS SDK of Adjust. You can read more about it at https://adjust.com."
66
s.homepage = "https://github.com/adjust/ios_sdk"
77
s.license = { :type => 'MIT', :file => 'LICENSE' }

Adjust/ADJLinkResolution.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// ADJLinkResolution.h
33
// Adjust
44
//
5-
// Created by Pedro S. on 26.04.21.
6-
// Copyright © 2021 adjust GmbH. All rights reserved.
5+
// Created by Pedro Silva (@nonelse) on 26th April 2021.
6+
// Copyright © 2021-Present Adjust GmbH. All rights reserved.
77
//
88

99
#import <Foundation/Foundation.h>

Adjust/ADJLinkResolution.m

Lines changed: 84 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
// ADJLinkResolution.m
33
// Adjust
44
//
5-
// Created by Pedro S. on 26.04.21.
6-
// Copyright © 2021 adjust GmbH. All rights reserved.
5+
// Created by Pedro Silva (@nonelse) on 26th April 2021.
6+
// Copyright © 2021-Present Adjust GmbH. All rights reserved.
77
//
88

99
#import "ADJLinkResolution.h"
10+
#import "ADJUtil.h"
1011

1112
static NSUInteger kMaxRecursions = 10;
1213

@@ -22,19 +23,21 @@ + (nonnull ADJLinkResolutionDelegate *)sharedInstance;
2223

2324
+ (nullable NSURL *)convertUrlToHttps:(nullable NSURL *)url;
2425

26+
+ (NSURLRequest *)replaceUrlWithRequest:(NSURLRequest *)request
27+
urlToReplace:(nonnull NSURL *)urlToReplace;
28+
2529
@end
2630

2731
@implementation ADJLinkResolutionDelegate
2832

2933
- (nonnull instancetype)init {
3034
self = [super init];
31-
3235
return self;
3336
}
3437

3538
+ (nonnull ADJLinkResolutionDelegate *)sharedInstance {
3639
static ADJLinkResolutionDelegate *sharedInstance = nil;
37-
static dispatch_once_t onceToken; // onceToken = 0
40+
static dispatch_once_t onceToken;
3841
dispatch_once(&onceToken, ^{
3942
sharedInstance = [[self alloc] init];
4043
});
@@ -44,8 +47,7 @@ + (nonnull ADJLinkResolutionDelegate *)sharedInstance {
4447
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
4548
willPerformHTTPRedirection:(NSHTTPURLResponse *)response
4649
newRequest:(NSURLRequest *)request
47-
completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler
48-
{
50+
completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler {
4951
// if we're already at a terminal host (adjust.com / adj.st / go.link),
5052
// stop auto-following to preserve the terminal URL (avoid jumping to App Store links)
5153
if ([ADJLinkResolution isTerminalUrlWithHost:response.URL.host]) {
@@ -55,7 +57,7 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
5557

5658
NSURL *_Nullable convertedUrl = [ADJLinkResolutionDelegate convertUrlToHttps:request.URL];
5759

58-
if (request.URL != nil && convertedUrl != nil && ! [request.URL isEqual:convertedUrl]) {
60+
if (request.URL != nil && convertedUrl != nil && ![request.URL isEqual:convertedUrl]) {
5961
completionHandler([ADJLinkResolutionDelegate replaceUrlWithRequest:request
6062
urlToReplace:convertedUrl]);
6163
} else {
@@ -67,24 +69,18 @@ + (nullable NSURL *)convertUrlToHttps:(nullable NSURL *)url {
6769
if (url == nil) {
6870
return nil;
6971
}
70-
71-
if (! [url.absoluteString hasPrefix:@"http:"]) {
72+
if (![url.absoluteString hasPrefix:@"http:"]) {
7273
return url;
7374
}
7475

7576
NSString *_Nonnull urlStringWithoutPrefix = [url.absoluteString substringFromIndex:5];
76-
77-
return [NSURL URLWithString:
78-
[NSString stringWithFormat:@"https:%@", urlStringWithoutPrefix]];
77+
return [NSURL URLWithString:[NSString stringWithFormat:@"https:%@", urlStringWithoutPrefix]];
7978
}
8079

8180
+ (NSURLRequest *)replaceUrlWithRequest:(NSURLRequest *)request
82-
urlToReplace:(nonnull NSURL *)urlToReplace
83-
{
81+
urlToReplace:(nonnull NSURL *)urlToReplace {
8482
NSMutableURLRequest *mutableRequest = [request mutableCopy];
85-
8683
[mutableRequest setURL:urlToReplace];
87-
8884
return [mutableRequest copy];
8985
}
9086

@@ -94,93 +90,99 @@ @implementation ADJLinkResolution
9490

9591
+ (void)resolveLinkWithUrl:(nonnull NSURL *)url
9692
resolveUrlSuffixArray:(nullable NSArray<NSString *> *)resolveUrlSuffixArray
97-
callback:(nonnull void (^)(NSURL *_Nullable resolvedLink))callback
98-
{
93+
callback:(nonnull void (^)(NSURL *_Nullable resolvedLink))callback {
9994
if (callback == nil) {
10095
return;
10196
}
102-
103-
if (url == nil) {
104-
callback(nil);
97+
if (url == nil || url.host == nil || url.host.length == 0) {
98+
[ADJUtil launchInMainThread:^{
99+
callback(url);
100+
}];
105101
return;
106102
}
107103

108-
if (! [ADJLinkResolution urlMatchesSuffixWithHost:url.host
109-
suffixArray:resolveUrlSuffixArray])
110-
{
111-
callback(url);
104+
// if suffix array is provided and URL doesn't match, return URL unchanged
105+
if (![ADJLinkResolution urlMatchesSuffixWithHost:url.host
106+
suffixArray:resolveUrlSuffixArray]) {
107+
[ADJUtil launchInMainThread:^{
108+
callback(url);
109+
}];
112110
return;
113111
}
114112

115-
ADJLinkResolutionDelegate *_Nonnull linkResolutionDelegate =
116-
[ADJLinkResolutionDelegate sharedInstance];
113+
ADJLinkResolutionDelegate *_Nonnull linkResolutionDelegate = [ADJLinkResolutionDelegate sharedInstance];
117114

118-
NSURLSession *_Nonnull session =
119-
[NSURLSession
120-
sessionWithConfiguration:NSURLSessionConfiguration.defaultSessionConfiguration
121-
delegate:linkResolutionDelegate
122-
delegateQueue:nil];
115+
// reuse shared session for better performance
116+
static NSURLSession *sharedSession = nil;
117+
static dispatch_once_t sessionOnceToken;
118+
dispatch_once(&sessionOnceToken, ^{
119+
sharedSession =
120+
[NSURLSession sessionWithConfiguration:NSURLSessionConfiguration.defaultSessionConfiguration
121+
delegate:linkResolutionDelegate
122+
delegateQueue:nil];
123+
});
123124

124125
NSURL *_Nullable httpsUrl = [ADJLinkResolutionDelegate convertUrlToHttps:url];
125-
126-
NSURLSessionDataTask *task =
127-
[session
128-
dataTaskWithURL:httpsUrl
129-
completionHandler:
130-
^(NSData * _Nullable data,
131-
NSURLResponse * _Nullable response,
132-
NSError * _Nullable error)
133-
{
134-
// bootstrap the recursion of resolving the link
135-
[ADJLinkResolution
136-
resolveLinkWithResponseUrl:response != nil ? response.URL : nil
137-
previousUrl:httpsUrl
138-
recursionNumber:0
139-
session:session
140-
callback:callback];
141-
}];
126+
NSURLSessionDataTask *task = [sharedSession dataTaskWithURL:httpsUrl
127+
completionHandler:^(NSData * _Nullable data,
128+
NSURLResponse * _Nullable response,
129+
NSError * _Nullable error) {
130+
// bootstrap the recursion of resolving the link
131+
[ADJLinkResolution resolveLinkWithResponseUrl:response != nil ? response.URL : nil
132+
previousUrl:httpsUrl
133+
recursionNumber:0
134+
session:sharedSession
135+
callback:callback];
136+
}];
142137
[task resume];
143138
}
144139

145140
+ (void)resolveLinkWithResponseUrl:(nullable NSURL *)responseUrl
146141
previousUrl:(nullable NSURL *)previousUrl
147142
recursionNumber:(NSUInteger)recursionNumber
148143
session:(nonnull NSURLSession *)session
149-
callback:(nonnull void (^)(NSURL *_Nullable resolvedLink))callback
150-
{
144+
callback:(nonnull void (^)(NSURL *_Nullable resolvedLink))callback {
151145
// return (possible nil) previous url when the current one does not exist
152146
if (responseUrl == nil) {
153-
callback(previousUrl);
147+
[ADJUtil launchInMainThread:^{
148+
callback(previousUrl);
149+
}];
154150
return;
155151
}
156-
157-
// return found url with expected host
152+
// stop recursion when URL stops changing (prevents infinite loops)
153+
if (previousUrl != nil && [responseUrl isEqual:previousUrl]) {
154+
[ADJUtil launchInMainThread:^{
155+
callback(responseUrl);
156+
}];
157+
return;
158+
}
159+
// return found url with expected host (Adjust terminal domains)
160+
// these are domains where we stop to avoid redirecting to App Store
158161
if ([ADJLinkResolution isTerminalUrlWithHost:responseUrl.host]) {
159-
callback(responseUrl);
162+
[ADJUtil launchInMainThread:^{
163+
callback(responseUrl);
164+
}];
160165
return;
161166
}
162-
163-
// return previous (non-nil) url when it reached the max number of recursive tries
167+
// return current url when it reached the max number of recursive tries
164168
if (recursionNumber >= kMaxRecursions) {
165-
callback(responseUrl);
169+
[ADJUtil launchInMainThread:^{
170+
callback(responseUrl);
171+
}];
166172
return;
167173
}
168174

169175
// when found a non expected url host, use it to recursively resolve the link
170-
NSURLSessionDataTask *task =
171-
[session
172-
dataTaskWithURL:responseUrl
173-
completionHandler:
174-
^(NSData * _Nullable data,
175-
NSURLResponse * _Nullable response,
176-
NSError * _Nullable error)
177-
{
178-
[ADJLinkResolution resolveLinkWithResponseUrl:response != nil ? response.URL : nil
179-
previousUrl:responseUrl
180-
recursionNumber:(recursionNumber + 1)
181-
session:session
182-
callback:callback];
183-
}];
176+
NSURLSessionDataTask *task = [session dataTaskWithURL:responseUrl
177+
completionHandler:^(NSData * _Nullable data,
178+
NSURLResponse * _Nullable response,
179+
NSError * _Nullable error) {
180+
[ADJLinkResolution resolveLinkWithResponseUrl:response != nil ? response.URL : nil
181+
previousUrl:responseUrl
182+
recursionNumber:(recursionNumber + 1)
183+
session:session
184+
callback:callback];
185+
}];
184186
[task resume];
185187
}
186188

@@ -189,16 +191,22 @@ + (BOOL)isTerminalUrlWithHost:(nullable NSString *)urlHost {
189191
return NO;
190192
}
191193

192-
NSArray<NSString *> *_Nonnull terminalUrlHostSuffixArray =
193-
@[@"adjust.com", @"adj.st", @"go.link", @"adjust.cn", @"adjust.net.in", @"adjust.world", @"adjust.io"];
194+
// check hardcoded Adjust terminal domains
195+
// these are domains where we stop recursion to avoid redirecting to App Store
196+
NSArray<NSString *> *_Nonnull terminalUrlHostSuffixArray = @[@"adjust.com",
197+
@"adj.st",
198+
@"go.link",
199+
@"adjust.cn",
200+
@"adjust.net.in",
201+
@"adjust.world",
202+
@"adjust.io"];
194203

195204
return [ADJLinkResolution urlMatchesSuffixWithHost:urlHost
196205
suffixArray:terminalUrlHostSuffixArray];
197206
}
198207

199208
+ (BOOL)urlMatchesSuffixWithHost:(nullable NSString *)urlHost
200-
suffixArray:(nullable NSArray<NSString *> *)suffixArray
201-
{
209+
suffixArray:(nullable NSArray<NSString *> *)suffixArray {
202210
if (urlHost == nil) {
203211
return NO;
204212
}

Adjust/ADJLogger.m

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
#import "ADJLogger.h"
10+
#import <os/log.h>
1011

1112
static NSString * const kLogTag = @"Adjust";
1213

@@ -15,6 +16,7 @@ @interface ADJLogger()
1516
@property (nonatomic, assign) ADJLogLevel loglevel;
1617
@property (nonatomic, assign) BOOL logLevelLocked;
1718
@property (nonatomic, assign) BOOL isProductionEnvironment;
19+
@property (nonatomic, strong) os_log_t osLogLogger;
1820

1921
@end
2022

@@ -29,6 +31,7 @@ - (id)init {
2931
_loglevel = ADJLogLevelInfo;
3032
self.logLevelLocked = NO;
3133
self.isProductionEnvironment = NO;
34+
self.osLogLogger = os_log_create("com.adjust.sdk", "Adjust");
3235

3336
return self;
3437
}
@@ -100,8 +103,18 @@ - (void)logLevel:(NSString *)logLevel format:(NSString *)format parameters:(va_l
100103
va_end(parameters);
101104

102105
NSArray *lines = [string componentsSeparatedByString:@"\n"];
106+
107+
os_log_type_t osLogType = OS_LOG_TYPE_DEFAULT;
108+
if ([logLevel isEqualToString:@"e"] || [logLevel isEqualToString:@"w"]) {
109+
osLogType = OS_LOG_TYPE_ERROR;
110+
} else if ([logLevel isEqualToString:@"a"]) {
111+
osLogType = OS_LOG_TYPE_FAULT;
112+
}
113+
103114
for (NSString *line in lines) {
104-
NSLog(@"\t[%@]%@: %@", kLogTag, logLevel, line);
115+
os_log_with_type(self.osLogLogger, osLogType,
116+
"\t[%{public}@]%{public}@: %{public}@",
117+
kLogTag, logLevel, line);
105118
}
106119
}
107120

Adjust/Adjust.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Adjust.h
33
// Adjust SDK
44
//
5-
// V5.5.0
5+
// V5.5.1
66
// Created by Christian Wellenbrock (@wellle) on 23rd July 2013.
77
// Copyright (c) 2012-Present Adjust GmbH. All rights reserved.
88
//

Adjust/Internal/ADJActivityHandler.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,12 @@
6767
@end
6868

6969
@class ADJTrackingStatusManager;
70+
@class ADJAdServicesManager;
7071

7172
@protocol ADJActivityHandler <NSObject>
7273

7374
@property (nonatomic, strong) ADJTrackingStatusManager * _Nullable trackingStatusManager;
75+
@property (nonatomic, strong) ADJAdServicesManager * _Nullable adServicesManager;
7476

7577
- (id _Nullable)initWithConfig:(ADJConfig *_Nullable)adjustConfig
7678
savedPreLaunch:(ADJSavedPreLaunch * _Nullable)savedPreLaunch
@@ -103,8 +105,7 @@
103105

104106
- (BOOL)updateAttributionI:(id<ADJActivityHandler> _Nullable)selfI
105107
attribution:(ADJAttribution * _Nullable)attribution;
106-
- (void)setAdServicesAttributionToken:(NSString * _Nullable)token
107-
error:(NSError * _Nullable)error;
108+
- (void)forceRecheckAdServicesAttribution;
108109

109110
- (void)setOfflineMode:(BOOL)offline;
110111

@@ -199,6 +200,14 @@
199200

200201
@end
201202

203+
@interface ADJAdServicesManager : NSObject
204+
205+
- (instancetype _Nullable)initWithActivityHandler:(ADJActivityHandler * _Nullable)activityHandler;
206+
- (void)checkForAdServicesAttribution;
207+
- (void)forceRecheckAdServicesAttribution;
208+
209+
@end
210+
202211
extern NSString * _Nullable const ADJClickSourceAdServices;
203212
extern NSString * _Nullable const ADJClickSourceGoogleOdm;
204213

0 commit comments

Comments
 (0)