SwiftUI tip jar example, using SwiftTipJar
This SwiftUI sample code demonstrates ease of use for SwiftTipJar - an open source package.
There is also UIKit sample code (same functionality).
Tip jars on Apple platforms are a concept of letting users make in-app purchases to show appreciation for the app/developer. These don't actually unlock any additional features.
Demo app screenshots
Choice of tips | System UI for purchasing | Successful purchase | Thank you message |
---|---|---|---|
Usage
- Init TipJar with identifiers for In-App Purchases you wish to offer
- Make TipJar observe StoreKit's payment queue. It's best if observed during entire lifetime of the app.
- Let TipJar find out product information for identifiers you've supplied. It's either going to be fetched from Xcode (when using StoreKit Configuration file) or from App Store Connect over the network.
// #1
tipJar = SwiftTipJar(tipsIdentifiers: Set(["com.test.smallTip", "com.test.largeTip"]))
// #2
tipJar.startObservingPaymentQueue()
// #3
tipJar.productsRequest?.start()
- As soon as tipJar finds out about the products, it publishes tips, an array of Tip objects that supplies you with displayName and displayPrice, in local language and currency. Array has been sorted by price, ascending. Products that haven't been configured with a name and/or price are simply omitted from this array.
@Published public private(set) var tips: [Tip] = []
public final class Tip {
public var identifier: String = ""
public var displayName: String = ""
public var displayPrice: String = ""
/// TipJar uses this to quickly check if it should include this Tip in its published array.
var isValid: Bool {
return !identifier.isEmpty && !displayName.isEmpty && !displayPrice.isEmpty
}
}
- Assign any code you want to run after a successful purchase to transactionSuccessfulBlock, and similarly any code you want to run after a failed purchase (user clicked Cancel instead of Purchase) to transactionFailedBlock. With tip jars, it's even natural to do nothing if a transaction fails.
.onAppear {
tipJar.transactionSuccessfulBlock = {
showingThankYou = true
}
tipJar.transactionFailedBlock = {
// No need to do anything, user did tap cancel
}
}
- Set up button(s) to initiate a purchase to trigger the action initiatePurchase(productIdentifier:)
Button {
tipJar.initiatePurchase(productIdentifier: tip.identifier)
} label: {
Text("\(tip.displayName) \(tip.displayPrice)")
}
Troubleshooting
Q: I've set up IAPs in a StoreKit Configuration file, but nothing is showing up in the demo app
A: Edit Scheme > Options, and check that you have the correct StoreKit Configuration selected
Q: I've set up IAPs in StoreKit Configuration file, some are showing up in demo app, but not all
A: Check that TipJar's init is called with all relevant identifiers; check identifiers for any spelling errors. Check that you've provided the name and price for every IAP you want to see in the demo app.