• Stars
    star
    6,552
  • Rank 6,038 (Top 0.2 %)
  • Language
    Swift
  • License
    MIT License
  • Created about 9 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Lightweight In App Purchases Swift framework for iOS 8.0+, tvOS 9.0+ and macOS 10.10+ โ›บ

License Platform Language Build Issues Slack

SwiftyStoreKit is a lightweight In App Purchases framework for iOS, tvOS, watchOS, macOS, and Mac Catalyst.

Features

  • Super easy-to-use block-based API
  • Support for consumable and non-consumable in-app purchases
  • Support for free, auto-renewable and non-renewing subscriptions
  • Support for in-app purchases started in the App Store (iOS 11)
  • Support for subscription discounts and offers
  • Remote receipt verification
  • Verify purchases, subscriptions, subscription groups
  • Downloading content hosted with Apple
  • iOS, tvOS, watchOS, macOS, and Catalyst compatible

SwiftyStoreKit Alternatives

During WWDC21, Apple introduced StoreKit 2, a brand new Swift API for in-app purchases and auto-renewable subscriptions.

While it would be highly desirable to support StoreKit 2 in this project, little progress has been made over the last year and most issues remain unanswered.

Fortunately, there are some very good alternatives to SwiftyStoreKit, backed by real companies. By choosing their products, you'll make a safe choice and get much better support.

RevenueCat

RevenueCat is a great alternative to SwiftyStoreKit, offering great APIs, support, and much more at a very reasonable price.

If you've been using SwiftyStoreKit and want to migrate to RevenueCat, this guide covers everything you need:

Or if you're just getting started, consider skipping SwiftyStoreKit altogether and signing up for RevenueCat.

Glassfy

Glassfy makes it easy to build, handle, and optimize in-app subscriptions. If you switch to Glassfy from SwiftyStoreKit, you'll get a 20% discount by using this affiliate link.

Note from the author: if you sign up with the link above, I will receive an affiliate commission from Glassfy, at no cost to yourself. I only recommend products that I personally know and believe will help you.

Apphud

Apphud is more than just making a purchase and validating receipts. Apphud is all-in-one infrastructure for your app growth. Sign up for free and try it out.

Or you can learn how to migrate your app from SwiftyStoreKit to Apphud.

Adapty

With Adapty you can set up subscriptions in just an hour following these simple steps and instantly launch in-app purchases with the Paywall Builder. Adapty not only gives you the tools to embed purchases but also helps your customers grow. And the best part is that itโ€™s free for apps <$10k.

Contributions Wanted

