99import Foundation
1010
1111extension ApphudInternal {
12-
12+
1313 // MARK: - Attribution
14- internal func addAttribution ( rawData : [ AnyHashable : Any ] ? , from provider: ApphudAttributionProvider , identifer: String ? = nil , callback: ( ( Bool ) -> Void ) ? ) {
14+ internal func setAttribution ( data : ApphudAttributionData , from provider: ApphudAttributionProvider , identifer: String ? = nil , callback: ( ( Bool ) -> Void ) ? ) {
1515 performWhenUserRegistered {
1616 Task {
17-
18- let data = rawData as? [ String : any Sendable ]
19-
20- var params : [ String : Any ] = [ " device_id " : self . currentDeviceID]
21-
17+ var dict : [ String : any Sendable ] = data. rawData as? [ String : any Sendable ] ?? [ : ]
18+
2219 switch provider {
20+ // ---------- .custom ----------
2321 case . custom:
24- if let customAttribution = data {
25- params. merge ( customAttribution, uniquingKeysWith: { f, _ in f} )
26- }
22+ dict [ " identifier " ] = identifer
23+ break
24+
25+ // ---------- .voluum ----------
26+ case . voluum:
27+ dict [ " identifier " ] = identifer
28+ break
29+
30+ // ---------- .singular ----------
31+ case . singular:
32+ dict [ " identifier " ] = identifer
33+ break
34+
35+ // ---------- .tenjin ----------
36+ case . tenjin:
37+ dict [ " identifier " ] = identifer
38+ break
39+
40+ // ---------- .tiktok ----------
41+ case . tiktok:
42+ dict [ " identifier " ] = identifer
43+ break
44+
45+ // ---------- .branch ----------
2746 case . branch:
28- if let customAttribution = data {
29- let wrappedAttribution = customAttribution [ " branch_data " ] == nil ?
30- [ " branch_data " : customAttribution] : customAttribution
31- params. merge ( wrappedAttribution, uniquingKeysWith: { f, _ in f} )
32- }
47+ dict [ " identifier " ] = identifer
48+ break
49+
50+ // ---------- .facebook ----------
3351 case . facebook:
34- guard identifer != nil , self . submittedFacebookAnonId != identifer else {
35- apphudLog ( " Facebook Anon ID is nil or didn't change, exiting " , forceDisplay: true )
52+ guard let fbIdent = identifer,
53+ self . submittedFacebookAnonId != fbIdent
54+ else {
55+ apphudLog ( " Facebook Anon ID (identifer field) is nil or didn't change, exiting " , forceDisplay: true )
3656 callback ? ( false )
3757 return
3858 }
39- params [ " fb_anon_id " ] = identifer
40- if let customAttribution = data {
41- params. merge ( customAttribution, uniquingKeysWith: { f, _ in f} )
42- }
59+ dict [ " fb_anon_id " ] = fbIdent
60+
61+ // ---------- .firebase ----------
4362 case . firebase:
44- guard identifer != nil , self . submittedFirebaseId != identifer else {
63+ guard let firebaseId = identifer,
64+ self . submittedFirebaseId != firebaseId
65+ else {
4566 callback ? ( false )
4667 return
4768 }
48- params [ " firebase_id " ] = identifer
69+ dict [ " firebase_id " ] = firebaseId
70+
71+ // ---------- .appsFlyer ----------
4972 case . appsFlyer:
50- guard identifer != nil else {
73+ guard let afIdent = identifer else {
5174 callback ? ( false )
5275 return
5376 }
@@ -56,40 +79,37 @@ extension ApphudInternal {
5679 callback ? ( false )
5780 return
5881 }
59- params [ " appsflyer_id " ] = identifer
6082
61- if let data = data {
62- params [ " appsflyer_data " ] = data
83+ dict [ " appsflyer_id " ] = afIdent
6384
64- guard await self . submittedPreviouslyAF ( data: data) else {
65- apphudLog ( " Already submitted AppsFlyer attribution, skipping " , forceDisplay: true )
66- callback ? ( false )
67- return
68- }
85+ guard await self . submittedPreviouslyAF ( data: dict) else {
86+ apphudLog ( " Already submitted AppsFlyer attribution, skipping " , forceDisplay: true )
87+ callback ? ( false )
88+ return
6989 }
7090 self . isSendingAppsFlyer = true
91+
92+ // ---------- .adjust ----------
7193 case . adjust:
7294 guard !self . isSendingAdjust else {
7395 apphudLog ( " Already submitted Adjust attribution, skipping " , forceDisplay: true )
7496 callback ? ( false )
7597 return
7698 }
77- if var data = data {
78- if let adid = identifer {
79- data [ " adid " ] = adid
80- }
81-
82- params [ " adjust_data " ] = data
99+ if let adid = identifer {
100+ dict [ " adid " ] = adid
101+ }
83102
84- guard await self . submittedPreviouslyAdjust ( data: data) else {
85- apphudLog ( " Already submitted Adjust attribution, skipping " , forceDisplay: true )
86- callback ? ( false )
87- return
88- }
103+ guard await self . submittedPreviouslyAdjust ( data: dict) else {
104+ apphudLog ( " Already submitted Adjust attribution, skipping " , forceDisplay: true )
105+ callback ? ( false )
106+ return
89107 }
90108 self . isSendingAdjust = true
109+
110+ // ---------- .appleAdsAttribution ----------
91111 case . appleAdsAttribution:
92- guard identifer != nil else {
112+ guard let token = identifer else {
93113 callback ? ( false )
94114 return
95115 }
@@ -99,28 +119,55 @@ extension ApphudInternal {
99119 return
100120 }
101121
102- if let searchAdsData = await self . getAppleAttribution ( identifer!) {
103- params [ " search_ads_data " ] = searchAdsData
122+ if let searchAdsData = await self . getAppleAttribution ( token) {
123+ for (key, value) in searchAdsData {
124+ dict [ key] = value
125+ }
104126 } else {
105127 callback ? ( false )
106128 return
107129 }
130+
108131 default :
109- return
132+ break
110133 }
134+
135+ // Create Request params with raw_data
136+ var params : [ String : Any ] = [
137+ " device_id " : self . currentDeviceID,
138+ " provider " : provider. toString ( ) ,
139+ " raw_data " : dict
140+ ]
111141
112- // to avoid 404 problems on backend
142+ var attributionDict : [ String : any Sendable ] = [ : ]
143+ if let adNetwork = data. adNetwork { attributionDict [ " ad_network " ] = adNetwork }
144+ if let channel = data. channel { attributionDict [ " channel " ] = channel }
145+ if let campaign = data. campaign { attributionDict [ " campaign " ] = campaign }
146+ if let adSet = data. adSet { attributionDict [ " ad_set " ] = adSet }
147+ if let creative = data. creative { attributionDict [ " creative " ] = creative }
148+ if let keyword = data. keyword { attributionDict [ " keyword " ] = keyword }
149+ if let custom1 = data. custom1 { attributionDict [ " custom_1 " ] = custom1 }
150+ if let custom2 = data. custom2 { attributionDict [ " custom_2 " ] = custom2 }
151+
152+ params [ " attribution " ] = attributionDict
153+
113154 try ? await Task . sleep ( nanoseconds: 2_000_000_000 )
114-
115- self . startAttributionRequest ( params: params, provider: provider, identifer: identifer) { result in
155+
156+ self . startAttributionRequest ( params: params, apiVersion : . APIV2 , provider: provider, identifer: identifer) { result in
116157 Task {
117158 if result {
118159 switch provider {
119160 case . appsFlyer:
120- await ApphudDataActor . shared. setAFData ( data )
161+ await ApphudDataActor . shared. setAFData ( dict )
121162 case . adjust:
122- await ApphudDataActor . shared. setAdjustData ( data)
123- default :
163+ await ApphudDataActor . shared. setAdjustData ( dict)
164+ case . firebase:
165+ self . submittedFirebaseId = identifer
166+ case . facebook:
167+ self . submittedFacebookAnonId = identifer
168+ case . appleAdsAttribution:
169+ self . didSubmitAppleAdsAttribution = true
170+ default :
124171 break
125172 }
126173 }
@@ -130,7 +177,7 @@ extension ApphudInternal {
130177 }
131178 }
132179 }
133-
180+
134181 func submittedPreviouslyAF( data: [ String : any Sendable ] ) async -> Bool {
135182 return await self . compareAttribution ( first: data, second: ApphudDataActor . shared. submittedAFData ?? [ : ] )
136183 }
@@ -146,8 +193,8 @@ extension ApphudInternal {
146193 return !dictionary1. isEqual ( to: dictionary2 as! [ AnyHashable : Any ] )
147194 }
148195
149- func startAttributionRequest( params: [ String : Any ] , provider: ApphudAttributionProvider , identifer: String ? , callback: ( ( Bool ) -> Void ) ? ) {
150- self . httpClient? . startRequest ( path: . attribution, params: params, method: . post, retry: true ) { ( result, _, _, _, _, _, _) in
196+ func startAttributionRequest( params: [ String : Any ] , apiVersion : ApphudHttpClient . ApphudApiVersion = . APIV1 , provider: ApphudAttributionProvider , identifer: String ? , callback: ( ( Bool ) -> Void ) ? ) {
197+ self . httpClient? . startRequest ( path: . attribution, apiVersion : apiVersion , params: params, method: . post, retry: true ) { ( result, _, _, _, _, _, _) in
151198 switch provider {
152199 case . adjust:
153200 // to avoid sending the same data several times in a row
@@ -208,7 +255,7 @@ extension ApphudInternal {
208255 request. setValue ( " text/plain " , forHTTPHeaderField: " Content-Type " )
209256 request. httpBody = Data ( appleAttibutionToken. utf8)
210257
211- let response = try ? await URLSession . shared. data ( for: request, retries: 5 , delay: 1 .0)
258+ let response = try ? await URLSession . shared. data ( for: request, retries: 5 , delay: 7 .0)
212259 if let data = response? . 0 ,
213260 let result = try ? JSONSerialization . jsonObject ( with: data, options: . allowFragments) as? [ String : any Sendable ] ,
214261 let attribution = result [ " attribution " ] as? Bool {
0 commit comments