-
Notifications
You must be signed in to change notification settings - Fork 330
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
Paywalls
: initial configuration types
#2780
Changes from all commits
36ff37e
31f1152
cf7a920
0143196
f6067bb
96e9898
fb95238
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
// | ||
// Copyright RevenueCat Inc. All Rights Reserved. | ||
// | ||
// Licensed under the MIT License (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://opensource.org/licenses/MIT | ||
// | ||
// PaywallData.swift | ||
// | ||
// Created by Nacho Soto on 7/10/23. | ||
|
||
import Foundation | ||
|
||
/// The data necessary to display a paywall using the `RevenueCatUI` library. | ||
/// They can be created and configured in the dashboard, then access from ``Offering/paywall``. | ||
public struct PaywallData { | ||
|
||
/// The type of template used to display this paywall. | ||
public var template: PaywallTemplate | ||
|
||
/// Generic configuration for any paywall. | ||
public var config: Configuration | ||
|
||
fileprivate var defaultLocaleIdentifier: String | ||
fileprivate var localization: [String: LocalizedConfiguration] | ||
|
||
} | ||
|
||
extension PaywallData { | ||
|
||
/// Configuration containing values for the necessary `Locale`s. | ||
public struct LocalizedConfiguration { | ||
|
||
/// The content of the main action button for purchasing a subscription. | ||
public let callToAction: String | ||
/// The title of the paywall screen. | ||
public let title: String | ||
|
||
/// swiftlint:disable:next missing_docs | ||
public init(callToAction: String, title: String) { | ||
self.callToAction = callToAction | ||
self.title = title | ||
} | ||
|
||
} | ||
|
||
/// - Returns: ``PaywallData/LocalizedConfiguration-swift.struct`` for the given `Locale`, if found. | ||
public func config(for locale: Locale) -> LocalizedConfiguration? { | ||
return self.localization[locale.identifier] | ||
} | ||
|
||
/// The default `Locale` used if `Locale.current` is not configured for this paywall. | ||
public var defaultLocale: Locale { | ||
return .init(identifier: self.defaultLocaleIdentifier) | ||
} | ||
|
||
/// - Returns: the ``PaywallData/LocalizedConfiguration-swift.struct`` associated to the current `Locale` | ||
/// or the configuration associated to ``defaultLocale``. | ||
public var localizedConfiguration: LocalizedConfiguration { | ||
return self.config(for: Locale.current) ?? self.defaultLocalizedConfiguration | ||
} | ||
|
||
private var defaultLocalizedConfiguration: LocalizedConfiguration { | ||
let defaultLocale = self.defaultLocale | ||
|
||
guard let result = self.config(for: defaultLocale) else { | ||
fatalError( | ||
"Corrupted data. Expected to find locale \(defaultLocale.identifier) " + | ||
"in locales: \(Set(self.localization.keys))" | ||
) | ||
} | ||
|
||
return result | ||
} | ||
|
||
} | ||
|
||
extension PaywallData { | ||
|
||
/// Generic configuration for any paywall. | ||
public struct Configuration { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is empty for now. |
||
|
||
// swiftlint:disable:next missing_docs | ||
public init() {} | ||
|
||
} | ||
|
||
} | ||
|
||
// MARK: - Constructors | ||
|
||
extension PaywallData { | ||
|
||
init( | ||
template: PaywallTemplate, | ||
config: Configuration, | ||
defaultLocale: String, | ||
localization: [String: LocalizedConfiguration] | ||
) { | ||
self.template = template | ||
self.config = config | ||
self.defaultLocaleIdentifier = defaultLocale | ||
self.localization = localization | ||
} | ||
|
||
/// Creates a test ``PaywallData`` with one localization | ||
public init( | ||
template: PaywallTemplate, | ||
config: Configuration, | ||
localization: LocalizedConfiguration | ||
) { | ||
let locale = Locale.current.identifier | ||
|
||
self.init( | ||
template: template, | ||
config: config, | ||
defaultLocale: locale, | ||
localization: [locale: localization] | ||
) | ||
} | ||
|
||
} | ||
|
||
// MARK: - Codable | ||
|
||
extension PaywallData.LocalizedConfiguration: Codable { | ||
|
||
private enum CodingKeys: String, CodingKey { | ||
case callToAction = "cta" | ||
case title | ||
} | ||
|
||
} | ||
extension PaywallData.Configuration: Codable {} | ||
extension PaywallData: Codable { | ||
|
||
// Note: these are camel case but converted by the decoder | ||
private enum CodingKeys: String, CodingKey { | ||
case template = "templateName" | ||
case defaultLocaleIdentifier = "defaultLocale" | ||
case config | ||
case localization = "localizedStrings" | ||
} | ||
|
||
} | ||
|
||
// MARK: - Equatable | ||
|
||
extension PaywallData.LocalizedConfiguration: Equatable {} | ||
extension PaywallData.Configuration: Equatable {} | ||
extension PaywallData: Equatable {} | ||
|
||
// MARK: - Sendable | ||
|
||
extension PaywallData.LocalizedConfiguration: Sendable {} | ||
extension PaywallData.Configuration: Sendable {} | ||
extension PaywallData: Sendable {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// | ||
// Copyright RevenueCat Inc. All Rights Reserved. | ||
// | ||
// Licensed under the MIT License (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://opensource.org/licenses/MIT | ||
// | ||
// PaywallTemplate.swift | ||
// | ||
// Created by Nacho Soto on 7/10/23. | ||
|
||
import Foundation | ||
|
||
/// The type of template used to display a paywall. | ||
public enum PaywallTemplate: String { | ||
|
||
/// swiftlint:disable:next missing_docs | ||
case example1 = "sample_1" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will obviously change, just a placeholder. |
||
|
||
} | ||
|
||
extension PaywallTemplate: Codable {} | ||
extension PaywallTemplate: Sendable {} | ||
extension PaywallTemplate: Equatable {} | ||
extension PaywallTemplate: CaseIterable {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ | |
@implementation RCOfferingAPI | ||
|
||
+ (void)checkAPI { | ||
RCOffering *o = nil; // No public initializer. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We didn't update this when we exposed it for |
||
RCOffering *o = nil; | ||
NSString *i = o.identifier; | ||
NSString *sd = o.serverDescription; | ||
NSArray<RCPackage *> *a = o.availablePackages; | ||
|
@@ -34,6 +34,11 @@ + (void)checkAPI { | |
RCPackage *ok = [o objectForKeyedSubscript:@""]; | ||
NSDictionary<NSString *, id> *md = o.metadata; | ||
|
||
o = [[RCOffering alloc] initWithIdentifier:@"" | ||
serverDescription:@"" | ||
metadata:@{} | ||
availablePackages:a]; | ||
|
||
NSLog(o, i, sd, a, l, an, s, t, tm, m, w, p, ok, md); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Important that we don't fail to load the offering if this fails. The error will get logged with #2778
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1000. At least for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should fail at the Paywalls SDK level though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what I'm thinking:
With the
public
PaywallData
constructor, users could to this: