space-code/flare
## Description
Description
Flare is a modern, lightweight Swift framework that simplifies working with in-app purchases and subscriptions. Built on top of StoreKit and StoreKit 2, it provides a clean, unified API with async/await support and includes ready-to-use UI components for seamless integration across all Apple platforms.
β¨ Features
- ποΈ Complete Purchase Support - Consumable, non-consumable, and subscription purchases
- π Promotional Offers - Support for promotional and introductory offers
- β‘ Modern Swift - Built with async/await for clean, readable code
- π StoreKit 1 & 2 - Unified API supporting both StoreKit versions
- π¨ UI Components - Pre-built SwiftUI and UIKit views for product displays
- π± Cross-Platform - iOS, tvOS, watchOS, macOS, and visionOS compatible
- π§ͺ Thoroughly Tested - Complete unit, integration, and snapshot test coverage
π Table of Contents
- Fetching Products - Making Purchases - Managing Subscriptions - Handling Transactions - Promotional Offers
π± Requirements
| Package | Supported Platforms | Xcode | Minimum Swift Version | |---------|-------------------|-------|----------------------| | Flare | iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 7.0+ / visionOS 1.0+ | 15.4+ | 5.10 | | FlareUI | iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ | 15.4+ | 5.10 |
π Installation
Swift Package Manager
Add the following dependency to your Package.swift:
dependencies: [
.package(url: "https://github.com/space-code/flare.git", from: "3.3.0")
]Or via Xcode:
- File > Add Package Dependencies
- Enter package URL:
https://github.com/space-code/flare.git - Select version requirements
The package contains two libraries:
- Flare - Core in-app purchase functionality
- FlareUI - Ready-to-use UI components for SwiftUI and UIKit
Quick Start
import Flare
// Configure Flare
Flare.configure(with: .init(applicationUsername: "UUID"))
// Fetch products
let products = try await Flare.shared.fetch(productIDs: ["premium_monthly"])
// Purchase a product
let transaction = try await Flare.shared.purchase(product: products.first!)
// Finish the transaction
Flare.shared.finish(transaction: transaction, completion: nil)Usage
Fetching Products
Retrieve product information from the App Store:
import Flare
// Fetch single product
let productIDs = ["com.app.premium"]
let products = try await Flare.shared.fetch(productIDs: productIDs)
// Fetch multiple products
let subscriptionIDs = [
"com.app.monthly",
"com.app.yearly",
"com.app.lifetime"
]
let subscriptions = try await Flare.shared.fetch(productIDs: subscriptionIDs)
// Access product details
for product in products {
print("Product: \(product.localizedTitle)")
print("Price: \(product.localizedPriceString)")
print("Description: \(product.localizedDescription)")
}Making Purchases
Handle purchases with simple async/await syntax:
import Flare
func purchasePremium() async throws {
let productID = "com.app.premium"
let products = try await Flare.shared.fetch(productIDs: [productID])
guard let product = products.first else {
throw IAPError.storeProductNotAvailable
}
do {
let transaction = try await Flare.shared.purchase(product: product)
await unlockPremiumFeatures()
Flare.shared.finish(transaction: transaction, completion: nil)
} catch {
guard let error = error as? IAPError else { return }
switch error {
case .paymentCancelled:
print("β User cancelled the purchase")
default:
print("β Purchase failed: \(error)")
}
}
}Managing Subscriptions
Work with subscription products and their states:
import Flare
func purchaseSubscription(product: StoreProduct) async throws {
do {
let transaction = try await Flare.shared.purchase(product: product)
Flare.shared.finish(transaction: transaction, completion: nil)
} catch {
guard let error = error as? IAPError else { return }
// Handle the error
}
}Handling Transactions
Manage transaction lifecycle:
import Flare
// Finish a transaction after delivering content
func completeTransaction(_ transaction: StoreTransaction) {
Flare.shared.finish(transaction: transaction) {
print("β
Transaction completed successfully")
}
}
// Restore previous purchases
func restorePurchases() async throws {
do {
try await Flare.shared.restore()
print("β
Purchases restored successfully")
} catch {
print("β Failed to restore purchases: \(error)")
}
}
// Listen for transaction updates
func observeTransactions() {
Flare.shared.addTransactionObserver { result in
switch result {
case let .success(transaction):
handleTransaction(transaction)
case let .failure(error):
print("Transaction error: \(error)")
}
}
}Promotional Offers
Support promotional and introductory offers:
import Flare
func purchaseWithOffer(product: StoreProduct, offer: PromotionalOffer) async throws {
do {
let transaction = try await Flare.shared.purchase(
product: product,
promotionalOffer: offer
)
print("β
Purchased with promotional offer!")
Flare.shared.finish(transaction: transaction, completion: nil)
} catch {
guard let error = error as? IAPError else { return }
// Handle the error
}
}π¨ FlareUI
FlareUI provides ready-to-use UI components for displaying products and handling purchases in both SwiftUI and UIKit.
SwiftUI Integration
Display products with built-in SwiftUI views:
import SwiftUI
import FlareUI
struct StoreView: View {
var body: some View {
NavigationView {
SubscriptionsView(ids: ["com.product.subscription"])
.navigationTitle("Premium Features")
}
}
}UIKit Integration
Integrate with UIKit applications:
import UIKit
import FlareUI
let subscriptionsVC = SubscriptionsViewController(ids: [com.company.subscription_id])
let nav = UINavigationController(rootViewController: subscriptionsVC)
present(nav, animated: true)Documentation
Comprehensive documentation is available:
- Flare Documentation - Core framework integration and APIs
- FlareUI Documentation - UI components, customization, and integration guides
Contributing
We love contributions! Please read our Contributing Guide to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes.
Development Setup
Bootstrap the development environment:
mise installCode of Conduct
This project adheres to the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code.
License
Flare is released under the MIT license. See LICENSE for details.
<div align="center">
Made with β€οΈ by space-code
</div>
Package Metadata
Repository: space-code/flare
Default branch: main
README: README.md