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

[WIP] Separate ReceiptParser into SPM #2062

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ excluded:
- scan_derived_data
- .git
- .build
- Packages/*/.build

opt_in_rules:
- sorted_imports
Expand All @@ -19,7 +20,9 @@ opt_in_rules:
custom_rules:
xctestcase_superclass:
included: ".*\\.swift"
excluded: Tests/BackendIntegrationTests
excluded:
- Tests/BackendIntegrationTests
- Packages
regex: "\\: XCTestCase \\{"
name: "XCTestCase Superclass"
message: "Test classes must inherit `TestCase` instead."
Expand Down
7 changes: 7 additions & 0 deletions .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 27 additions & 18 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,20 @@
import PackageDescription
import class Foundation.ProcessInfo

func resolveTargets() -> [Target] {
let baseTargets: [Target] = [
.target(name: "RevenueCat",
path: "Sources",
exclude: ["Info.plist"])
]
let dependencies: [Package.Dependency] = {
// Only add DocC Plugin when building docs, so that clients of this library won't
// unnecessarily also get the DocC Plugin
let environmentVariables = ProcessInfo.processInfo.environment
let shouldIncludeDocCPlugin = environmentVariables["INCLUDE_DOCC_PLUGIN"] == "true"

return baseTargets
}
var result: [Package.Dependency] = []

// Only add DocC Plugin when building docs, so that clients of this library won't
// unnecessarily also get the DocC Plugin
let environmentVariables = ProcessInfo.processInfo.environment
let shouldIncludeDocCPlugin = environmentVariables["INCLUDE_DOCC_PLUGIN"] == "true"
if shouldIncludeDocCPlugin {
result.append(.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"))
}

var dependencies: [Package.Dependency] = []
if shouldIncludeDocCPlugin {
dependencies.append(.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"))
}
return result
}()

let package = Package(
name: "RevenueCat",
Expand All @@ -34,8 +29,22 @@ let package = Package(
],
products: [
.library(name: "RevenueCat",
targets: ["RevenueCat"])
targets: ["RevenueCat"]),
.library(name: "ReceiptParser",
type: .static,
targets: ["ReceiptParser"])
],
dependencies: dependencies,
targets: resolveTargets()
targets: [
.target(name: "RevenueCat",
dependencies: [.byName(name: "ReceiptParser")],
Copy link
Member

Choose a reason for hiding this comment

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

In my experience, this will complicate things quite a bit.
It's a total headache to manage imports from a local package, we had something like this back in the objc days with PurchasesCoreSwift and it broke hybrids in all sorts of ways.

I think we should just have these two be independent packages, which just happen to have the same files.
If you use RC, you don't need the ReceiptParser package. If you use the ReceiptParser package, and you want to move to the full RevenueCat, you need to remove ReceiptParser and replace it with RevenueCat.

Copy link
Member

Choose a reason for hiding this comment

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

One bummer with this is that SPM from Xcode might prompt you to install both by default, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we should just have these two be independent packages, which just happen to have the same files.

That's a great idea, which will simplify this tremendously.
I wanted to have a call with you to discuss the approach, but thanks for providing the best path forward already :D

Copy link
Member

Choose a reason for hiding this comment

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

happy to chat about it whenever!

path: "Sources",
exclude: ["Info.plist"]),
.target(name: "ReceiptParser",
dependencies: [],
path: "Packages/ReceiptParser/Sources/ReceiptParser",
swiftSettings: [
.unsafeFlags(["-enable-library-evolution"])
])
]
)
9 changes: 9 additions & 0 deletions Packages/ReceiptParser/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/
DerivedData/
.swiftpm/config/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1410"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "ReceiptParser"
BuildableName = "ReceiptParser"
BlueprintName = "ReceiptParser"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES"
testExecutionOrdering = "random">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "ReceiptParserTests"
BuildableName = "ReceiptParserTests"
BlueprintName = "ReceiptParserTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "ReceiptParser"
BuildableName = "ReceiptParser"
BlueprintName = "ReceiptParser"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
36 changes: 36 additions & 0 deletions Packages/ReceiptParser/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// swift-tools-version: 5.5
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "ReceiptParser",
platforms: [
.macOS(.v10_13),
.watchOS("6.2"),
.tvOS(.v11),
.iOS(.v11)
],
products: [
.library(
name: "ReceiptParser",
type: .static,
targets: ["ReceiptParser"])
],
dependencies: [
.package(url: "git@github.com:Quick/Nimble.git", from: "10.0.0")
],
targets: [
.target(
name: "ReceiptParser",
dependencies: [],
swiftSettings: [
.unsafeFlags(["-enable-library-evolution"])
]
),
.testTarget(
name: "ReceiptParserTests",
dependencies: ["ReceiptParser", "Nimble"]
)
]
)
3 changes: 3 additions & 0 deletions Packages/ReceiptParser/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# ReceiptParser

A description of this package.
28 changes: 28 additions & 0 deletions Packages/ReceiptParser/ReceiptParser.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Pod::Spec.new do |s|
s.name = "ReceiptParser"
s.version = "4.15.0-SNAPSHOT"
s.summary = "TODO"

s.description = <<-DESC
TODO https://www.revenuecat.com/
DESC

s.homepage = "https://www.revenuecat.com/"
s.license = { :type => 'MIT' }
s.author = { "RevenueCat, Inc." => "support@revenuecat.com" }
s.source = { :git => "https://github.com/revenuecat/purchases-ios.git", :tag => s.version.to_s }
s.documentation_url = "https://docs.revenuecat.com/" # TODO ?

s.framework = 'StoreKit'
s.swift_version = '5.5'

s.ios.deployment_target = '11.0'
s.watchos.deployment_target = '6.2'
s.tvos.deployment_target = '11.0'
s.osx.deployment_target = '10.13'

s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }

s.source_files = 'Sources/**/*.swift'