SwiftyStoreKit makes it easy for an incredible number of developers to seemlessly integrate in-App Purchases. This project, however, is now community-led. We need help building out features and writing tests (see issue #550).

Maintainers Wanted

The author is no longer maintaining this project actively. If you'd like to become a maintainer, join the Slack workspace and enter the #maintainers channel. Going forward, SwiftyStoreKit should be made for the community, by the community.

More info here: The Future of SwiftyStoreKit: Maintainers Wanted.

Requirements

If you've shipped an app in the last five years, you're probably good to go. Some features (like discounts) are only available on new OS versions, but most features are available as far back as:

iOS watchOS tvOS macOS Mac Catalyst
8.0 6.2 9.0 10.10 13.0

Installation

There are a number of ways to install SwiftyStoreKit for your project. Swift Package Manager, CocoaPods, and Carthage integrations are the preferred and recommended approaches.

Regardless, make sure to import the project wherever you may use it:

import SwiftyStoreKit

Swift Package Manager

The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into Xcode and the Swift compiler. This is the recommended installation method. Updates to SwiftyStoreKit will always be available immediately to projects with SPM. SPM is also integrated directly with Xcode.

If you are using Xcode 11 or later:

  1. Click File
  2. Swift Packages
  3. Add Package Dependency...
  4. Specify the git URL for SwiftyStoreKit.
https://github.com/bizz84/SwiftyStoreKit.git

Carthage

To integrate SwiftyStoreKit into your Xcode project using Carthage, specify it in your Cartfile:

github "bizz84/SwiftyStoreKit"

NOTE: Please ensure that you have the latest Carthage installed.

CocoaPods

SwiftyStoreKit can be installed as a CocoaPod and builds as a Swift framework. To install, include this in your Podfile.

use_frameworks!

pod 'SwiftyStoreKit'

Contributing

Got issues / pull requests / want to contribute? Read here.

Documentation

Full documentation is available on the SwiftyStoreKit Wiki. As SwiftyStoreKit (and Apple's StoreKit) gains features, platforms, and implementation approaches, new information will be added to the Wiki. Essential documentation is available here in the README and should be enough to get you up and running.

App startup

Complete Transactions

Apple recommends to register a transaction observer as soon as the app starts:

Adding your app's observer at launch ensures that it will persist during all launches of your app, thus allowing your app to receive all the payment queue notifications.

SwiftyStoreKit supports this by calling completeTransactions() when the app starts:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
	// see notes below for the meaning of Atomic / Non-Atomic
	SwiftyStoreKit.completeTransactions(atomically: true) { purchases in
	    for purchase in purchases {
	        switch purchase.transaction.transactionState {
	        case .purchased, .restored:
	            if purchase.needsFinishTransaction {
	                // Deliver content from server, then:
	                SwiftyStoreKit.finishTransaction(purchase.transaction)
	            }
	            // Unlock content
	        case .failed, .purchasing, .deferred:
	            break // do nothing
	        }
	    }
	}
    return true
}

If there are any pending transactions at this point, these will be reported by the completion block so that the app state and UI can be updated.

If there are no pending transactions, the completion block will not be called.

Note that completeTransactions() should only be called once in your code, in application(:didFinishLaunchingWithOptions:).

Purchases

Retrieve products info

SwiftyStoreKit.retrieveProductsInfo(["com.musevisions.SwiftyStoreKit.Purchase1"]) { result in
    if let product = result.retrievedProducts.first {
        let priceString = product.localizedPrice!
        print("Product: \(product.localizedDescription), price: \(priceString)")
    }
    else if let invalidProductId = result.invalidProductIDs.first {
        print("Invalid product identifier: \(invalidProductId)")
    }
    else {
        print("Error: \(result.error)")
    }
}

Purchase a product (given a product id)

  • Atomic: to be used when the content is delivered immediately.
SwiftyStoreKit.purchaseProduct("com.musevisions.SwiftyStoreKit.Purchase1", quantity: 1, atomically: true) { result in
    switch result {
    case .success(let purchase):
        print("Purchase Success: \(purchase.productId)")
    case .error(let error):
        switch error.code {
        case .unknown: print("Unknown error. Please contact support")
        case .clientInvalid: print("Not allowed to make the payment")
        case .paymentCancelled: break
        case .paymentInvalid: print("The purchase identifier was invalid")
        case .paymentNotAllowed: print("The device is not allowed to make the payment")
        case .storeProductNotAvailable: print("The product is not available in the current storefront")
        case .cloudServicePermissionDenied: print("Access to cloud service information is not allowed")
        case .cloudServiceNetworkConnectionFailed: print("Could not connect to the network")
        case .cloudServiceRevoked: print("User has revoked permission to use this cloud service")
        default: print((error as NSError).localizedDescription)
        }
    }
}
  • Non-Atomic: to be used when the content is delivered by the server.
SwiftyStoreKit.purchaseProduct("com.musevisions.SwiftyStoreKit.Purchase1", quantity: 1, atomically: false) { result in
    switch result {
    case .success(let product):
        // fetch content from your server, then:
        if product.needsFinishTransaction {
            SwiftyStoreKit.finishTransaction(product.transaction)
        }
        print("Purchase Success: \(product.productId)")
    case .error(let error):
        switch error.code {
        case .unknown: print("Unknown error. Please contact support")
        case .clientInvalid: print("Not allowed to make the payment")
        case .paymentCancelled: break
        case .paymentInvalid: print("The purchase identifier was invalid")
        case .paymentNotAllowed: print("The device is not allowed to make the payment")
        case .storeProductNotAvailable: print("The product is not available in the current storefront")
        case .cloudServicePermissionDenied: print("Access to cloud service information is not allowed")
        case .cloudServiceNetworkConnectionFailed: print("Could not connect to the network")
        case .cloudServiceRevoked: print("User has revoked permission to use this cloud service")
        default: print((error as NSError).localizedDescription)
        }
    }
}

Additional Purchase Documentation

These additional topics are available on the Wiki:

Restore Previous Purchases

According to Apple - Restoring Purchased Products:

In most cases, all your app needs to do is refresh its receipt and deliver the products in its receipt. The refreshed receipt contains a record of the userโ€™s purchases in this app, on this device or any other device.

Restoring completed transactions creates a new transaction for every completed transaction the user made, essentially replaying history for your transaction queue observer.

See the Receipt Verification section below for how to restore previous purchases using the receipt.

This section shows how to restore completed transactions with the restorePurchases method instead. When successful, the method returns all non-consumable purchases, as well as all auto-renewable subscription purchases, regardless of whether they are expired or not.

  • Atomic: to be used when the content is delivered immediately.
SwiftyStoreKit.restorePurchases(atomically: true) { results in
    if results.restoreFailedPurchases.count > 0 {
        print("Restore Failed: \(results.restoreFailedPurchases)")
    }
    else if results.restoredPurchases.count > 0 {
        print("Restore Success: \(results.restoredPurchases)")
    }
    else {
        print("Nothing to Restore")
    }
}
  • Non-Atomic: to be used when the content is delivered by the server.
SwiftyStoreKit.restorePurchases(atomically: false) { results in
    if results.restoreFailedPurchases.count > 0 {
        print("Restore Failed: \(results.restoreFailedPurchases)")
    }
    else if results.restoredPurchases.count > 0 {
        for purchase in results.restoredPurchases {
            // fetch content from your server, then:
            if purchase.needsFinishTransaction {
                SwiftyStoreKit.finishTransaction(purchase.transaction)
            }
        }
        print("Restore Success: \(results.restoredPurchases)")
    }
    else {
        print("Nothing to Restore")
    }
}

What does atomic / non-atomic mean?

For more information about atomic vs. non-atomic restorations, view the Wiki page here.

Downloading content hosted with Apple

More information about downloading hosted content is available on the Wiki.

To start downloads (this can be done in purchaseProduct(), completeTransactions() or restorePurchases()):

SwiftyStoreKit.purchaseProduct("com.musevisions.SwiftyStoreKit.Purchase1", quantity: 1, atomically: false) { result in
    switch result {
    case .success(let product):
        let downloads = purchase.transaction.downloads
        if !downloads.isEmpty {
            SwiftyStoreKit.start(downloads)
        }
    case .error(let error):
        print("\(error)")
    }
}

To check the updated downloads, setup a updatedDownloadsHandler block in your AppDelegate:

SwiftyStoreKit.updatedDownloadsHandler = { downloads in
    // contentURL is not nil if downloadState == .finished
    let contentURLs = downloads.flatMap { $0.contentURL }
    if contentURLs.count == downloads.count {
        // process all downloaded files, then finish the transaction
        SwiftyStoreKit.finishTransaction(downloads[0].transaction)
    }
}

To control the state of the downloads, SwiftyStoreKit offers start(), pause(), resume(), cancel() methods.

Receipt verification

This helper can be used to retrieve the (encrypted) local receipt data:

let receiptData = SwiftyStoreKit.localReceiptData
let receiptString = receiptData.base64EncodedString(options: [])
// do your receipt validation here

However, the receipt file may be missing or outdated. Use this method to get the updated receipt:

SwiftyStoreKit.fetchReceipt(forceRefresh: true) { result in
    switch result {
    case .success(let receiptData):
        let encryptedReceipt = receiptData.base64EncodedString(options: [])
        print("Fetch receipt success:\n\(encryptedReceipt)")
    case .error(let error):
        print("Fetch receipt failed: \(error)")
    }
}

Use this method to (optionally) refresh the receipt and perform validation in one step.

let appleValidator = AppleReceiptValidator(service: .production, sharedSecret: "your-shared-secret")
SwiftyStoreKit.verifyReceipt(using: appleValidator, forceRefresh: false) { result in
    switch result {
    case .success(let receipt):
        print("Verify receipt success: \(receipt)")
    case .error(let error):
        print("Verify receipt failed: \(error)")
    }
}

Additional details about receipt verification are available on the wiki.

Verifying purchases and subscriptions

Once you have retrieved the receipt using the verifyReceipt method, you can verify your purchases and subscriptions by product identifier.

Verify Purchase

let appleValidator = AppleReceiptValidator(service: .production, sharedSecret: "your-shared-secret")
SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in
    switch result {
    case .success(let receipt):
        let productId = "com.musevisions.SwiftyStoreKit.Purchase1"
        // Verify the purchase of Consumable or NonConsumable
        let purchaseResult = SwiftyStoreKit.verifyPurchase(
            productId: productId,
            inReceipt: receipt)
            
        switch purchaseResult {
        case .purchased(let receiptItem):
            print("\(productId) is purchased: \(receiptItem)")
        case .notPurchased:
            print("The user has never purchased \(productId)")
        }
    case .error(let error):
        print("Receipt verification failed: \(error)")
    }
}

