From 91d3abe3857e24d20ce1a9eba62a7523fbbb81bf Mon Sep 17 00:00:00 2001 From: Scott Clampet <110618242+scottkicks@users.noreply.github.com> Date: Tue, 25 Jul 2023 10:36:52 -0600 Subject: [PATCH] [MBL 873] Implement TriggerThirdPartyEvent Mutation (#1835) * rename FacebookCAPIEventName to ThirdPartyEventInputName * replace .triggerCapiEventInput calls with .triggerThirdPartyEventInput * cleanup TriggerCapiEventInput related files and references * cleanup mutation calls * include required OS version in extInfo at correct index according to CAPI docs all values are required and must be in the given indexed order. * rename input name * add platformVersion computed property to NSBundleType * refactor mutation calls --- Kickstarter.xcodeproj/project.pbxproj | 28 ++------ KsApi/MockService.swift | 17 ----- KsApi/Service.swift | 10 --- KsApi/ServiceType.swift | 4 -- ...CapiEventInput+TriggerCapiEventInput.swift | 12 ---- ...ventInput+TriggerCapiEventInputTests.swift | 28 -------- KsApi/mutations/TriggerCapiEvent.graphql | 5 -- .../inputs/TriggerCapiEventInput.swift | 37 ----------- .../inputs/TriggerCapiEventInputTests.swift | 29 --------- Library/NSBundleType+Tests.swift | 5 ++ Library/NSBundleType.swift | 4 ++ Library/TestHelpers/MockBundle.swift | 1 + ...e.swift => ThirdPartyEventInputName.swift} | 2 +- .../PledgePaymentMethodsViewModel.swift | 32 +++++++--- .../PledgePaymentMethodsViewModelTests.swift | 1 - Library/ViewModels/ProjectPageViewModel.swift | 34 ++++++---- .../RewardsCollectionViewModel.swift | 34 ++++++---- Library/ViewModels/ThanksViewModel.swift | 64 +++++++++++-------- 18 files changed, 118 insertions(+), 229 deletions(-) delete mode 100644 KsApi/models/graphql/adapters/GraphAPI.TriggerCapiEventInput+TriggerCapiEventInput.swift delete mode 100644 KsApi/models/graphql/adapters/GraphAPI.TriggerCapiEventInput+TriggerCapiEventInputTests.swift delete mode 100644 KsApi/mutations/TriggerCapiEvent.graphql delete mode 100644 KsApi/mutations/inputs/TriggerCapiEventInput.swift delete mode 100644 KsApi/mutations/inputs/TriggerCapiEventInputTests.swift rename Library/Tracking/{FacebookCAPIEventName.swift => ThirdPartyEventInputName.swift} (88%) diff --git a/Kickstarter.xcodeproj/project.pbxproj b/Kickstarter.xcodeproj/project.pbxproj index 37f929dcab..6c4dae7e61 100644 --- a/Kickstarter.xcodeproj/project.pbxproj +++ b/Kickstarter.xcodeproj/project.pbxproj @@ -475,7 +475,7 @@ 6008633729B9025F00B87B39 /* GraphUserEmailTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6008633529B9023300B87B39 /* GraphUserEmailTests.swift */; }; 6008633F29BF750700B87B39 /* MockAppTrackingTransparency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6008633E29BF750700B87B39 /* MockAppTrackingTransparency.swift */; }; 6018626629A9194600EA2842 /* AppTrackingTransparency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6018626529A9194600EA2842 /* AppTrackingTransparency.swift */; }; - 6018626829A91B8C00EA2842 /* FacebookCAPIEventName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6018626729A91B8C00EA2842 /* FacebookCAPIEventName.swift */; }; + 6018626829A91B8C00EA2842 /* ThirdPartyEventInputName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6018626729A91B8C00EA2842 /* ThirdPartyEventInputName.swift */; }; 606754BD28CF91D60033CD5E /* FacebookCore in Frameworks */ = {isa = PBXBuildFile; productRef = 606754BC28CF91D60033CD5E /* FacebookCore */; }; 606754BF28CF91DD0033CD5E /* FacebookLogin in Frameworks */ = {isa = PBXBuildFile; productRef = 606754BE28CF91DD0033CD5E /* FacebookLogin */; }; 6067BCE9293E49AC0036ABB1 /* FacebookResetPasswordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6067BCE7293E48140036ABB1 /* FacebookResetPasswordViewController.swift */; }; @@ -486,11 +486,6 @@ 606C45F529FACD78001BA067 /* RemoteConfigFeature+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 606C45F429FACD78001BA067 /* RemoteConfigFeature+Helpers.swift */; }; 606C45F829FACD9F001BA067 /* RemoteConfigFeature+HelpersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 606C45F629FACD94001BA067 /* RemoteConfigFeature+HelpersTests.swift */; }; 606C45FA29FACE17001BA067 /* MockRemoteConfigClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 606C45F929FACE17001BA067 /* MockRemoteConfigClient.swift */; }; - 606F215C299D3FA900BA5CDF /* GraphAPI.TriggerCapiEventInput+TriggerCapiEventInputTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 606F215A299D3EF800BA5CDF /* GraphAPI.TriggerCapiEventInput+TriggerCapiEventInputTests.swift */; }; - 606F215E299D414800BA5CDF /* GraphAPI.TriggerCapiEventInput+TriggerCapiEventInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 606F215D299D414800BA5CDF /* GraphAPI.TriggerCapiEventInput+TriggerCapiEventInput.swift */; }; - 606F2166299D456D00BA5CDF /* TriggerCapiEvent.graphql in Sources */ = {isa = PBXBuildFile; fileRef = 606F2165299D456D00BA5CDF /* TriggerCapiEvent.graphql */; }; - 606F2168299D45F900BA5CDF /* TriggerCapiEventInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 606F2167299D45F900BA5CDF /* TriggerCapiEventInput.swift */; }; - 606F216B299E8D8500BA5CDF /* TriggerCapiEventInputTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 606F2169299E8C9F00BA5CDF /* TriggerCapiEventInputTests.swift */; }; 6078106B2A0419130050D4F7 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = 6078106A2A0419130050D4F7 /* FirebaseCrashlytics */; }; 6078106D2A0419170050D4F7 /* FirebasePerformance in Frameworks */ = {isa = PBXBuildFile; productRef = 6078106C2A0419170050D4F7 /* FirebasePerformance */; }; 6078106F2A04191C0050D4F7 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 6078106E2A04191C0050D4F7 /* FirebaseAnalytics */; }; @@ -2056,7 +2051,7 @@ 6008633529B9023300B87B39 /* GraphUserEmailTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphUserEmailTests.swift; sourceTree = ""; }; 6008633E29BF750700B87B39 /* MockAppTrackingTransparency.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockAppTrackingTransparency.swift; sourceTree = ""; }; 6018626529A9194600EA2842 /* AppTrackingTransparency.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTrackingTransparency.swift; sourceTree = ""; }; - 6018626729A91B8C00EA2842 /* FacebookCAPIEventName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacebookCAPIEventName.swift; sourceTree = ""; }; + 6018626729A91B8C00EA2842 /* ThirdPartyEventInputName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdPartyEventInputName.swift; sourceTree = ""; }; 6067BCE7293E48140036ABB1 /* FacebookResetPasswordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacebookResetPasswordViewController.swift; sourceTree = ""; }; 6067BCEA293E49CB0036ABB1 /* FacebookResetPasswordViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacebookResetPasswordViewModel.swift; sourceTree = ""; }; 6067BCEF293FC10E0036ABB1 /* FacebookResetPasswordViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacebookResetPasswordViewModelTests.swift; sourceTree = ""; }; @@ -2065,11 +2060,6 @@ 606C45F429FACD78001BA067 /* RemoteConfigFeature+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RemoteConfigFeature+Helpers.swift"; sourceTree = ""; }; 606C45F629FACD94001BA067 /* RemoteConfigFeature+HelpersTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RemoteConfigFeature+HelpersTests.swift"; sourceTree = ""; }; 606C45F929FACE17001BA067 /* MockRemoteConfigClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRemoteConfigClient.swift; sourceTree = ""; }; - 606F215A299D3EF800BA5CDF /* GraphAPI.TriggerCapiEventInput+TriggerCapiEventInputTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GraphAPI.TriggerCapiEventInput+TriggerCapiEventInputTests.swift"; sourceTree = ""; }; - 606F215D299D414800BA5CDF /* GraphAPI.TriggerCapiEventInput+TriggerCapiEventInput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GraphAPI.TriggerCapiEventInput+TriggerCapiEventInput.swift"; sourceTree = ""; }; - 606F2165299D456D00BA5CDF /* TriggerCapiEvent.graphql */ = {isa = PBXFileReference; lastKnownFileType = text; path = TriggerCapiEvent.graphql; sourceTree = ""; }; - 606F2167299D45F900BA5CDF /* TriggerCapiEventInput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TriggerCapiEventInput.swift; sourceTree = ""; }; - 606F2169299E8C9F00BA5CDF /* TriggerCapiEventInputTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TriggerCapiEventInputTests.swift; sourceTree = ""; }; 608E7A5128ABD5E700289E92 /* SetYourPasswordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetYourPasswordViewController.swift; sourceTree = ""; }; 608E7A5428ABE27400289E92 /* SetYourPasswordViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetYourPasswordViewModel.swift; sourceTree = ""; }; 6093098C2A6054CB004297AF /* GraphAPI.TriggerThirdPartyEventInput+TriggerThirdPartyEventInput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GraphAPI.TriggerThirdPartyEventInput+TriggerThirdPartyEventInput.swift"; sourceTree = ""; }; @@ -5775,7 +5765,6 @@ 06261602273B0E1500389981 /* PostComment.graphql */, 062868E526B999EF00EC5052 /* DeletePaymentSource.graphql */, 47D7D09526C2EA5200D2BAB5 /* SignInWithApple.graphql */, - 606F2165299D456D00BA5CDF /* TriggerCapiEvent.graphql */, 609309942A6055A5004297AF /* TriggerThirdPartyEvent.graphql */, 8AC3E0F4269F48A400168BF8 /* UpdateBacking.graphql */, 06643F3926A5FF1C002C5997 /* UpdateUserAccount.graphql */, @@ -5889,7 +5878,7 @@ children = ( 8A788F25263C80C500A89DAE /* Vendor */, 6018626529A9194600EA2842 /* AppTrackingTransparency.swift */, - 6018626729A91B8C00EA2842 /* FacebookCAPIEventName.swift */, + 6018626729A91B8C00EA2842 /* ThirdPartyEventInputName.swift */, 8A23203025B0ECF700B940C3 /* IdentifyingTrackingClient.swift */, 8A213CE8239EAEA400BBB4C7 /* KSRAnalytics.swift */, 8A4B8E812639F8C700D92E4E /* KSRAnalyticsIdentityData.swift */, @@ -5995,8 +5984,6 @@ 06962F8E273B3DF200FB0B3D /* GraphAPI.PostCommentInput+PostCommentInputTests.swift */, 47D7D09726C2ECB300D2BAB5 /* GraphAPI.SignInWithAppleInput+SignInWithAppleInput.swift */, 47D7D09B26C2FA5F00D2BAB5 /* GraphAPI.SignInWithAppleInput+SignInWithAppleInputTests.swift */, - 606F215D299D414800BA5CDF /* GraphAPI.TriggerCapiEventInput+TriggerCapiEventInput.swift */, - 606F215A299D3EF800BA5CDF /* GraphAPI.TriggerCapiEventInput+TriggerCapiEventInputTests.swift */, 6093098C2A6054CB004297AF /* GraphAPI.TriggerThirdPartyEventInput+TriggerThirdPartyEventInput.swift */, 6093098E2A6054D8004297AF /* GraphAPI.TriggerThirdPartyEventInput+TriggerThirdPartyEventInputTests.swift */, 8AC3E10C269F4D4000168BF8 /* GraphAPI.UpdateBackingInput+UpdateBackingInput.swift */, @@ -7089,8 +7076,6 @@ 47A662F826AF7745001CE7B1 /* WatchProjectInputTests.swift */, D6F5C6102437E12300C1A79D /* SignInWithAppleInput.swift */, 77C0818D245CBA1B004ABE88 /* SignInWithAppleInputTests.swift */, - 606F2167299D45F900BA5CDF /* TriggerCapiEventInput.swift */, - 606F2169299E8C9F00BA5CDF /* TriggerCapiEventInputTests.swift */, 609309902A60555F004297AF /* TriggerThirdPartyEventInput.swift */, 609309922A605563004297AF /* TriggerThirdPartyEventInputTests.swift */, 4753C76E264DAFD300BB10B6 /* PostCommentInput.swift */, @@ -7828,7 +7813,7 @@ D66850A1236CA44C00EE9AC2 /* ProjectPamphletCreatorHeaderCellViewModel.swift in Sources */, A75C81201D210C4700B5AD03 /* UpdateActivityItemProvider.swift in Sources */, 9D7536CF1D78D88D00A7623B /* SurveyResponseViewModel.swift in Sources */, - 6018626829A91B8C00EA2842 /* FacebookCAPIEventName.swift in Sources */, + 6018626829A91B8C00EA2842 /* ThirdPartyEventInputName.swift in Sources */, A710573B1DC2B2DF00A69552 /* SharedFunctions.swift in Sources */, A7DC83961C9DBBE700BB2B44 /* RefTag.swift in Sources */, D6089E8F209106CD0032CC99 /* PushNotificationDialog.swift in Sources */, @@ -8664,7 +8649,6 @@ D01589811EEB2ED7006E7684 /* Update.swift in Sources */, 8AC3E00726961E6400168BF8 /* Reward+RewardFragment.swift in Sources */, 378CA24622C4449F004E3C86 /* CountryLenses.swift in Sources */, - 606F215E299D414800BA5CDF /* GraphAPI.TriggerCapiEventInput+TriggerCapiEventInput.swift in Sources */, 476A2A6425DEED2600EB6A56 /* PerimeterXTypes.swift in Sources */, D0158A161EEB30A2006E7684 /* ItemTemplates.swift in Sources */, D63BBD33217F9CDE007E01F0 /* GraphCreditCardTemplate.swift in Sources */, @@ -8783,7 +8767,6 @@ D01588E51EEB2ED7006E7684 /* Location.swift in Sources */, 8A15571D2693B29600017845 /* Comment+CommentFragment.swift in Sources */, 6008633429B8FBD700B87B39 /* GraphUserEmail.swift in Sources */, - 606F2168299D45F900BA5CDF /* TriggerCapiEventInput.swift in Sources */, 06232D442795EC4300A81755 /* ExternalSourceViewElement.swift in Sources */, 8A67DDB624DCB7D500B4AB10 /* Constants.swift in Sources */, D01588A11EEB2ED7006E7684 /* MessageThreadLenses.swift in Sources */, @@ -8847,7 +8830,6 @@ D01589931EEB2ED7006E7684 /* User.swift in Sources */, D0158A271EEB30A2006E7684 /* ShippingRuleTemplates.swift in Sources */, 06566375270BAA7C00CE7EDF /* Project+FetchProjectRewardsByIdQueryData.swift in Sources */, - 606F2166299D456D00BA5CDF /* TriggerCapiEvent.graphql in Sources */, 8AF34C782342D6A5000B211D /* Encodable+Dictionary.swift in Sources */, 77E44B7421823A56006446B8 /* ChangePasswordInput.swift in Sources */, 06B3605F26E15A5E006CB9E4 /* Project+FetchProjectQueryData.swift in Sources */, @@ -8958,7 +8940,6 @@ 06D00FAB26EFA95300E11E38 /* UserFragmentTemplate.swift in Sources */, 77DB532A2215D0AA0078991C /* UserCreditCardsTests.swift in Sources */, D01589A21EEB2ED7006E7684 /* ServiceTypeTests.swift in Sources */, - 606F215C299D3FA900BA5CDF /* GraphAPI.TriggerCapiEventInput+TriggerCapiEventInputTests.swift in Sources */, D0D10C0F1EEB4550005EBAD0 /* LocationTests.swift in Sources */, 194C002E2A68447200621DC3 /* TriggerThirdPartyEventInputTests.swift in Sources */, 06032A8E26CEB3E50013AAB9 /* CommentFragmentTemplate.swift in Sources */, @@ -9029,7 +9010,6 @@ 77FA1AF32445FB810035D659 /* GraphUserTests.swift in Sources */, 066C0AE926CC20490048F4D8 /* SignInWithAppleMutationTemplate.swift in Sources */, D0D10C021EEB4550005EBAD0 /* ActivityTests.swift in Sources */, - 606F216B299E8D8500BA5CDF /* TriggerCapiEventInputTests.swift in Sources */, 06032A9026CEC3290013AAB9 /* FetchUpdateCommentsQueryTemplate.swift in Sources */, D01589A81EEB306D006E7684 /* EncodableTests.swift in Sources */, D0D10C111EEB4550005EBAD0 /* MessageThreadTests.swift in Sources */, diff --git a/KsApi/MockService.swift b/KsApi/MockService.swift index 165af40f7e..84108567cd 100644 --- a/KsApi/MockService.swift +++ b/KsApi/MockService.swift @@ -38,8 +38,6 @@ fileprivate let deletePaymentMethodResult: Result? - fileprivate let triggerCapiEventResult: Result? - fileprivate let triggerThirdPartyEventResult: Result? fileprivate let facebookConnectResponse: User? @@ -224,7 +222,6 @@ changeCurrencyResult: Result? = nil, changePaymentMethodResult: Result? = nil, deletePaymentMethodResult: Result? = nil, - triggerCapiEventResult: Result? = nil, triggerThirdPartyEventResult: Result? = nil, clearUserUnseenActivityResult: Result? = nil, facebookConnectResponse: User? = nil, @@ -345,8 +342,6 @@ self.changePaymentMethodResult = changePaymentMethodResult self.deletePaymentMethodResult = deletePaymentMethodResult - self.triggerCapiEventResult = triggerCapiEventResult - self.triggerThirdPartyEventResult = triggerThirdPartyEventResult self.facebookConnectResponse = facebookConnectResponse @@ -1598,18 +1593,6 @@ return client.performWithResult(mutation: mutation, result: self.deletePaymentMethodResult) } - internal func triggerCapiEventInput(input: TriggerCapiEventInput) - -> SignalProducer { - guard let client = self.apolloClient else { - return .empty - } - - let mutation = GraphAPI - .TriggerCapiEventMutation(input: GraphAPI.TriggerCapiEventInput.from(input)) - - return client.performWithResult(mutation: mutation, result: self.triggerCapiEventResult) - } - internal func triggerThirdPartyEventInput(input: TriggerThirdPartyEventInput) -> ReactiveSwift .SignalProducer { guard let client = self.apolloClient else { diff --git a/KsApi/Service.swift b/KsApi/Service.swift index 78f5f2b9bb..afe59e93cf 100644 --- a/KsApi/Service.swift +++ b/KsApi/Service.swift @@ -106,16 +106,6 @@ public struct Service: ServiceType { .flatMap(CreatePaymentSourceEnvelope.producer(from:)) } - public func triggerCapiEventInput(input: TriggerCapiEventInput) - -> SignalProducer { - return GraphQL.shared.client - .perform(mutation: GraphAPI - .TriggerCapiEventMutation(input: GraphAPI.TriggerCapiEventInput.from(input))) - .flatMap { _ in - SignalProducer(value: EmptyResponseEnvelope()) - } - } - public func triggerThirdPartyEventInput(input: TriggerThirdPartyEventInput) -> SignalProducer { return GraphQL.shared.client diff --git a/KsApi/ServiceType.swift b/KsApi/ServiceType.swift index 4645473461..e18320d00d 100644 --- a/KsApi/ServiceType.swift +++ b/KsApi/ServiceType.swift @@ -47,10 +47,6 @@ public protocol ServiceType { func addImage(file fileURL: URL, toDraft draft: UpdateDraft) -> SignalProducer - /// Sends facebook ad data relevant to the user - func triggerCapiEventInput(input: TriggerCapiEventInput) - -> SignalProducer - /// Sends facebook ad data and/or google analytics data relevant to the user func triggerThirdPartyEventInput(input: TriggerThirdPartyEventInput) -> SignalProducer diff --git a/KsApi/models/graphql/adapters/GraphAPI.TriggerCapiEventInput+TriggerCapiEventInput.swift b/KsApi/models/graphql/adapters/GraphAPI.TriggerCapiEventInput+TriggerCapiEventInput.swift deleted file mode 100644 index bd8ea8e836..0000000000 --- a/KsApi/models/graphql/adapters/GraphAPI.TriggerCapiEventInput+TriggerCapiEventInput.swift +++ /dev/null @@ -1,12 +0,0 @@ -extension GraphAPI.TriggerCapiEventInput { - static func from(_ input: TriggerCapiEventInput) -> GraphAPI.TriggerCapiEventInput { - return GraphAPI.TriggerCapiEventInput( - projectId: input.projectId, - eventName: input.eventName, - externalId: input.externalId, - userEmail: input.userEmail, - appData: input.appData, - customData: input.customData - ) - } -} diff --git a/KsApi/models/graphql/adapters/GraphAPI.TriggerCapiEventInput+TriggerCapiEventInputTests.swift b/KsApi/models/graphql/adapters/GraphAPI.TriggerCapiEventInput+TriggerCapiEventInputTests.swift deleted file mode 100644 index 23f859350b..0000000000 --- a/KsApi/models/graphql/adapters/GraphAPI.TriggerCapiEventInput+TriggerCapiEventInputTests.swift +++ /dev/null @@ -1,28 +0,0 @@ -@testable import KsApi -import XCTest - -class GraphAPI_TriggerCapiEventInput_TriggerCapiEventInputTests: XCTestCase { - func testTriggerCapiEventInputCreation_WithValidData_Success() { - let input = TriggerCapiEventInput( - projectId: "projectId", - eventName: "eventName", - externalId: "externalId", - userEmail: "userEmail", - appData: GraphAPI.AppDataInput( - advertiserTrackingEnabled: true, - applicationTrackingEnabled: true, - extinfo: ["appData"] - ), - customData: GraphAPI.CustomDataInput(currency: nil, value: nil) - ) - - let graphInput = GraphAPI.TriggerCapiEventInput.from(input) - - XCTAssertEqual(graphInput.projectId, input.projectId) - XCTAssertEqual(graphInput.eventName, input.eventName) - XCTAssertEqual(graphInput.externalId, input.externalId) - XCTAssertEqual(graphInput.userEmail, input.userEmail) - XCTAssertNotNil(input.appData) - XCTAssertNotNil(input.customData) - } -} diff --git a/KsApi/mutations/TriggerCapiEvent.graphql b/KsApi/mutations/TriggerCapiEvent.graphql deleted file mode 100644 index 9b62cf1984..0000000000 --- a/KsApi/mutations/TriggerCapiEvent.graphql +++ /dev/null @@ -1,5 +0,0 @@ -mutation triggerCAPIEvent($input: TriggerCapiEventInput!) { - triggerCAPIEvent(input: $input) { - success - } -} diff --git a/KsApi/mutations/inputs/TriggerCapiEventInput.swift b/KsApi/mutations/inputs/TriggerCapiEventInput.swift deleted file mode 100644 index c096198f8c..0000000000 --- a/KsApi/mutations/inputs/TriggerCapiEventInput.swift +++ /dev/null @@ -1,37 +0,0 @@ -import Foundation - -public struct TriggerCapiEventInput: GraphMutationInput { - let projectId: String - let eventName: String - let externalId: String - let userEmail: String? - let appData: GraphAPI.AppDataInput? - let customData: GraphAPI.CustomDataInput? - - public init( - projectId: String, - eventName: String, - externalId: String, - userEmail: String?, - appData: GraphAPI.AppDataInput?, - customData: GraphAPI.CustomDataInput? - ) { - self.projectId = projectId - self.eventName = eventName - self.externalId = externalId - self.userEmail = userEmail - self.appData = appData - self.customData = customData - } - - public func toInputDictionary() -> [String: Any] { - return [ - "projectId": self.projectId, - "eventName": self.eventName, - "externalId": self.externalId, - "userEmail": self.userEmail, - "appData": self.appData, - "customData": self.customData - ] - } -} diff --git a/KsApi/mutations/inputs/TriggerCapiEventInputTests.swift b/KsApi/mutations/inputs/TriggerCapiEventInputTests.swift deleted file mode 100644 index 005e83b4ef..0000000000 --- a/KsApi/mutations/inputs/TriggerCapiEventInputTests.swift +++ /dev/null @@ -1,29 +0,0 @@ -@testable import KsApi -import XCTest - -final class TriggerCapiEventInputTests: XCTestCase { - func testTriggerCapiEventInputTestsDictionary_WithValue_Success() { - let triggerCapiEventInput = - TriggerCapiEventInput( - projectId: "projId", - eventName: "eventName", - externalId: "extId", - userEmail: "userEmail", - appData: GraphAPI.AppDataInput( - advertiserTrackingEnabled: true, - applicationTrackingEnabled: true, - extinfo: ["appData"] - ), - customData: GraphAPI.CustomDataInput(currency: nil, value: nil) - ) - - let input = triggerCapiEventInput.toInputDictionary() - - XCTAssertEqual(input["projectId"] as? String, "projId") - XCTAssertEqual(input["eventName"] as? String, "eventName") - XCTAssertEqual(input["externalId"] as? String, "extId") - XCTAssertEqual(input["userEmail"] as? String, "userEmail") - XCTAssertNotNil(input["appData"]) - XCTAssertNotNil(input["customData"]) - } -} diff --git a/Library/NSBundleType+Tests.swift b/Library/NSBundleType+Tests.swift index 28e409184b..63715ef77d 100644 --- a/Library/NSBundleType+Tests.swift +++ b/Library/NSBundleType+Tests.swift @@ -11,4 +11,9 @@ class NSBundleTests: XCTestCase { let bundle = MockBundle(bundleIdentifier: KickstarterBundleIdentifier.release.rawValue, lang: "en") XCTAssertEqual(bundle.appVersionString, "1.2.3.4.5.6.7.8.9.0") } + + func testPlatformVersionString() { + let bundle = MockBundle(bundleIdentifier: KickstarterBundleIdentifier.release.rawValue, lang: "en") + XCTAssertEqual(bundle.platformVersion, "16") + } } diff --git a/Library/NSBundleType.swift b/Library/NSBundleType.swift index bb13f7d4f1..666760b5df 100644 --- a/Library/NSBundleType.swift +++ b/Library/NSBundleType.swift @@ -50,6 +50,10 @@ extension NSBundleType { return "\(versionString)\(build)" } + public var platformVersion: String { + return self.infoDictionary?["DTPlatformVersion"] as? String ?? "Unknown" + } + public var isDebug: Bool { return self.identifier == KickstarterBundleIdentifier.debug.rawValue } diff --git a/Library/TestHelpers/MockBundle.swift b/Library/TestHelpers/MockBundle.swift index e0da55b054..c1992794fb 100644 --- a/Library/TestHelpers/MockBundle.swift +++ b/Library/TestHelpers/MockBundle.swift @@ -71,6 +71,7 @@ internal struct MockBundle: NSBundleType { result["CFBundleIdentifier"] = self.bundleIdentifier result["CFBundleVersion"] = "1234567890" result["CFBundleShortVersionString"] = "1.2.3.4.5.6.7.8.9.0" + result["DTPlatformVersion"] = "16" return result } } diff --git a/Library/Tracking/FacebookCAPIEventName.swift b/Library/Tracking/ThirdPartyEventInputName.swift similarity index 88% rename from Library/Tracking/FacebookCAPIEventName.swift rename to Library/Tracking/ThirdPartyEventInputName.swift index 529afce21a..301aef93de 100644 --- a/Library/Tracking/FacebookCAPIEventName.swift +++ b/Library/Tracking/ThirdPartyEventInputName.swift @@ -1,7 +1,7 @@ import Foundation import KsApi -public enum FacebookCAPIEventName: String { +public enum ThirdPartyEventInputName: String { /// viewing a project page case ProjectPageViewed = "ViewContent" /// viewing the reward selection screen diff --git a/Library/ViewModels/PledgePaymentMethodsViewModel.swift b/Library/ViewModels/PledgePaymentMethodsViewModel.swift index 67d11951d4..9b5ee8d0de 100644 --- a/Library/ViewModels/PledgePaymentMethodsViewModel.swift +++ b/Library/ViewModels/PledgePaymentMethodsViewModel.swift @@ -357,36 +357,48 @@ public final class PledgePaymentMethodsViewModel: PledgePaymentMethodsViewModelT return indexPath } - // FB CAPI + // Facebook CAPI + Google Analytics let stripePaymentSheetDidAppear = self.stripePaymentSheetDidAppearProperty.signal _ = Signal.combineLatest(project, self.viewDidLoadProperty.signal) .takeWhen(stripePaymentSheetDidAppear) .observeValues { project, _ in - guard project.sendMetaCapiEvents else { return } AppEnvironment.current.appTrackingTransparency.updateAdvertisingIdentifier() guard let externalId = AppEnvironment.current.appTrackingTransparency.advertisingIdentifier else { return } - /** FIXME: Soon we will use `triggerThirdPartyEvents` mutation paired with an in-app flag for allowing an advertising identifier to be sent even if it isn't nil. That will affect `applicationTrackingEnabled` and `advertiserTrackingEnabled`. */ + var userId = "" + + if let userValue = AppEnvironment.current.currentUser { + userId = "\(userValue.id)" + } + + let projectId = "\(project.id)" + + var extInfo = Array(repeating: "", count: 16) + extInfo[0] = "i2" + extInfo[4] = AppEnvironment.current.mainBundle.platformVersion _ = AppEnvironment .current .apiService - .triggerCapiEventInput( + .triggerThirdPartyEventInput( input: .init( - projectId: "\(project.id)", - eventName: FacebookCAPIEventName.AddNewPaymentMethod.rawValue, - externalId: externalId, - userEmail: AppEnvironment.current.currentUserEmail, + deviceId: externalId, + eventName: ThirdPartyEventInputName.AddNewPaymentMethod.rawValue, + projectId: projectId, + pledgeAmount: nil, + shipping: nil, + transactionId: nil, + userId: userId, appData: .init( advertiserTrackingEnabled: true, applicationTrackingEnabled: true, - extinfo: ["i2"] + extinfo: extInfo ), - customData: .init(currency: nil, value: nil) + clientMutationId: "" ) ) } diff --git a/Library/ViewModels/PledgePaymentMethodsViewModelTests.swift b/Library/ViewModels/PledgePaymentMethodsViewModelTests.swift index 7c48345926..3662c87084 100644 --- a/Library/ViewModels/PledgePaymentMethodsViewModelTests.swift +++ b/Library/ViewModels/PledgePaymentMethodsViewModelTests.swift @@ -15,7 +15,6 @@ final class PledgePaymentMethodsViewModelTests: TestCase { private let goToProject = TestObserver() private let notifyDelegateCreditCardSelected = TestObserver() private let notifyDelegateLoadPaymentMethodsError = TestObserver() - private let notifyFacebookCAPIUserEmail = TestObserver() private let reloadPaymentMethodsCards = TestObserver<[UserCreditCards.CreditCard], Never>() private let reloadPaymentSheetPaymentMethodsCards = TestObserver< diff --git a/Library/ViewModels/ProjectPageViewModel.swift b/Library/ViewModels/ProjectPageViewModel.swift index 196b346ca1..78bd17f742 100644 --- a/Library/ViewModels/ProjectPageViewModel.swift +++ b/Library/ViewModels/ProjectPageViewModel.swift @@ -372,36 +372,46 @@ public final class ProjectPageViewModel: ProjectPageViewModelType, ProjectPageVi ) } - // FB CAPI - + // Facebook CAPI + Google Analytics trackFreshProjectAndRefTagViewed .observeValues { projectAndRefTag in let (project, _) = projectAndRefTag - guard project.sendMetaCapiEvents else { return } - AppEnvironment.current.appTrackingTransparency.updateAdvertisingIdentifier() guard let externalId = AppEnvironment.current.appTrackingTransparency.advertisingIdentifier else { return } - /** FIXME: Soon we will use `triggerThirdPartyEvents` mutation paired with an in-app flag for allowing an advertising identifier to be sent even if it isn't nil. That will affect `applicationTrackingEnabled` and `advertiserTrackingEnabled`. */ + var userId = "" + + if let userValue = AppEnvironment.current.currentUser { + userId = "\(userValue.id)" + } + + let projectId = "\(project.id)" + + var extInfo = Array(repeating: "", count: 16) + extInfo[0] = "i2" + extInfo[4] = AppEnvironment.current.mainBundle.platformVersion _ = AppEnvironment .current .apiService - .triggerCapiEventInput( + .triggerThirdPartyEventInput( input: .init( - projectId: "\(project.id)", - eventName: FacebookCAPIEventName.ProjectPageViewed.rawValue, - externalId: externalId, - userEmail: AppEnvironment.current.currentUserEmail, + deviceId: externalId, + eventName: ThirdPartyEventInputName.ProjectPageViewed.rawValue, + projectId: projectId, + pledgeAmount: nil, + shipping: nil, + transactionId: nil, + userId: userId, appData: .init( advertiserTrackingEnabled: true, applicationTrackingEnabled: true, - extinfo: ["i2"] + extinfo: extInfo ), - customData: .init(currency: nil, value: nil) + clientMutationId: "" ) ) } diff --git a/Library/ViewModels/RewardsCollectionViewModel.swift b/Library/ViewModels/RewardsCollectionViewModel.swift index 430b9a8809..1fbe53654b 100644 --- a/Library/ViewModels/RewardsCollectionViewModel.swift +++ b/Library/ViewModels/RewardsCollectionViewModel.swift @@ -229,36 +229,46 @@ public final class RewardsCollectionViewModel: RewardsCollectionViewModelType, ) } - // FB CAPI - + // Facebook CAPI + Google Analytics _ = Signal.combineLatest(project, self.viewDidAppearProperty.signal.ignoreValues()) .observeValues { projectAndRefTag in let (project, _) = projectAndRefTag - guard project.sendMetaCapiEvents else { return } - AppEnvironment.current.appTrackingTransparency.updateAdvertisingIdentifier() guard let externalId = AppEnvironment.current.appTrackingTransparency.advertisingIdentifier else { return } - /** FIXME: Soon we will use `triggerThirdPartyEvents` mutation paired with an in-app flag for allowing an advertising identifier to be sent even if it isn't nil. That will affect `applicationTrackingEnabled` and `advertiserTrackingEnabled`. */ + var userId = "" + + if let userValue = AppEnvironment.current.currentUser { + userId = "\(userValue.id)" + } + + let projectId = "\(project.id)" + + var extInfo = Array(repeating: "", count: 16) + extInfo[0] = "i2" + extInfo[4] = AppEnvironment.current.mainBundle.platformVersion _ = AppEnvironment .current .apiService - .triggerCapiEventInput( + .triggerThirdPartyEventInput( input: .init( - projectId: "\(project.id)", - eventName: FacebookCAPIEventName.RewardSelectionViewed.rawValue, - externalId: externalId, - userEmail: AppEnvironment.current.currentUserEmail, + deviceId: externalId, + eventName: ThirdPartyEventInputName.RewardSelectionViewed.rawValue, + projectId: projectId, + pledgeAmount: nil, + shipping: nil, + transactionId: nil, + userId: userId, appData: .init( advertiserTrackingEnabled: true, applicationTrackingEnabled: true, - extinfo: ["i2"] + extinfo: extInfo ), - customData: .init(currency: nil, value: nil) + clientMutationId: "" ) ) } diff --git a/Library/ViewModels/ThanksViewModel.swift b/Library/ViewModels/ThanksViewModel.swift index 680c1ee0d4..bbcd8ea2d3 100644 --- a/Library/ViewModels/ThanksViewModel.swift +++ b/Library/ViewModels/ThanksViewModel.swift @@ -198,47 +198,57 @@ public final class ThanksViewModel: ThanksViewModelType, ThanksViewModelInputs, checkoutData: $0.checkoutData ) } - // FB CAPI - + // Facebook CAPI + Google Analytics _ = Signal.combineLatest( project, self.configureWithDataProperty.signal.skipNil() ) .observeValues { project, configData in - var checkoutUSDAmount = "" + var pledgeAmount: Double? + var shipping: Double? + var transactionId: String? if let checkoutDataValues = configData.checkoutData { - checkoutUSDAmount = "\(checkoutDataValues.revenueInUsd)" + "\(checkoutDataValues.addOnsMinimumUsd)" - checkoutUSDAmount += String(describing: checkoutDataValues.shippingAmountUsd) - checkoutUSDAmount += String(describing: checkoutDataValues.bonusAmountInUsd) + transactionId = checkoutDataValues.checkoutId + shipping = checkoutDataValues.shippingAmountUsd + pledgeAmount = NSDecimalNumber(decimal: checkoutDataValues.revenueInUsd).doubleValue + + NSDecimalNumber(decimal: checkoutDataValues.bonusAmountInUsd ?? 0).doubleValue + + checkoutDataValues.addOnsMinimumUsd } - guard project.sendMetaCapiEvents else { return } - AppEnvironment.current.appTrackingTransparency.updateAdvertisingIdentifier() guard let externalId = AppEnvironment.current.appTrackingTransparency.advertisingIdentifier else { return } - /** FIXME: Soon we will use `triggerThirdPartyEvents` mutation paired with an in-app flag for allowing an advertising identifier to be sent even if it isn't nil. That will affect `applicationTrackingEnabled` and `advertiserTrackingEnabled`. */ - - _ = AppEnvironment - .current - .apiService - .triggerCapiEventInput( - input: .init( - projectId: "\(project.id)", - eventName: FacebookCAPIEventName.BackingComplete.rawValue, - externalId: externalId, - userEmail: AppEnvironment.current.currentUserEmail, - appData: .init( - advertiserTrackingEnabled: true, - applicationTrackingEnabled: true, - extinfo: ["i2"] - ), - customData: .init(currency: Currency.USD.rawValue, value: checkoutUSDAmount) - ) - ) + var userId = "" + + if let userValue = AppEnvironment.current.currentUser { + userId = "\(userValue.id)" + } + + let projectId = "\(project.id)" + + var extInfo = Array(repeating: "", count: 16) + extInfo[0] = "i2" + extInfo[4] = AppEnvironment.current.mainBundle.platformVersion + + _ = AppEnvironment.current.apiService + .triggerThirdPartyEventInput(input: .init( + deviceId: externalId, + eventName: ThirdPartyEventInputName.BackingComplete.rawValue, + projectId: projectId, + pledgeAmount: pledgeAmount, + shipping: shipping, + transactionId: transactionId, + userId: userId, + appData: .init( + advertiserTrackingEnabled: true, + applicationTrackingEnabled: true, + extinfo: extInfo + ), + clientMutationId: "" + )) } }