Giter Site home page Giter Site logo

swifttipjar's Introduction

SwiftTipJar

On Apple patforms, tip jars are a concept of letting users make in-app purchases to show appreciation for the app/developer, which don't actually unlock any additional features of the app.

This package lets you have a tip jar running in minutes.

Here are SwiftUI sample code and UIKit sample code that demonstrate this.

All you need to do is polish your UI and configure Consumable IAPs in App Store Connect or an Xcode StoreKit Configuration
(see Setting up StoreKit testing in Xcode).

Installation

SwiftTipJar is available through Swift Package Manager.

  • In Xcode, click File > Add Packages...
  • Select GitHub under Source Control Accounts
  • Search for SwiftTipJar
  • Click "Add Package" in bottom right

Usage

For a quick start refer to SwiftUI sample code and UIKit sample code.

Backstory

There are many - good - tutorials for implementing IAPs in Swift.

Following any of them will help you understand how StoreKit works, what are products request and products response, what makes up StoreKit products, how to initiate a purchase, how to observe the transaction queue, how to process a transaction...

I had to re-learn all that when I recently developed a tip jar for Tubist, a macOS menu bar YouTube player even though I've dealt with IAPs like less than two years ago. Memory fades!

Then it hit me - pretty much all tip jars work the same way, right? While learning how StoreKit works is useful and ahem noble, if all you need is a working tip jar, why not reach for a single package that already does all the lifting?

Thus I created SwiftTipJar. Use it, and hopefully get some tips out of it!

P.S. If you find any code smells or documentation smells, feel free to open an issue

swifttipjar's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

swifttipjar's Issues

No prices showing in release version of app ?

Hi,

I've just released my app with SwiftTipJar integrated into my app and none of the prices are showing.
My button to send the tip also crashes my app.

During the development and in test flight the prices were shown from the store kit configuration file and everything worked fine.

Help.

Here's my code...

import SwiftTipJar
import SwiftUI

struct TipJarView: View {
    @EnvironmentObject var tipJar: SwiftTipJar
    @State private var showingThankYou = false
    @State private var showingTipJarFailure = false
    @State private var tipIndex: Int = 1

    var buttonText: String {
        guard !tipJar.tips.isEmpty else { return "" }
        return "\(tipJar.tips[tipIndex].displayPrice)"
    }

    var body: some View {
        VStack {
            Text(Strings.settingsTipJarDescription)
                .frame(maxWidth: .infinity, minHeight: 100)

            Picker(.settingsTipJarPickerLabel, selection: $tipIndex) {
                ForEach(0 ..< tipJar.tips.count, id: \.self) { index in
                    Text("\(tipJar.tips[index].displayPrice)")
                }
            }
            .pickerStyle(SegmentedPickerStyle())

            Button(action: {
                showingThankYou = false
                showingTipJarFailure = false
                tipJar.initiatePurchase(
                    productIdentifier: tipJar.tips[self.tipIndex].identifier)
            }, label: {
                HStack {
                    Text(.settingsTipJarButton,
                         values: [buttonText])
                }
                .accessibilityElement()
                .accessibility(addTraits: .isButton)

            })
            .frame(maxWidth: .infinity,
                   minHeight: 50,
                   alignment: .center)
            .buttonStyle(BorderlessButtonStyle())

            if showingThankYou {
                Text(.settingsTipJarThanks)
                    .bold()
                    .multilineTextAlignment(.center)
                    .padding(15)
            }
            if showingTipJarFailure {
                Text(.settingsTipJarFailure)
                    .foregroundColor(Color.red)
                    .multilineTextAlignment(.center)
                    .padding(15)
            }
        }
        .onAppear {
            tipJar.transactionSuccessfulBlock = {
                showingThankYou = true
            }
            tipJar.transactionFailedBlock = {
                showingTipJarFailure = true
            }
        }
    }
}
struct MyApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    let tipJar: SwiftTipJar

    init() {

        tipJar = SwiftTipJar(tipsIdentifiers: Set([
            "com.myapp.tinyTip",
            "com.myapp.smallTip",
            "com.myapp.mediumTip",
            "com.myapp.largeTip",
            "com.myapp.extraLargeTip"
        ]))
        tipJar.startObservingPaymentQueue()
        tipJar.productsRequest?.start()
 }

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(tipJar)