Verify Subscription

This can be used to check if a subscription was previously purchased, and whether it is still active or if it's expired.

From Apple - Working with Subscriptions:

Keep a record of the date that each piece of content is published. Read the Original Purchase Date and Subscription Expiration Date field from each receipt entry to determine the start and end dates of the subscription.

When one or more subscriptions are found for a given product id, they are returned as a ReceiptItem array ordered by expiryDate, with the first one being the newest.

let appleValidator = AppleReceiptValidator(service: .production, sharedSecret: "your-shared-secret")
SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in
    switch result {
    case .success(let receipt):
        let productId = "com.musevisions.SwiftyStoreKit.Subscription"
        // Verify the purchase of a Subscription
        let purchaseResult = SwiftyStoreKit.verifySubscription(
            ofType: .autoRenewable, // or .nonRenewing (see below)
            productId: productId,
            inReceipt: receipt)
            
        switch purchaseResult {
        case .purchased(let expiryDate, let items):
            print("\(productId) is valid until \(expiryDate)\n\(items)\n")
        case .expired(let expiryDate, let items):
            print("\(productId) is expired since \(expiryDate)\n\(items)\n")
        case .notPurchased:
            print("The user has never purchased \(productId)")
        }

    case .error(let error):
        print("Receipt verification failed: \(error)")
    }
}

