Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Paywall events so it can be used for customer center #4376

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

vegaro
Copy link
Contributor

@vegaro vegaro commented Oct 17, 2024

We want to reuse Paywall events for Customer Center, the issue is that the Paywall events system is very types and requires PaywallEvents to be passed around.

Customer Center events will have different properties than Paywalls events, so we need a way to "untype" the code so it stores and posts events of any type.

After some attempts, I figured that if we just stores AnyEncodable and if we post AnyEncodable we can keep storing and posting paywall events the same way, and also create new Customer Center events without being constrained by paywall events types.

@vegaro vegaro force-pushed the https/linear.app/revenuecat/issue/SDK-3607/create-customer-center-open-event branch 3 times, most recently from 9ce8a40 to e02864e Compare October 21, 2024 16:39
return nil
}
return AnyEncodable(event)
})
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is going to be a case .customerCenter here, that will create a CustomerCenterEventRequest.Event

(In another PR)

}

}

extension PaywallEventsRequest {
protocol FeatureEvent: Encodable {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CustomerCenterEventRequest.Event will also conform to this

// This is a `struct` instead of `enum` so that
// we can use make it conform to Encodable
// swiftlint:disable:next convenience_type
struct PaywallEventRequest {

enum EventType: String {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This used to be part of the PaywallEventsRequest but we now need to have different EventType for PaywallEventRequest and CustomerCenterRequest

@@ -16,20 +16,39 @@ import Foundation
/// The content of a request to the events endpoints.
struct PaywallEventsRequest {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought about renaming this, but we are still using the api-paywalls to post all type of events. So I am not sure. I thought about renaming to FeatureEventsRequest

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I think we should rename it or it would be very confusing down the line, and maybe just keep using the old endpoint for now, (or even alias to a new endpoint name in the backend and deprecate the old one... But that can come in a separate PR.

@@ -40,9 +40,14 @@ internal actor PaywallEventStore: PaywallEventStoreType {

func store(_ storedEvent: PaywallStoredEvent) async {
do {
Logger.verbose(PaywallEventStoreStrings.storing_event(storedEvent.event))
if let eventDescription = try? storedEvent.event.prettyPrintedJSON {
Logger.verbose(PaywallEventStoreStrings.storing_event(eventDescription))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improved the logging a bit so it's easier to see what's being stored

@vegaro vegaro force-pushed the https/linear.app/revenuecat/issue/SDK-3607/create-customer-center-open-event branch from e02864e to ec57fbe Compare October 21, 2024 16:43
@vegaro vegaro force-pushed the https/linear.app/revenuecat/issue/SDK-3607/create-customer-center-open-event branch from 79779b0 to 72e8bfd Compare October 23, 2024 13:21
@vegaro vegaro marked this pull request as ready for review October 23, 2024 13:21
@vegaro vegaro requested a review from a team October 23, 2024 13:21
Copy link
Contributor

@tonidero tonidero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm mostly concerned about the naming being confusing... not sure if we should perform some renames now or maybe delay it for later.

@@ -16,20 +16,39 @@ import Foundation
/// The content of a request to the events endpoints.
struct PaywallEventsRequest {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I think we should rename it or it would be very confusing down the line, and maybe just keep using the old endpoint for now, (or even alias to a new endpoint name in the backend and deprecate the old one... But that can come in a separate PR.

init?(storedEvent: PaywallStoredEvent) {
guard let eventData = storedEvent.event.value as? [String: Any],
let paywallEvent: PaywallEvent = try? JSONDecoder.default.decode(dictionary: eventData) else {
return nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we log something in this case? It should ideally never happen.

// This is a `struct` instead of `enum` so that
// we can use make it conform to Encodable
// swiftlint:disable:next convenience_type
struct PaywallEventRequest {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I'm wondering... this is not actually a request (which is PaywallEventsRequest), but a single event... I was wondering whether to rename to PaywallEvent.Event or soemthing along those lines? Not sure... I think it's a bit confusing right now...

@vegaro
Copy link
Contributor Author

vegaro commented Oct 24, 2024

@tonidero agree on the naming concerns. Let me give them more thought

@vegaro vegaro requested a review from tonidero October 24, 2024 09:28
Copy link
Contributor

@tonidero tonidero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the decodable stuff still confuses me a bit but I think it makes sense. Just a few questions to make sure I didn't miss something!

}

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
init(events: [PaywallStoredEvent]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess ideally we also do the rename for PaywallStoredEvent to something more generic that can include customer center/other features... But that can come in a separate PR I think

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh right, good point


self.event = try container.decode(AnyEncodable.self, forKey: .event)
self.userID = try container.decode(String.self, forKey: .userID)
self.feature = try container.decodeIfPresent(Feature.self, forKey: .feature) ?? .paywalls
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would we need to handle unknown feature types here? As in, just making sure that if there is a value, and it's unknown it won't throw an exception and just default to .paywalls.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't it go to ?? .paywalls? Or maybe we need to try? yes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think we might need to use “try?”

struct PaywallStoredEvent {

var event: PaywallEvent
var event: AnyEncodable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small concern I have over this... If for some reason the event is written partially (say that during the write it crashed or something), this won't catch it and try to send everything? Or would at least fail if it's not a valid structure?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants