mirror of
https://github.com/RevenueCat/purchases-ios
synced 2026-11-11 22:55:55 +05:45
* enable force_unwrapping * avoid force unwrap * fixed all errors * remove extra disable
210 lines
6.7 KiB
Swift
210 lines
6.7 KiB
Swift
//
|
|
// 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
|
|
//
|
|
// PaywallComponentsData.swift
|
|
//
|
|
// Created by Josh Holtz on 11/11/24.
|
|
// swiftlint:disable identifier_name missing_docs
|
|
|
|
import Foundation
|
|
|
|
public struct PaywallComponentsData: Codable, Equatable, Sendable {
|
|
|
|
public struct ComponentsConfig: Codable, Equatable, Sendable {
|
|
|
|
public var base: PaywallComponentsConfig
|
|
|
|
public init(base: PaywallComponentsConfig) {
|
|
self.base = base
|
|
}
|
|
|
|
}
|
|
|
|
public struct PaywallComponentsConfig: Codable, Equatable, Sendable {
|
|
|
|
public var stack: PaywallComponent.StackComponent
|
|
public let stickyFooter: PaywallComponent.StickyFooterComponent?
|
|
public var background: PaywallComponent.Background
|
|
|
|
public init(
|
|
stack: PaywallComponent.StackComponent,
|
|
stickyFooter: PaywallComponent.StickyFooterComponent?,
|
|
background: PaywallComponent.Background
|
|
) {
|
|
self.stack = stack
|
|
self.stickyFooter = stickyFooter
|
|
self.background = background
|
|
}
|
|
|
|
}
|
|
|
|
public enum LocalizationData: Codable, Equatable, Sendable {
|
|
case string(String), image(PaywallComponent.ThemeImageUrls)
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
let container = try decoder.singleValueContainer()
|
|
if let stringValue = try? container.decode(String.self) {
|
|
self = .string(stringValue)
|
|
} else if let imageValue = try? container.decode(PaywallComponent.ThemeImageUrls.self) {
|
|
self = .image(imageValue)
|
|
} else {
|
|
throw DecodingError.typeMismatch(
|
|
LocalizationData.self,
|
|
DecodingError.Context(codingPath: decoder.codingPath,
|
|
debugDescription: "Wrong type for LocalizationData")
|
|
)
|
|
}
|
|
}
|
|
|
|
public func encode(to encoder: Encoder) throws {
|
|
var container = encoder.singleValueContainer()
|
|
switch self {
|
|
case .string(let stringValue):
|
|
try container.encode(stringValue)
|
|
case .image(let imageValue):
|
|
try container.encode(imageValue)
|
|
}
|
|
}
|
|
}
|
|
|
|
public var templateName: String
|
|
|
|
/// The base remote URL where assets for this paywall are stored.
|
|
public var assetBaseURL: URL
|
|
|
|
/// The revision identifier for this paywall.
|
|
public var revision: Int {
|
|
get { return self._revision }
|
|
set { self._revision = newValue }
|
|
}
|
|
|
|
public var componentsConfig: ComponentsConfig
|
|
public var componentsLocalizations: [PaywallComponent.LocaleID: PaywallComponent.LocalizationDictionary]
|
|
public var defaultLocale: String
|
|
|
|
@DefaultDecodable.Zero
|
|
internal private(set) var _revision: Int = 0
|
|
|
|
public var errorInfo: [String: EquatableError]?
|
|
|
|
private enum CodingKeys: String, CodingKey {
|
|
case templateName
|
|
case componentsConfig
|
|
case componentsLocalizations
|
|
case defaultLocale
|
|
case assetBaseURL = "assetBaseUrl"
|
|
case _revision = "revision"
|
|
}
|
|
|
|
public init(templateName: String,
|
|
assetBaseURL: URL,
|
|
componentsConfig: ComponentsConfig,
|
|
componentsLocalizations: [PaywallComponent.LocaleID: PaywallComponent.LocalizationDictionary],
|
|
revision: Int,
|
|
defaultLocaleIdentifier: String) {
|
|
self.templateName = templateName
|
|
self.assetBaseURL = assetBaseURL
|
|
self.componentsConfig = componentsConfig
|
|
self.componentsLocalizations = componentsLocalizations
|
|
self._revision = revision
|
|
self.defaultLocale = defaultLocaleIdentifier
|
|
}
|
|
|
|
}
|
|
|
|
extension PaywallComponentsData {
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
var errors: [String: EquatableError] = [:]
|
|
|
|
do {
|
|
templateName = try container.decode(String.self, forKey: .templateName)
|
|
} catch {
|
|
errors["templateName"] = .init(error)
|
|
templateName = ""
|
|
}
|
|
|
|
do {
|
|
assetBaseURL = try container.decode(URL.self, forKey: .assetBaseURL)
|
|
} catch {
|
|
errors["assetBaseURL"] = .init(error)
|
|
// swiftlint:disable:next force_unwrapping
|
|
assetBaseURL = URL(string: "https://example.com")!
|
|
}
|
|
|
|
do {
|
|
componentsConfig = try container.decode(ComponentsConfig.self, forKey: .componentsConfig)
|
|
} catch {
|
|
errors["componentsConfig"] = .init(error)
|
|
componentsConfig = ComponentsConfig(base: PaywallComponentsConfig(
|
|
stack: .init(components: []),
|
|
stickyFooter: nil,
|
|
background: .color(.init(light: .hex("#ffffff")))
|
|
))
|
|
}
|
|
|
|
do {
|
|
componentsLocalizations = try container.decode(
|
|
[PaywallComponent.LocaleID: PaywallComponent.LocalizationDictionary].self,
|
|
forKey: .componentsLocalizations
|
|
)
|
|
} catch {
|
|
errors["componentsLocalizations"] = .init(error)
|
|
componentsLocalizations = [:]
|
|
}
|
|
|
|
do {
|
|
defaultLocale = try container.decode(String.self, forKey: .defaultLocale)
|
|
} catch {
|
|
errors["defaultLocale"] = .init(error)
|
|
defaultLocale = "en"
|
|
}
|
|
|
|
do {
|
|
_revision = try container.decode(Int.self, forKey: ._revision)
|
|
} catch {
|
|
errors["_revision"] = .init(error)
|
|
_revision = 0
|
|
}
|
|
|
|
if !errors.isEmpty {
|
|
errorInfo = errors
|
|
}
|
|
}
|
|
|
|
public func encode(to encoder: Encoder) throws {
|
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
|
|
try container.encode(templateName, forKey: .templateName)
|
|
try container.encode(assetBaseURL, forKey: .assetBaseURL)
|
|
try container.encode(componentsConfig, forKey: .componentsConfig)
|
|
try container.encode(componentsLocalizations, forKey: .componentsLocalizations)
|
|
try container.encode(defaultLocale, forKey: .defaultLocale)
|
|
try container.encode(_revision, forKey: ._revision)
|
|
}
|
|
|
|
}
|
|
|
|
extension PaywallComponentsData {
|
|
|
|
public struct EquatableError: Equatable, Sendable {
|
|
let description: String
|
|
|
|
init(_ error: Error) {
|
|
self.description = String(describing: error)
|
|
}
|
|
|
|
public static func == (lhs: EquatableError, rhs: EquatableError) -> Bool {
|
|
return lhs.description == rhs.description
|
|
}
|
|
}
|
|
|
|
}
|