Further documentation on verifying subscriptions is available on the wiki.

Subscription Groups

From Apple Docs - Offering Subscriptions:

A subscription group is a set of in-app purchases that you can create to provide users with a range of content offerings, service levels, or durations to best meet their needs. Users can only buy one subscription within a subscription group at a time. If users would want to buy more that one type of subscription โ€” for example, to subscribe to more than one channel in a streaming app โ€” you can put these in-app purchases in different subscription groups.

You can verify all subscriptions within the same group with the verifySubscriptions method. Learn more on the wiki.

Notes

The framework provides a simple block based API with robust error handling on top of the existing StoreKit framework. It does NOT persist in app purchases data locally. It is up to clients to do this with a storage solution of choice (i.e. NSUserDefaults, CoreData, Keychain).

Change Log

See the Releases Page.

Sample Code

The project includes demo apps for iOS and macOS showing how to use SwiftyStoreKit. Note that the pre-registered in app purchases in the demo apps are for illustration purposes only and may not work as iTunes Connect may invalidate them.

Essential Reading

I have also written about building SwiftyStoreKit on Medium:

Troubleshooting

Video Tutorials

Jared Davidson: In App Purchases! (Swift 3 in Xcode : Swifty Store Kit)

@rebeloper: Ultimate In-app Purchases Guide

Written Tutorials

Credits

Many thanks to phimage for adding macOS support and receipt verification.

Apps using SwiftyStoreKit

It would be great to showcase apps using SwiftyStoreKit here. Pull requests welcome :)

A full list of apps is published on AppSight.

More Repositories

1

flutter-tips-and-tricks

My Flutter Tips & Tricks on Twitter ๐Ÿ‘‡
Dart
2,040
star
2

starter_architecture_flutter_firebase

Time Tracking app with Flutter & Firebase
Dart
1,655
star
3

layout-demo-flutter

Super Useful Flutter Layouts - Right in Your Pocket. ๐Ÿ˜‰
Dart
1,381
star
4

complete-flutter-course

Flutter Foundations Course - eCommerce App
Dart
815
star
5

flutter_example_apps

A directory of all my open source Flutter apps and projects.
753
star
6

firebase_auth_demo_flutter

Reference Authentication Flow with Flutter & Firebase
Dart
675
star
7

nested-navigation-demo-flutter

Nested navigation with BottomNavigationBar
Dart
620
star
8

movie_app_state_management_flutter

Flutter State Management: Movie App with Provider, Riverpod, flutter_bloc
Dart
557
star
9

time_tracker_flutter_course

Source code for every lesson in the "Flutter & Firebase: Build a Complete App for iOS & Android" course on Udemy
Dart
405
star
10

dart-course-materials

Code, Exercises & Syllabus for my Complete Dart Course
Dart
343
star
11

open_weather_example_flutter

Flutter Weather App Example using the OpenWeatherMap API
Dart
295
star
12

bottom_bar_fab_flutter

BottomAppBar Navigation with FAB
Dart
283
star
13

flutter_animations_course_materials

All projects from my Flutter Animations Course
Dart
248
star
14

tmdb_movie_app_riverpod

Flutter Movies app with Riverpod (TMDB API)
Dart
233
star
15

