Skip to content

Commit 4077d42

Browse files
authored
feat(profile): Apple advertising id (#182)
* feat(profile): advertising id in profile data params * feat(profile): pass advertising id for setProfile * feat(profile): advertising id param key * feat(init): send advertising id * feat(advertising): config * feat(profile): advertising port * feat(profile): idfa advertising adapter * feat(domain): advertising id vo * feat(domain): advertising error * feat(application): update advertising id use case * feat(sdk): update advertising id use case in sdk init * feat(advertising): use advertising id vo instead of string * feat(advertising): permissions request * feat(advertising): use value object
1 parent e521a46 commit 4077d42

File tree

11 files changed

+110
-4
lines changed

11 files changed

+110
-4
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
public protocol AdvertisingIdPort {
2+
func getAdvertisingId(completion: @escaping (AdvertisingId?) -> Void)
3+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class UpdateAdvertisingIdUseCase {
2+
private let advertisingIdPort: AdvertisingIdPort
3+
private let profileData: ProfileDataProtocol
4+
5+
init(advertisingIdPort: AdvertisingIdPort, profileData: ProfileDataProtocol) {
6+
self.advertisingIdPort = advertisingIdPort
7+
self.profileData = profileData
8+
}
9+
10+
func execute(completion: @escaping (Result<AdvertisingId, Error>) -> Void) {
11+
advertisingIdPort.getAdvertisingId { [weak self] id in
12+
guard let self = self, let id = id else {
13+
completion(.failure(AdvertisingError.advertisingIdUnavailable))
14+
return
15+
}
16+
17+
let profile = ProfileData(advertisingId: id.value)
18+
19+
self.profileData.setProfileData(profileData: profile) { result in
20+
switch result {
21+
case .success:
22+
completion(.success(id))
23+
case .failure(let error):
24+
completion(.failure(error))
25+
}
26+
}
27+
}
28+
}
29+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
enum AdvertisingError: Error {
2+
case advertisingIdUnavailable
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
public struct AdvertisingId {
2+
let value: String
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import Foundation
2+
3+
public let NullIDFA = "00000000-0000-0000-0000-000000000000"
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import AdSupport
2+
import AppTrackingTransparency
3+
import Foundation
4+
5+
public final class IDFAAdapter: AdvertisingIdPort {
6+
7+
public func getAdvertisingId(completion: @escaping (AdvertisingId?) -> Void) {
8+
if #available(iOS 14, *) {
9+
DispatchQueue.main.async {
10+
let status = ATTrackingManager.trackingAuthorizationStatus
11+
switch status {
12+
case .notDetermined:
13+
ATTrackingManager.requestTrackingAuthorization { newStatus in
14+
self.handleAuthorizationStatus(newStatus, completion: completion)
15+
}
16+
default:
17+
self.handleAuthorizationStatus(status, completion: completion)
18+
}
19+
}
20+
} else {
21+
if ASIdentifierManager.shared().isAdvertisingTrackingEnabled {
22+
let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
23+
completion(idfa != NullIDFA ? AdvertisingId(value: idfa) : nil)
24+
} else {
25+
completion(nil)
26+
}
27+
}
28+
}
29+
30+
@available(iOS 14, *)
31+
private func handleAuthorizationStatus(_ status: ATTrackingManager.AuthorizationStatus, completion: @escaping (AdvertisingId?) -> Void) {
32+
guard status == .authorized else {
33+
completion(nil)
34+
return
35+
}
36+
let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
37+
completion(idfa != NullIDFA ? AdvertisingId(value: idfa) : nil)
38+
}
39+
}

REES46/Classes/Profile/Service/Model/ProfileData.struct.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ struct ProfileData {
1010
var lastName: String?
1111
var location: String?
1212
var gender: Gender?
13+
var advertisingId: String?
1314
var fbID: String?
1415
var vkID: String?
1516
var telegramId: String?

REES46/Classes/Profile/Service/Model/ProfileDataConstants.struct.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ struct ProfileDataConstants{
77
static let lastName = "last_name"
88
static let phone = "phone"
99
static let location = "location"
10+
static let advertisingId = "apple_advertising_id"
1011
static let fbId = "fb_id"
1112
static let vkId = "vk_id"
1213
static let telegramId = "telegram_id"

REES46/Classes/Profile/Service/impl/ProfileDataImpl.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class ProfileDataImpl: ProfileDataProtocol {
5858
addIfNotNil(params: &params, key: ProfileDataConstants.loyaltyCardLocation, value: profileData.loyaltyCardLocation)
5959
addIfNotNil(params: &params, key: ProfileDataConstants.loyaltyId, value: profileData.userLoyaltyId)
6060
addIfNotNil(params: &params, key: ProfileDataConstants.loyaltyStatus, value: profileData.loyaltyStatus)
61+
addIfNotNil(params: &params, key: ProfileDataConstants.advertisingId, value: profileData.advertisingId)
6162
addIfNotNil(params: &params, key: ProfileDataConstants.fbId, value: profileData.fbID)
6263
addIfNotNil(params: &params, key: ProfileDataConstants.vkId, value: profileData.vkID)
6364
addIfNotNil(params: &params, key: ProfileDataConstants.telegramId, value: profileData.telegramId)

REES46/Classes/Sdk/impl/SimplePersonalizationSDK.swift

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ class SimplePersonalizationSDK: PersonalizationSDK {
6666
return ProfileDataImpl(sdk: self, configProvider: self)
6767
}()
6868

69+
lazy var updateAdvertisingIdUseCase: UpdateAdvertisingIdUseCase = {
70+
let advertisingIdAdapter = IDFAAdapter()
71+
return UpdateAdvertisingIdUseCase(
72+
advertisingIdPort: advertisingIdAdapter,
73+
profileData: self.profileData
74+
)
75+
}()
76+
6977
init(
7078
shopId: String,
7179
userEmail: String? = nil,
@@ -130,7 +138,20 @@ class SimplePersonalizationSDK: PersonalizationSDK {
130138
}
131139
self.initSemaphore.wait()
132140
}
133-
141+
142+
updateAdvertisingIdUseCase.execute { result in
143+
switch result {
144+
case .success(let advertisingId):
145+
#if DEBUG
146+
print("Advertising ID sent successfully: \(advertisingId.value)")
147+
#endif
148+
case .failure(let error):
149+
#if DEBUG
150+
print("Failed to send Advertising ID: \(error.localizedDescription)")
151+
#endif
152+
}
153+
}
154+
134155
initializeNotificationRegistrar()
135156
}
136157

@@ -318,6 +339,7 @@ class SimplePersonalizationSDK: PersonalizationSDK {
318339
lastName: String?,
319340
location: String?,
320341
gender: Gender?,
342+
advertisingId: String?,
321343
fbID: String?,
322344
vkID: String?,
323345
telegramId: String?,
@@ -341,6 +363,7 @@ class SimplePersonalizationSDK: PersonalizationSDK {
341363
lastName:lastName,
342364
location:location,
343365
gender:gender,
366+
advertisingId:advertisingId,
344367
fbID:fbID,
345368
vkID:vkID,
346369
telegramId:telegramId,

0 commit comments

Comments
 (0)