image

Edit....
Hmmm

image

iOS 14 fails to return products

Hi,

I've been looking through the Xcode output and can't see any error...
The plug-in seems to work fine with iOS 15.4, however with iOS 14.5 it fails to return any products.
To be specific ...
tipJar.tips = 0

I'm using Xcode 13.3.1
And using the simulator.

Any ideas ?

Thanks,

Jules.

Feature Request: Subscription tip

Hi

I love the idea of this plugin.

I was thinking about how this might look, Iโ€™m thinking I would have a number picker and probably buy me a n coffee(s).

Then I thought n coffees a month could be good too, although this would require a subscription.

Just an idea.

Jules.

MacOS crash

This works on iPadOS and iOS, but when running the iPad app on MacOS, it crashes.

2023-06-30 15:52:20.118308-0700 Making Cents[53561:8446214] [default] LSPrefs: could not find untranslocated node for <FSNode 0x600000171180> { isDir = ?, path = '/private/var/folders/z1/y19bl3s5323d0ykjxsqdqwmc0000gp/X/2FE04D90-D134-5236-8973-9DD7F1CC0288/d/Wrapper/Making Cents.app' }, proceeding on the assumption it is not translocated: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"
2023-06-30 15:52:20.122081-0700 Making Cents[53561:8446214] [default] LSPrefs: could not find untranslocated node for <FSNode 0x600000171180> { isDir = ?, path = '/private/var/folders/z1/y19bl3s5323d0ykjxsqdqwmc0000gp/X/2FE04D90-D134-5236-8973-9DD7F1CC0288/d/Wrapper/Making Cents.app' }, proceeding on the assumption it is not translocated: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"
2023-06-30 15:52:20.125603-0700 Making Cents[53561:8446214] [default] LSPrefs: could not find untranslocated node for <FSNode 0x600000171180> { isDir = ?, path = '/private/var/folders/z1/y19bl3s5323d0ykjxsqdqwmc0000gp/X/2FE04D90-D134-5236-8973-9DD7F1CC0288/d/Wrapper/Making Cents.app' }, proceeding on the assumption it is not translocated: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"
2023-06-30 15:52:20.997610-0700 Making Cents[53561:8446214] [default] LSPrefs: could not find untranslocated node for <FSNode 0x600000171180> { isDir = ?, path = '/private/var/folders/z1/y19bl3s5323d0ykjxsqdqwmc0000gp/X/2FE04D90-D134-5236-8973-9DD7F1CC0288/d/Wrapper/Making Cents.app' }, proceeding on the assumption it is not translocated: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"
2023-06-30 15:52:21.062872-0700 Making Cents[53561:8446214] [TraitCollection] Class _UIFindNavigatorViewController overrides the -traitCollection getter, which is not supported. If you're trying to override traits, you must use the appropriate API.
2023-06-30 15:52:21.152197-0700 Making Cents[53561:8446214] [default] CGSWindowShmemCreateWithPort failed on port 0
2023-06-30 15:52:21.547331-0700 Making Cents[53561:8446214] void * _Nullable NSMapGet(NSMapTable * Nonnull, const void * Nullable): map table argument is NULL
2023-06-30 15:52:23.187601-0700 Making Cents[53561:8446214] [default] CGSWindowShmemCreateWithPort failed on port 0
SwiftUI/EnvironmentObject.swift:82: Fatal error: No ObservableObject of type SwiftTipJar found. A View.environmentObject(
:) for SwiftTipJar may be missing as an ancestor of this view.
2023-06-30 15:52:23.633152-0700 Making Cents[53561:8446214] SwiftUI/EnvironmentObject.swift:82: Fatal error: No ObservableObject of type SwiftTipJar found. A View.environmentObject(
:) for SwiftTipJar may be missing as an ancestor of this view.
(lldb)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.