fluttercon_23_resources

List of talks from FlutterCon 23
219
star
16

MVCarouselCollectionView

UICollectionView-based image carousel written in Swift
Swift
205
star
17

Sustainable-Earth

A curated list of all things sustainable
Ruby
189
star
18

coding-with-flutter-login-demo

Source code for login demo in Coding with Flutter series
Dart
168
star
19

flutter_animations_gallery

A showcase of the most common Flutter animation APIs.
Dart
156
star
20

firebase_user_avatar_flutter

Advanced Provider Architecture Demo: Image Picker + Firebase Storage Upload
Dart
154
star
21

stopwatch-flutter

Simple stopwatch example app in Flutter
Dart
142
star
22

multiple-counters-flutter

Flutter State Management [ setState โ– StreamBuilder โ– scoped_model โ– redux ]
Dart
132
star
23

ftcon24eu_talks

List of talks from FlutterCon 24 Europe
Dart
122
star
24

coronavirus_rest_api_flutter_course

Coronavirus REST API Flutter Course
Dart
120
star
25

codewithandrea_flutter_packages

A collection of packages created to increase code reuse across many of my Flutter projects.
Dart
119
star
26

slivers_demo_flutter

Example Layouts with Slivers in Flutter
Dart
111
star
27

nested_navigation_examples

Bottom Navigation Bar with Nested Routes: GoRouter vs Beamer
106
star
28

firebase-login-flutter

Sample login and registration app with Firebase built in Flutter.
Dart
106
star
29

MVSelectorScrollView

Simple scrollable horizontal control, alternative to UISegmentedControl
Objective-C
103
star
30

flutter-firebase-masterclass

Flutter & Firebase Masterclass
Dart
103
star
31

simple_auth_flutter_riverpod

Simple authentication flow using Flutter & Riverpod
Dart
99
star
32

code_with_andrea_flutter

Code With Andrea Home Page - Flutter Clone
Dart
76
star
33

AcceptanceMark

Tool for generating Acceptance Tests in Xcode, inspired by Fitnesse
Swift
65
star
34

flight_co2_calculator_flutter

Flutter package and sample app to calculate Flight CO2 emissions
Dart
58
star
35

page_flip_builder

Interactive Page Flip Flutter widget
Dart
49
star
36

CrackingTheCodingInterview

Solutions to exercises from the book "Cracking the Coding Interview"
Swift
49
star
37

image-picker-demo-flutter

Photos and Camera Image Picker built in Flutter
Dart
47
star
38

split_view_example_flutter

Flutter Split View and Drawer Navigation example
Dart
47
star
39

localization_riverpod_flutter

Simplified localization app template
Dart
47
star
40

MVHorizontalPicker

Simple scrollable horizontal control, alternative to UISegmentedControl
Swift
43
star
41

github_search_flutter_client_rxdart_example

Example GitHub Search app built in Flutter & RxDart
Dart
41
star
42

apple_sign_in_firebase_flutter

Demo app showing how to implement Apple Sign In with Firebase & Flutter
Dart
40
star
43

json_placeholder_flutter_example

Riverpod data caching and CRUD example with the JsonPlaceholder API
Dart
35
star
44

simple_auth_comparison_flutter

Flutter State Management Comparison: [ setState โ– BLoC โ– ValueNotifier โ– Provider ]
Dart
35
star
45

fitness_tracker_flutter

Fitness Tracker - Flutter UI Demo
Dart
35
star
46

input_validation_demo_flutter

Flutter: Input Validation with RegExp
Dart
33
star
47

platform_aware_widgets_flutter

Example project showing how to create platform-aware widget classes in Flutter.
Dart
32
star
48

async_notifier_example_riverpod

AsyncNotifier example with Riverpod
C++
29
star
49

pushable_button

A 3D pushable button built in Flutter. Ideal for important CTAs in the app.
Dart
29
star
50

MVBouncyView

UIView category to add bouncing animations to your UIViews
Objective-C
28
star
51

restaurant_ratings_flutter_firebase

Restaurant In-App Rating Demo App with Flutter & Firebase
Dart
28
star
52

passwordless_sign_in_firebase_flutter

Passwordless sign-in with Flutter and Firebase
Dart
24
star
53

faker_app_flutter_firebase

Demo project for the first module of my Flutter & Firebase Masterclass
Dart
21
star
54

ncov2019-api-and-webclient

nCoV 2019 Backend REST API and Admin Web Client
Dart
21
star
55