end
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ import Foundation
// swiftlint:disable nesting

/// The contents of a parsed IAP receipt.
struct AppleReceipt: Equatable {
public struct AppleReceipt: Equatable {

// swiftlint:disable:next line_length
// https://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html
struct Attribute {
public struct Attribute {

enum AttributeType: Int {
public enum AttributeType: Int {

case bundleId = 2,
applicationVersion = 3,
Expand All @@ -36,22 +36,22 @@ struct AppleReceipt: Equatable {

}

let type: AttributeType
let version: Int
let value: String
public let type: AttributeType
public let version: Int
public let value: String

}

let bundleId: String
let applicationVersion: String
let originalApplicationVersion: String?
let opaqueValue: Data
let sha1Hash: Data
let creationDate: Date
let expirationDate: Date?
let inAppPurchases: [InAppPurchase]
public let bundleId: String
public let applicationVersion: String
public let originalApplicationVersion: String?
public let opaqueValue: Data
public let sha1Hash: Data
public let creationDate: Date
public let expirationDate: Date?
public let inAppPurchases: [InAppPurchase]

func purchasedIntroOfferOrFreeTrialProductIdentifiers() -> Set<String> {
public func purchasedIntroOfferOrFreeTrialProductIdentifiers() -> Set<String> {
let productIdentifiers = self.inAppPurchases
.filter { $0.isInIntroOfferPeriod == true || $0.isInTrialPeriod == true }
.map { $0.productId }
Expand All @@ -62,7 +62,7 @@ struct AppleReceipt: Equatable {

// MARK: - Extensions

extension AppleReceipt {
public extension AppleReceipt {

func containsActivePurchase(forProductIdentifier identifier: String) -> Bool {
return (
Expand All @@ -79,8 +79,10 @@ extension AppleReceipt: Codable {}

extension AppleReceipt: CustomDebugStringConvertible {

var debugDescription: String {
return (try? self.prettyPrintedJSON) ?? "<null>"
public var debugDescription: String {
// TODO
return "TODO"
// return (try? self.prettyPrintedJSON) ?? "<null>"
}

}
Loading