MVScrollViewAutoLayout

Example iOS project showing how Auto-Layout can calculate the contentSize of a UIScrollView for you based on the constraints of the scroll viewโ€™s subviews.
Objective-C
20
star
56

MVMediaSlider

Custom media slider inspired by the Overcast App
Swift
18
star
57

force_update_helper

A package for showing a force update prompt that is controlled remotely.
Dart
18
star
58

bmi_calculator_app_flutter

Simple BMI Calculator Flutter App
Dart
16
star
59

flutter_ship_app

Companion app for the Flutter in Production course
JavaScript
16
star
60

rxdart_combine_latest_example_movie_app

Simple movie favourites app showcasing how to use combineLatest to combine data from two Firestore collections into one stream.
Dart
15
star
61

convert-srt-vtt

Bash script to convert closed captions from SRT to VTT format
Shell
15
star
62

redux-navigation-color-picker

Code for "Managing State in a React-Navigation App with Redux" tutorial
JavaScript
15
star
63

ResponsiveCollectionViews

Demo app showing how to make UICollectionViews responsive to trait collection changes
Swift
14
star
64

OAuthRequestBuilderSwift

OAuth Authentication with Custom Headers in Swift
Swift
13
star
65

firebase-example-flutter

Sample Firebase anonymous auth with Flutter
Dart
13
star
66

mood_tracker_flutter

Super easy mood tracking app to demonstrate use of the Firebase Local Emulator Suite
Dart
13
star
67

game_of_life_flutter

Game Of Life Flutter Demo
Dart
12
star
68

flutter_simple_permissions

Swift
12
star
69

dart_json_parsing_examples

JSON Parsing examples in Dart
Dart
11
star
70

flutter_web_apps_template

Flutter Web + GitHub Pages templates
Makefile
11
star
71

SudokuSolver

JSON Android Sudoku Solver
Java
10
star
72

contacts_list_demo_flutter

Sample contact list page built in Flutter and iOS
Swift
10
star
73

MVFeedbackBanner

Customisable banner UI to ask for user feedback / app rating
Swift
9
star
74

ITunesSearch.js

Javascript client for App Store Lookup based on iTunes Search API
JavaScript
7
star
75

coding-with-flutter-robohash-demo

Sample Flutter app showing an avatar image with the RoboHash API.
Dart
7
star
76

openai_dart_shelf_flutter

OpenAI + Dart Shelf + Flutter Demo
C++
7
star
77

flutter_firestore_counter_app

Dart
6
star
78

multiple_counters_firestore_flutter

Multiple Counters Flutter App with Cloud Firestore
Dart
6
star
79

simple_auth_flutter_firebase_ui

Minimal authentication flow with Flutter & Firebase Auth
C++
5
star
80

faker_app_firebase

Simple Flutter app showing how to use the Firebase UI packages
C++
5
star
81

image_upload_flutter_firebase

Flutter image upload demo with Firebase Storage
C++
5
star
82

flutter-firebase-ecommerce-docs

4
star
83

ncov_2019_app_flutter

Coronavirus REST API Flutter Course (demo app before recordings)
Dart
4
star
84

OGLESCubeTestAPI

Android Test for ES API 1.0 and 2.0
Java
3
star
85

required_version_shelf

A simple server-side Dart implementing a required_version endpoint.
Dart
3
star
86

MVKerningLabel

UILabel subclass with kerning support via @IBInspectable property
Swift
2
star
87

MVCoreDataStack

Core Data Parent-Child Stack for iOS 8 and 9
Swift
2
star
88

dart-null-safety-package-name-issue

Null Safety only works if package name is `test`
Dart
2
star
89

firebase_id_token_bug

Ruby
2
star
90

redux-navigator-react

Example app combining redux with react-navigation
JavaScript
2
star
91

SwiftyStoreDemo

Example app for iOS, tvOS showing how to retrieve products info with StoreKit
Swift
2
star
92

astro-vercel-serverless-bug

Astro
1
star
93

Xcode-xcarchive-command

Xcode xcarchive command to archive to custom location
Shell
1
star
94

PopSpringViews

Helper classes to enable Facebook POP spring animations on UIViews
Swift
1
star
95

firebase_ui_auth_widget_tests_bug

C++
1
star
96

biz-engine

OpenGL 2.0 Graphics engine + SDK
C++
1
star
97

ff3_whitelabel_app

Dart
1
star
98

MVITunesSearch

Simple wrapper library for the iTunes Search API to search for apps by developer ID
Objective-C
1
star