In-app purchases and subscriptions made easy. Support for iOS, iPadOS, watchOS, and Mac.

Overview

😻 In-App Subscriptions Made Easy 😻

License Version Version Carthage compatible SwiftPM compatible

Purchases.framework (currently supported)

We're in the process of migrating the entire framework over to Swift 🎉 . The new framework is called RevenueCat.framework. While this migration is happening, you can (and should) still use the currently supported production version you know and love. If you'd like to help us by testing our beta, please feel free!

IMPORTANT: SPM integration note for users of our stable release:

Swift Package Manager (SPM) integration is currently not working as expected. If you wish to use the currently supported and stable Purchases framework (version 3.12.4), you'll need to specify < 4.0.0 or for your dependencies in Xcode. By default, Xcode will specify exactly 4.0.0 and that won't work because we haven't released that version yet, only 4.0.0-beta.x.

RevenueCat.framework Beta

Purchases and RevenueCat are clients for the RevenueCat subscription and purchase tracking system.

Purchases is the currently supported, production-ready, open source framework that provides a wrapper around StoreKit and the RevenueCat backend to make implementing in-app subscriptions in Swift or Objective-C easy - receipt validation and status tracking included!

RevenueCat is our next big release (what we've been calling Purchases V4). It is a rename of Purchases to RevenueCat, and now, 100% Swift. It contains all the same functionality (and almost exactly the same API) as Purchases. It's not a brand-new framework, but rather, a migration of the ObjC bits over to Swift with improved nullability, various bug fixes, and some new features. We're also going to be adding in StoreKit2 support before we 🚢 it, too! The framework is nearly production-ready, but we're going to keep it in beta while we continue to work on the StoreKit2 bits and iron out any remaining bugs folks find. Keep an eye out over the next few releases if you're excited to try out the StoreKit2 integration- we'll announce when we add it to the beta 😄

Features

RevenueCat
Server-side receipt validation
➡️ Webhooks - enhanced server-to-server communication with events for purchases, renewals, cancellations, and more
🖥 macOS support
🎯 Subscription status tracking - know whether a user is subscribed whether they're on iOS, Android or web
📊 Analytics - automatic calculation of metrics like conversion, mrr, and churn
📝 Online documentation up to date
🔀 Integrations - over a dozen integrations to easily send purchase data where you need it
💯 Well maintained - frequent releases
📮 Great support - Help Center

Getting Started

For more detailed information, you can view our complete documentation at docs.revenuecat.com.

Or browse our iOS sample apps:

Comments
  • How to use the library in watch app?

    How to use the library in watch app?

    Hi, I have the error with version 4.0 when running it with the latest Xcode beta.

    Showing Recent Messages /Users/majid/Library/Developer/Xcode/DerivedData/SleepBot-fcdzzaaaglxzwpcmtdyrkdzbxapm/SourcePackages/checkouts/purchases-ios/Purchases/Public/RCPurchases.m:27:9: 'RCDeviceCache.h' file not found

    opened by mecid 33
  • Feature: xcframeworks

    Feature: xcframeworks

    Adds support for building xcframeworks. Automatically builds and uploads an xcframework to releases, alongside the old universal framework. \

    This should provide seamless compatibility for macOS / macCatalyst and Apple Sillicon for developers who integrate the framework directly through the binary. For folks who use other mechanisms:

    • Carthage: updating to Carthage v0.37+ should already provide seamless compatibility
    • Cocoapods: was already working correctly for all architectures
    • Swift Package Manager: was already working correctly for all architectures
    • Xcode direct integration: I believe that since there's no concept of an XCFramework target in Xcode, you'd have to create the XCFramework yourself. This can be done by running (from the project dir) bundle exec fastlane export_xcframework.
    opened by aboedo 25
  • crash: EXC_BAD_ACCESS in 4.2.1, DeviceCache.swift - Line 123

    crash: EXC_BAD_ACCESS in 4.2.1, DeviceCache.swift - Line 123

    Describe the bug Crash in DeviceCache.cache(customerInfo:appUserID:) + 123 Crashed: Backend callbackQueue EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000b2005a2e0

    see stack trace below

    1. Environment
      1. Platform: iOS
      2. SDK version: 4.2.1
      3. StoreKit 2 enabled (Y/N): not sure.
      4. OS version: 15.5.0
      5. Xcode version: 13.3.1
      6. How widespread is the issue. Percentage of devices affected. unknown as of now
    2. Debug logs that reproduce the issue no logs available for this crash
    3. Steps to reproduce, with a description of expected vs. actual behavior No steps as such - happened randomly
    4. Other information (e.g. stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, etc.)
    Crashed: Backend callbackQueue
    EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000b2005a2e0
    0
    libobjc.A.dylib
    objc_release + 16
    1
    Foundation
    -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:maybeNewValuesDict:usingBlock:] + 676
    2
    Foundation
    -[NSObject(NSKeyValueObservingPrivate) _notifyObserversOfChangeFromValuesForKeys:toValuesForKeys:] + 816
    3
    CoreFoundation
    -[CFPrefsSource forEachObserver:] + 332
    4
    CoreFoundation
    -[CFPrefsSource _notifyObserversOfChangeFromValuesForKeys:toValuesForKeys:] + 112
    5
    CoreFoundation
    ___CFPrefsDeliverPendingKVONotificationsGuts_block_invoke + 440
    6
    CoreFoundation
    __CFDictionaryApplyFunction_block_invoke + 28
    7
    CoreFoundation
    CFBasicHashApply + 148
    8
    CoreFoundation
    CFDictionaryApplyFunction + 328
    9
    CoreFoundation
    _CFPrefsDeliverPendingKVONotificationsGuts + 300
    10
    CoreFoundation
    -[_CFXPreferences _deliverPendingKVONotifications] + 96
    11
    CoreFoundation
    __108-[_CFXPreferences(SearchListAdditions) withSearchListForIdentifier:container:cloudConfigurationURL:perform:]_block_invoke + 428
    12
    CoreFoundation
    normalizeQuintuplet + 356
    13
    CoreFoundation
    -[_CFXPreferences withSearchListForIdentifier:container:cloudConfigurationURL:perform:] + 152
    14
    CoreFoundation
    -[_CFXPreferences setValue:forKey:appIdentifier:container:configurationURL:] + 128
    15
    CoreFoundation
    _CFPreferencesSetAppValueWithContainerAndConfiguration + 136
    16
    Foundation
    -[NSUserDefaults(NSUserDefaults) setObject:forKey:] + 84
    17
    <my app>
    DeviceCache.swift - Line 123
    closure #1 in DeviceCache.cache(customerInfo:appUserID:) + 123 
    

    Additional context Add any other context about the problem here.

    purchase state is unsubscribed. was on mobile data and not on wifi. app was in foreground, and buttons were pressed, and randomly the crash happened. hasn't happened again today

    bug triaged 
    opened by quantamrhino 24
  • RCAnonymousID doesn't change after identify

    RCAnonymousID doesn't change after identify

    Our app have it’s own user uid’s and usually client obtaining it from backend after installation and login. We follow all the guides on RC identification written here: https://docs.revenuecat.com/docs/user-ids#section-tips-for-setting-app-user-ids but it’s still didn’t works how we expect. So here the problem and steps to reproduce:

    1 First we configure Purchases with nil on appUserId, so SDK creates RCAnonymousID 2 After login and obtaining our own id, we call identify method, with our id as parameter 3 In method closure(RCReceivePurchaserInfoBlock) info contains wrong originalAppUserId 4 And purchaserInfo method are also contains wrong originalAppUserId

    We expect here to see our own id. We have an Android app, built the same way, and the issue doesn’t reproduce on it.

    Also we made some research, and if we call Purchases.shared.appUserID in same closure, it will be correct one We thought that maybe there’s a problem with UserDefaults which RC uses as storage. If we call UserDefaults(suiteName: «»)?.dictionaryRepresentation() we can’t find any correct id

    What suggestions and tips do you have for our problem? Version 3.4.0

    opened by ichikmarev 24
  • Apple App store - sandboxing doc for macOS outdated?

    Apple App store - sandboxing doc for macOS outdated?

    Hi there,

    I've specifically updated my mac from Big Sur to Monetery (12.2) to be able to sandbox test with revenue cat. According to your doc(https://docs.revenuecat.com/docs/apple-app-store#add-the-sandbox-test-account-to-your-device) to sandbox user on mac you've to:

    On macOS 11.5.2 or greater, navigate to App Store > Preferences > Sandbox Account.

    Screen Shot 2022-02-04 at 1 08 13 PM

    but such option doesn't seem to appear on when you go to Preferences.

    I'd also like to know if setting:

    Purchases.logLevel = .debug

    in delegate, automatically makes me a sandbox user & won't charge me as a temporary solution.

    bug 
    opened by Daniyaldehleh 22
  • App crashes during SKProductsRequest on iOS 13

    App crashes during SKProductsRequest on iOS 13

    On iOS 13 the app crashes during SKProductsRequest.

    When SK1StoreProductDiscount is initialised it crashes on line 32: self.currencyCode = sk1Discount.priceLocale.currencyCode at priceLocale.

    1. Environment

      1. Platform: iOS
      2. SDK version: 4.2.1 also happnes with 4.1.0
      3. StoreKit 2 enabled (Y/N): Yes
      4. OS version: 13.6.1
      5. Xcode version: 13.3
      6. How widespread is the issue. Percentage of devices affected: All devices with iOS 13 I guess
    2. Debug logs that reproduce the issue Before the crash, there's just:

    [Purchases] - DEBUG: 😻 SKProductsRequest did finish
    [Purchases] - DEBUG: 😻 SKProductsRequest request received response
    
    1. Steps to reproduce, with a description of expected vs. actual behavior Just call Purchases.configure(withAPIKey and it happens every time.

    2. Other information (e.g. stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, etc.)

    Exception Type:  EXC_BREAKPOINT (SIGTRAP)
    Exception Codes: 0x0000000000000001, 0x00000001d1360494
    Termination Signal: Trace/BPT trap: 5
    Termination Reason: Namespace SIGNAL, Code 0x5
    Terminating Process: exc handler [6572]
    Triggered by Thread:  0
    
    Thread 0 name:
    Thread 0 Crashed:
    0   libswiftFoundation.dylib      	0x00000001d1360494 static Locale._unconditionallyBridgeFromObjectiveC(_:) + 332 (Locale.swift:473)
    1   AppBlock                      	0x00000001051a7bc4 init + 84 (StoreProductDiscount.swift:169)
    2   AppBlock                      	0x00000001051a7bc4 init + 84 (<compiler-generated>:85)
    3   AppBlock                      	0x00000001051a7bc4 compactMap + 84 (SK1StoreProduct.swift:0)
    4   AppBlock                      	0x00000001051a7bc4 SK1StoreProduct.discounts.getter + 1144
    5   AppBlock                      	0x0000000105182010 discounts.get + 40 (StoreProduct.swift:96)
    6   AppBlock                      	0x0000000105182010 extractDiscounts + 64 (ProductRequestData+Initialization.swift:71)
    7   AppBlock                      	0x0000000105182010 specialized ProductRequestData.init(with:) + 1136 (ProductRequestData+Initialization.swift:30)
    8   AppBlock                      	0x0000000105193fd4 init + 8 (PurchasesOrchestrator.swift:0)
    9   AppBlock                      	0x0000000105193fd4 PurchasesOrchestrator.postReceipt(withTransaction:receiptData:products:) + 76
    10  AppBlock                      	0x0000000105198b7c partial apply for closure #1 in PurchasesOrchestrator.fetchProductsAndPostReceipt(withTransaction:receiptData:) + 76 (PurchasesOrchestrator.swift:561)
    11  AppBlock                      	0x000000010518fd20 closure #1 in closure #2 in PurchasesOrchestrator.products(withIdentifiers:completion:) + 256 (PurchasesOrchestrator.swift:117)
    12  AppBlock                      	0x000000010518f2f0 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0)
    13  libdispatch.dylib             	0x000000019b0959a8 _dispatch_call_block_and_release + 24 (init.c:1408)
    14  libdispatch.dylib             	0x000000019b096524 _dispatch_client_callout + 16 (object.m:495)
    15  libdispatch.dylib             	0x000000019b0485b4 _dispatch_main_queue_callback_4CF$VARIANT$mp + 904 (inline_internal.h:2484)
    16  CoreFoundation                	0x000000019b34e6bc __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12 (CFRunLoop.c:1749)
    17  CoreFoundation                	0x000000019b349590 __CFRunLoopRun + 1724 (CFRunLoop.c:3069)
    18  CoreFoundation                	0x000000019b348ba8 CFRunLoopRunSpecific + 424 (CFRunLoop.c:3192)
    19  GraphicsServices              	0x00000001a54b8344 GSEventRunModal + 160 (GSEvent.c:2246)
    20  UIKitCore                     	0x000000019f4843e4 UIApplicationMain + 1932 (UIApplication.m:4823)
    21  libswiftUIKit.dylib           	0x00000001d15dd2b4 UIApplicationMain(_:_:_:_:) + 168 (UIKit.swift:528)
    22  AppBlock                      	0x0000000104e6ff80 main + 80 (<compiler-generated>:18)
    23  AppBlock                      	0x0000000104e6ff80 $main + 92 (LicensesViewController.swift:0)
    24  AppBlock                      	0x0000000104e6ff80 main + 108
    25  libdyld.dylib                 	0x000000019b1d08f0 start + 4
    
    bug triaged 
    opened by honzakeller 19
  • Receiving Error message ITMS-90562: Invalid Bundle from Apple after submitting new binary for publication

    Receiving Error message ITMS-90562: Invalid Bundle from Apple after submitting new binary for publication

    I was using CocoaPods and updated to RevenueCat 4.1 from Purchases and then made the code adjustments and tested the app on my devices and all worked great. I submitted a binary to Apple and then received this message.

    ITMS-90562: Invalid Bundle - One or more dynamic libraries that are referenced by your app are not present in the dylib search path.

    I then decided to move from CocoaPods to Swift Package Manager (SPM) and after that transition while still using Purchases 3.x.x, and submitting the binary to Apple, all was good. I then updated the SPM to RevenueCat 4.x.x + and all worked great on my devices. But again, after submitting to Apple, I receive the same error message.

    ITMS-90562: Invalid Bundle - One or more dynamic libraries that are referenced by your app are not present in the dylib search path.

    I have RevenueCat used with just one target and I have checked that Purchases has been removed from the 'Link Binaries with Libraries' and RevenueCat appears there instead.

    Any help will be appreciated.

    thanks, Glen

    bug 
    opened by ghb101 19
  • AppStore.showManageSubscriptions(in: scene) Freezes App When Dismissed

    AppStore.showManageSubscriptions(in: scene) Freezes App When Dismissed

    This isn't a RevenueCat bug but I tried using this API on simulator and device and whenever I dismiss the in-app subscription management page by pressing the page's "X" button on the top right, the app gets stuck. In fact, any iPhone with a notch gets bricked, lol. Just wondering if you experienced this too.

    1. Environment
      1. Platform: iOS
      2. SDK version: NA
      3. OS version: 15.3
      4. Xcode version: 13.2.1
      5. How widespread is the issue. Percentage of devices affected. NA
    2. Debug logs that reproduce the issue
    3. Steps to reproduce, with a description of expected vs. actual behavior
    4. Other information (e.g. stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, etc.)

    Additional context Add any other context about the problem here.

    bug triaged 
    opened by haarj 18
  • Purchase already in progress for this product

    Purchase already in progress for this product

    Hello! Starting with SDK 3.5.0 (we haven't shipped 3.5.1 yet) we've been seeing some odd errors in production. It appears that sometimes when a user canceled a purchase then tries to purchase again RevCat can throw an already-in-progress error

    1. Environment
      1. Platform: iOS
      2. SDK version: 3.5.0
      3. OS version: 12-13
      4. XCode/Android Studio version: 11.6
      5. How widespread is the issue. Percentage of devices affected. 0.5-1%
    2. Debug logs that reproduce the issue
    3. Steps to reproduce: Unable to reproduce at this time, still attempting

    Additional context Here's an excerpt from our prod logs for an effected user, they pretty much all look like this:

    User :

    Jul 22 17:59:50  🎁 Saw Sell page flow: setupSensor, sku: ***   <Saw our sell page
    Jul 22 17:59:59  💰 Initiating Purchase: ***                    <User hit purchase, Purchases.shared.purchasePackage(package) Called
    Jul 22 18:00:01  💰 Purchase State: .purchasing                 <Our own SKPaymentTransactionObserver sees the state change
    Jul 22 18:00:03  🚀 Application - WillResignActive              <User sees native pay sheet
    Jul 22 18:01:31  🚀 Application - DidBecomeActive               <User exists native pay sheet
    Jul 22 18:01:31  💰 User Canceled Purchase                      <Purchases.shared.purchasePackage returned userCancelled == true
    Jul 22 18:01:31  🎁 Premium Popup: User Cancel
    Jul 22 18:01:32  ⛓ Got Branch params: [AnyHashable("+is_first_session"): 0, AnyHashable("+clicked_branch_link"): 0]
    Jul 22 18:01:33  💰 Initiating Purchase: ***
    Jul 22 18:01:33  💰 Purchase State: .purchasing
    Jul 22 18:01:34  🚀 Application - WillResignActive
    Jul 22 18:20:21  🚀 Application - DidBecomeActive‰‰
    ...
    Jul 22 18:20:21  ⛓ Got Branch params: [AnyHashable("+clicked_branch_link"): 0, AnyHashable("+is_first_session"): 0]
    Jul 22 18:20:40  🎁 Saw Sell page flow: scanFooter(index: 1), sku: ***
    Jul 22 18:20:46  💰 Initiating Purchase: ***
    Jul 22 18:20:46  💰 🔥🔥🔥 Purchase Error: {Unknown Error Type}: Type: NSError, Description: Purchase already in progress for this product.
    Jul 22 18:20:46  💰 🔥 Rcat: operationAlreadyInProgressError
    Jul 22 18:20:46  🎁 Premium Popup: 🔥 Other Error!
    Jul 22 18:20:46  🔥🔥🔥 PRODUCTION NON-FATAL ERROR: Other error in PremiumSellVC
    Jul 22 18:20:46  🔥🔥🔥 PURCHASE: DEFAULT ERROR! Type: {Unknown Error Type}: Type: NSError, Description: Purchase already in progress for this product., typeString: operationAlreadyInProgressError 
    

    In every case a user starts, then cancels (sometimes up to 3 times) and then becomes unable to purchase going forward until force quitting/relaunching the app. We've had RevCat for a while and haven't seen this problem until our most recent version with the 3.5.0 SDK. Is it possible canceled transactions aren't getting cleared intermittently?

    bug next_release 
    opened by RamblinWreck77 18
  • [macOS] Purchases.purchasePackage returns userCancelled == false when clicking on Cancel in Confirm Subscription popup

    [macOS] Purchases.purchasePackage returns userCancelled == false when clicking on Cancel in Confirm Subscription popup

    Common project specific issues

    Describe the bug A clear and concise description of what the bug is. The more detail you can provide the faster our team will be able to triage and resolve the issue.

    1. Environment
      1. Platform: macOS
      2. SDK version: 10.15.6 (19G68)
      3. OS version: Big Sur - 11.0 Beta (20A5384c)
      4. Xcode version: 12.0.1
      5. How widespread is the issue. 100%
    2. Debug logs 

    <SKPaymentQueue: 0x6000015cd740>: Payment completed with error: Error Domain=ASDServerErrorDomain Code=5115 "The server encountered an error" UserInfo={NSLocalizedDescription=The server encountered an error} [Purchases] - DEBUG: PaymentQueue updatedTransaction: P1Y.mac_app_store_trial_1 (null) (Error Domain=SKErrorDomain Code=0 "UNKNOWN_ERROR" UserInfo={NSLocalizedDescription=UNKNOWN_ERROR, NSUnderlyingError=0x6000018cd260 {Error Domain=ASDServerErrorDomain Code=5115 "The server encountered an error" UserInfo={NSLocalizedDescription=The server encountered an error}}}) (null) - 2 [Purchases] - ERROR: There was a problem with the App Store.

    1. Steps to reproduce, with a description of expected vs. actual behavior

    Steps to reproduce:

    1. Click on Cancel in either the Subscription Terms screen or Confirm Subscription screen

    image

    image

    Expected outcome:

    • Returns 'userCancelled == true'

    Actual:

    • Returns userCancelled == false and error:

    image

    sharpen the saw triaged 
    opened by iPile 17
  • Improve Swift Concurrency support

    Improve Swift Concurrency support

    We're using Swift Concurrency in a few places. There are a couple of compiler flags that help prevent issues with Swift Concurrency, that we should leverage.

    The flags are -Xfrontend -warn-concurrency -Xfrontend -enable-actor-data-race-checks

    And can be enabled in Xcode -> RevenueCat Project -> RevenueCat target -> Build Settings -> Other Swift Flags.

    image

    Enabling them fires up a few warnings and errors. We should enable the compiler flags, and fix the warnings / errors. More context here: https://forums.swift.org/t/concurrency-in-swift-5-and-6/49337

    https://app.shortcut.com/revenuecat/story/11686/enable-swift-compiler-flags-for-concurrency-and-fix-errors

    enhancement triaged 
    opened by aboedo 16
  • [AUTOMATIC] Release/4.13.0

    [AUTOMATIC] Release/4.13.0

    This is an automatic release.

    Bugfixes

    • StoreKit 1: changed result of cancelled purchases to be consistent with StoreKit 2 (#1910) via NachoSoto (@NachoSoto)
    • PaymentQueueWrapper: handle promotional purchase requests from App Store when SK1 is disabled (#1901) via NachoSoto (@NachoSoto)

    New Features

    • StoreKit 2: enabled by default (#1922) via NachoSoto (@NachoSoto)
    • Extracted PurchasesType and PurchasesSwiftType (#1912) via NachoSoto (@NachoSoto)

    Other Changes

    • Fixed iOS 12 tests (#1936) via NachoSoto (@NachoSoto)
    • CacheableNetworkOperation: fixed race condition in new test (#1932) via NachoSoto (@NachoSoto)
    • BasePurchasesTests: changed default back to SK1 (#1935) via NachoSoto (@NachoSoto)
    • Logger: refactored default LogLevel definition (#1934) via NachoSoto (@NachoSoto)
    • AppleReceipt: refactored declarations into nested types (#1933) via NachoSoto (@NachoSoto)
    • Integration Tests: relaunch tests when retrying failures (#1925) via NachoSoto (@NachoSoto)
    • CircleCI: downgraded release jobs to Xcode 13.x (#1927) via NachoSoto (@NachoSoto)
    • ErrorUtils: added test to verify that PublicErrors can be catch'd as ErrorCode (#1924) via NachoSoto (@NachoSoto)
    • StoreKitIntegrationTests: print AppleReceipt data whenever verifyEntitlementWentThrough fails (#1929) via NachoSoto (@NachoSoto)
    • OperationQueue: log debug message when requests are found in cache and skipped (#1926) via NachoSoto (@NachoSoto)
    • GetCustomerInfoAPI: avoid making a request if there's any PostReceiptDataOperation in progress (#1911) via NachoSoto (@NachoSoto)
    • PurchaseTester: allow HTTP requests and enable setting ProxyURL (#1917) via NachoSoto (@NachoSoto)
    next_release 
    opened by NachoSoto 1
  • `ProductsFetcherSK2`: removed now redundant caching logic

    `ProductsFetcherSK2`: removed now redundant caching logic

    Follow up to #1907.

    This logic is now implemented and shared in CachingProductsManager.

    I've decided to keep the logic in ProductsFetcherSK1 because it's intertwined with the retry mechanism, and it wasn't trivial to remove caching while leaving that logic.

    refactor 
    opened by NachoSoto 0
  • Created `CachingProductsManager` to provide consistent caching logic when fetching products

    Created `CachingProductsManager` to provide consistent caching logic when fetching products

    Goal

    The main feature that this change introduces is providing a request cache to ProductsFetcherSK2 (like ProductsFetcherSK1 has). It already implements a product cache, but concurrent requests for the same products result in fetching those multiple times. It does not cache products until they're done being fetched.

    This was observed in the logs when doing something simple like purchasing a product. This is running testCanPurchaseProduct integration test:

    DEBUG: ℹ️ No existing products cached, starting store products request for: ["com.revenuecat.monthly_4.99.1_week_intro", "com.revenuecat.annual_39.99.2_week_intro", "com.revenuecat.weekly_1.99.3_day_intro"] DEBUG: ℹ️ No existing products cached, starting store products request for: ["com.revenuecat.monthly_4.99.1_week_intro", "com.revenuecat.annual_39.99.2_week_intro", "com.revenuecat.weekly_1.99.3_day_intro"] DEBUG: 😻 Store products request request received response DEBUG: ℹ️ Store products request finished DEBUG: 😻 Store products request request received response DEBUG: ℹ️ Store products request finished

    With this PR, we avoid the double request due to that race condition:

    DEBUG: ℹ️ No existing products cached, starting store products request for: ["com.revenuecat.annual_39.99.2_week_intro", "com.revenuecat.weekly_1.99.3_day_intro", "com.revenuecat.monthly_4.99.1_week_intro"] DEBUG: 😻 Store products request request received response DEBUG: ℹ️ Store products request finished

    How

    Instead of implementing that logic only on ProductsFetcherSK2 or in ProductsManager, this aims to keep the implementation simple in ProductsManager and each of the fetchers, and instead uses the decorator pattern to provide that new functionality in a way that's simple to test and maintain, independent of the logic for actually fetching products.

    To accomplish that, this adds a new protocol: ProductsManagerType, with 2 main methods (more about why the need for an SK2 special method below):

    /// Fetches the ``StoreProduct``s with the given identifiers
    /// The returned products will be SK1 or SK2 backed depending on the implementation and configuration.
    func products(withIdentifiers identifiers: Set<String>, completion: @escaping Completion)
    
    /// Fetches the `SK2StoreProduct`s with the given identifiers.
    @available(iOS 15.0, tvOS 15.0, watchOS 8.0, macOS 12.0, *)
    func sk2Products(withIdentifiers identifiers: Set<String>, completion: @escaping SK2Completion)
    

    Those are only completion-block APIs. To avoid repetition, an extension on the protocol itself provides an async API, wrapping on top of these 2 methods, regardless of which ProductsManagerType they're being used on.

    The hierarchy is now as follows:

    • CachingProductsManager
      • ProductsManager
        • ProductsFetcherSK1
        • ProductsFetcherSK2

    #1908 gets rid of the now duplicate caching logic in ProductsManager and the fetchers.

    Other notes

    What makes the implementation a bit more convoluted is the need for a special SK2 method. This is necessary specifically for TrialOrIntroPriceEligibilityChecker which requires fetching only SK2 products regardless of StoreKit2Setting. In order to guarantee this invariant at compile time through types, a separate cache is maintained with SK2StoreProducts. However, the main caching logic is not duplicated and instead shared for both.

    The main tests for CachingProductsManager are simple unit tests that don't make use of StoreKitConfigTestCase. Because creating SK2 products does require that, I added a separate test class for those.

    Future changes

    The caching logic is very simple, just like what we had for the fetchers. One missing piece is that if products A and B are requested, and only A is in the cache, this is treated as a complete cache miss.

    The fetchers had the same problem, but now that this caching logic is isolated and much easier to test, we can evolve and solve that feature in a more maintainable way.

    perf 
    opened by NachoSoto 0
  • Has any one meet `Cached appUserID has been deleted from user defaults.` crash on iOS16?

    Has any one meet `Cached appUserID has been deleted from user defaults.` crash on iOS16?

    Describe the bug A clear and concise description of what the bug is. The more detail you can provide the faster our team will be able to triage and resolve the issue. Do not remove any of the steps from the template below. If a step is not applicable to your issue, please leave that step empty.

    1. Environment
      1. Platform: iOS
      2. SDK version: 4
      3. StoreKit 2 (enabled with useStoreKit2IfEnabled) (Y/N): Y
      4. OS version: iOS16
      5. Xcode version: Xcode14

    Additional context Add any other context about the problem here.

    RevenueCat/DeviceCache.swift:70: Fatal error: [Purchases] - Cached appUserID has been deleted from user defaults. This leaves the SDK in an undetermined state. Please make sure that RevenueCat entries in user defaults don't get deleted by anything other than the SDK. More info: https://rev.cat/userdefaults-crash
    
    0x3820c _assertionFailure(_:_:file:line:flags:) + 312
    1  Grow                           0x95260c DeviceCache.handleUserDefaultsChanged(notification:) + 4388398604 (<compiler-generated>:4388398604)
    2  Grow                           0x95267c @objc DeviceCache.handleUserDefaultsChanged(notification:) + 4388398716 (<compiler-generated>:4388398716)
    3  CoreFoundation                 0x377c4 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 148
    4  CoreFoundation                 0xde75c ___CFXRegistrationPost_block_invoke + 88
    5  CoreFoundation                 0xc1a34 _CFXRegistrationPost + 440
    6  CoreFoundation                 0x4bdc8 _CFXNotificationPost + 704
    7  Foundation                     0x5c4dc -[NSNotificationCenter postNotificationName:object:userInfo:] + 92
    8  Grow                           0x957aa0 specialized static DeviceCache.deleteSyncedSubscriberAttributesForOtherUsers(_:) + 4388420256 (<compiler-generated>:4388420256)
    9  Grow                           0xa055c8 specialized IdentityManager.init(deviceCache:backend:customerInfoManager:attributeSyncing:appUserID:) + 43 (SynchronizedUserDefaults.swift:43)
    10 Grow                           0xa08018 specialized Purchases.__allocating_init(apiKey:appUserID:userDefaults:observerMode:platformInfo:storeKit2Setting:storeKitTimeout:networkTimeout:dangerousSettings:) + 24 (TransactionsManager.swift:24)
    11 Grow                           0xa099bc specialized static Purchases.configure(with:) + 4389149116 (<compiler-generated>:4389149116)
    12 Grow                           0x3d4880 specialized static AppConfig.configApps(_:didFinishLaunchingWithOptions:) + 42 (AppConfig.swift:42)
    13 Grow                           0x4287a0 specialized AppDelegate.application(_:didFinishLaunchingWithOptions:) + 4382984096 (<compiler-generated>:4382984096)
    14 Grow                           0x4256bc @objc AppDelegate.application(_:didFinishLaunchingWithOptions:) + 4382971580 (<compiler-generated>:4382971580)
    15 UIKitCore                      0x35af40 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 300
    16 UIKitCore                      0x35a664 -[UIApplication _callInitializationDelegatesWithActions:forCanvas:payload:fromOriginatingProcess:] + 2848
    17 UIKitCore                      0x359640 -[UIApplication _runWithMainScene:transitionContext:completion:] + 856
    18 UIKitCore                      0x3592b8 -[_UISceneLifecycleMultiplexer completeApplicationLaunchWithFBSScene:transitionContext:] + 176
    19 UIKitCore                      0x3a3d0c -[UIApplication _compellApplicationLaunchToCompleteUnconditionally] + 48
    20 UIKitCore                      0x3a2d64 -[UIApplication _run] + 852
    21 UIKitCore                      0x3a29ec UIApplicationMain + 340
    22 libswiftUIKit.dylib            0x352a0 UIApplicationMain(_:_:_:_:) + 104
    23 Grow                           0xa1d0 main + 4378665424 (HabitType+Extension.swift:4378665424)
    24 ???                            0x1b668d948 (缺少)
    
    bug 
    opened by alfredcc 11
  • Enable SSL Pinning to prevent MitM attack

    Enable SSL Pinning to prevent MitM attack

    Hi RevenueCat creators,

    I've tried https://app.revenuecat.com/settings/support but didn't hear back, this is still an issue, and I am seeing things are getting worse.

    RevenueCat's HTTPClient doesn't support SSL Pinning, which means responses returned from RC's server can be easily modified by MitM attacks, and there're lots of network debug tools to do this, majority of them are heavily used for piracy.

    Here are just some examples:

    • https://github.com/89996462/Storm-Sniffer
    • https://github.com/nzw9314/Surge/blob/master/Module/Script_All_in_one.sgmodule
    • https://github.com/Angelalisa-x/Loon/blob/master/Script.conf
    • https://github.com/guzhig/QuantumultX/blob/master/Scripts.conf

    Another thread on Twitter: https://twitter.com/icodesign_me/status/1352133580030296064

    Any chance we can get SSL Pinning added? My understanding is that it should be a trivial effort but can help lots of indie devs.

    On the other hand, I think this can help RevenueCat too, a platform that is related to money should have higher level of security, then it will be trusted by more devs and teams.

    enhancement 
    opened by cyanzhong 4
  • Bug: CheckTrialOrIntroDiscountEligibility too slow

    Bug: CheckTrialOrIntroDiscountEligibility too slow

    Describe the bug Add any other context about the problem here.

    We are using checkTrialOrIntroDiscountEligibility in iOS with swift  after get the product, and we notice that this call is too slow (even 45s - 1 min). 

    Purchases.shared.checkTrialOrIntroDiscountEligibility(productIdentifiers: ["productIdentifier"]) { result in
    ....
    }
    
    1. Environment
      1. Platform: iOS
      2. SDK version: 4.10
      3. StoreKit 2 (enabled with useStoreKit2IfEnabled) (Y/N): N
      4. OS version: 15.5
      5. Xcode version: 13.4.1
      6. How widespread is the issue. Percentage of devices affected: Unknown/Random Additional context

    Environment: Real device & simulator. iOS 15.5 SDK Version: "4.10.0" Code that is too slow

    Purchases.shared.checkTrialOrIntroDiscountEligibility(productIdentifiers: ["productIdentifier"]) { result in
    ....
    }
    
    bug 
    opened by jesus-mg-ios 7
Releases(4.12.1)
  • 4.12.1(Sep 23, 2022)

    Bugfixes

    • Purchases.beginRefundRequest: ensured errors are PublicError (#1913) via NachoSoto (@NachoSoto)
    • PurchaseTesterSwiftUI: fixed macOS target (#1915) via NachoSoto (@NachoSoto)

    Other Changes

    • Fixed tvOS tests (#1928) via NachoSoto (@NachoSoto)
    • SnapshotTesting: require version 1.9.0 to keep supporting iOS 12/13 tests (#1931) via NachoSoto (@NachoSoto)
    • pre-commit hook: also verify leftover API keys in PurchaseTester (#1914) via NachoSoto (@NachoSoto)
    • CircleCI: changed iOS 12/13 to use Xcode 13 (#1918) via NachoSoto (@NachoSoto)
    • PurchaseTesterSwiftUI: removed unnecessary UIApplicationDelegate (#1916) via NachoSoto (@NachoSoto)
    • CircleCI: changed all jobs to use Xcode 14 (#1909) via NachoSoto (@NachoSoto)
    • Atomic: added unit test to verify value's setter (#1905) via NachoSoto (@NachoSoto)
    • spm build CI job: changed to release build (#1903) via NachoSoto (@NachoSoto)
    • StoreKitUnitTests: compile on iOS 11.0+ (#1904) via NachoSoto (@NachoSoto)
    • Purchases: only expose testing data on DEBUG (#1902) via NachoSoto (@NachoSoto)
    • Integration Tests: added test to verify re-subscription behavior (#1898) via NachoSoto (@NachoSoto)
    • IntegrationTests: simplified testExpireSubscription to fix flaky test (#1899) via NachoSoto (@NachoSoto)
    • Integration Tests: actually verify that entitlement is active (#1880) via NachoSoto (@NachoSoto)
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(51.99 MB)
    RevenueCat.xcframework.zip(161.66 MB)
  • 4.12.0(Sep 8, 2022)

    Note:

    ⚠️ ⚠️ This version does not support promoted purchases initiated directly from the App Store when StoreKit 2 is enabled. we’re working on a hotfix to address this (#1901). In the meantime, you can stick with 4.11.0 if you’re using promoted purchases.

    Bugfixes

    • watchOS: fixed crash when ran on single-target apps with Xcode 14 and before watchOS 9.0 (#1895) via NachoSoto (@NachoSoto)
    • CustomerInfoManager/OfferingsManager: improved display of underlying errors (#1888) via NachoSoto (@NachoSoto)
    • Offering: improved confusing log for PackageType.custom (#1884) via NachoSoto (@NachoSoto)
    • PurchasesOrchestrator: don't log warning if allowSharingAppStoreAccount setting was never explicitly set (#1885) via NachoSoto (@NachoSoto)
    • Introduced type-safe PurchasesError and fixed some incorrect returned error types (#1879) via NachoSoto (@NachoSoto)
    • CustomerInfoManager: fixed thread-unsafe implementation (#1878) via NachoSoto (@NachoSoto)

    New Features

    • Disable SK1's StoreKitWrapper if SK2 is enabled and available (#1882) via NachoSoto (@NachoSoto)
    • Sendable support (#1795) via NachoSoto (@NachoSoto)

    Other Changes

    • Renamed StoreKitWrapper to StoreKit1Wrapper (#1886) via NachoSoto (@NachoSoto)
    • Enabled DEAD_CODE_STRIPPING (#1887) via NachoSoto (@NachoSoto)
    • HTTPClient: added X-Client-Bundle-ID and logged on SDK initialization (#1883) via NachoSoto (@NachoSoto)
    • add link to SDK reference (#1872) via Andy Boedo (@aboedo)
    • Added StoreKit2Setting.shouldOnlyUseStoreKit2 (#1881) via NachoSoto (@NachoSoto)
    • Introduced TestLogHandler to simplify how we test logged messages (#1858) via NachoSoto (@NachoSoto)
    • Integration Tests: added test for purchasing StoreProduct instead of Package (#1875) via NachoSoto (@NachoSoto)
    • ErrorUtils: added test to verify that returned errors can be converted to ErrorCode (#1871) via NachoSoto (@NachoSoto)
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(52.00 MB)
    RevenueCat.xcframework.zip(161.66 MB)
  • 4.11.0(Aug 30, 2022)

  • 4.10.3(Aug 26, 2022)

    Bugfixes

    • TrialOrIntroPriceEligibilityChecker: return .noIntroOfferExists if the product has no introductory offer (#1859) via NachoSoto (@NachoSoto)
    • watchOS: fixed crash on single-target apps (#1849) via NachoSoto (@NachoSoto)

    Other Changes

    • Update fastlane-plugin-revenuecat_internal and fix release-train job (#1866) via Cesar de la Vega (@vegaro)
    • fix typo in comment (#1863) via Andy Boedo (@aboedo)
    • Use Dangerfile repository (#1864) via Cesar de la Vega (@vegaro)
    • CircleCI: added job for building SDK with SPM (#1860) via NachoSoto (@NachoSoto)
    • Lock: changed default implementation to use NSLock (#1819) via NachoSoto (@NachoSoto)
    • Offering/StoreProductType: Sendable conformance (#1826) via NachoSoto (@NachoSoto)
    • ReceiptParser: Sendable conformance (#1825) via NachoSoto (@NachoSoto)
    • CustomerInfo: Sendable conformance (#1824) via NachoSoto (@NachoSoto)
    • Added Collection.onlyElement (#1857) via NachoSoto (@NachoSoto)
    • README updates (#1856) via rglanz-rc (@rglanz-rc)
    • IntegrationTests: actually fail test if tests aren't configured (#1855) via NachoSoto (@NachoSoto)
    • Configuration.with(usesStoreKit2IfAvailable:): removed "experimental" warning (#1845) via NachoSoto (@NachoSoto)
    • Build fix- Update package requirements for MagicWeather (#1852) via Joshua Liebowitz (@taquitos)
    • Fastfile: test_tvos lane had duplicate parameter (#1846) via NachoSoto (@NachoSoto)
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(51.48 MB)
    RevenueCat.xcframework.zip(160.24 MB)
  • 4.10.2(Aug 19, 2022)

    Bugfixes

    • ErrorResponse: don't add attribute errors to message if empty (#1844) via NachoSoto (@NachoSoto)
    • Purchase cancellations: unify behavior between SK1 and SK2 (#1841) via NachoSoto (@NachoSoto)
    • StoreKit 2: PurchasesOrchestrator: don't log "purchased product" if it was cancelled (#1840) via NachoSoto (@NachoSoto)
    • Backend: fixed potential race conditions introduced by OperationDispatcher.dispatchOnWorkerThread(withRandomDelay:) (#1827) via NachoSoto (@NachoSoto)
    • DeviceCache: Sendable conformance and fixed thread-safety (#1823) via NachoSoto (@NachoSoto)
    • Directly send delegate customer info when delegate is set (always sends cached CustomerInfo value) (#1828) via Josh Holtz (@joshdholtz)
    • SystemInfo.finishTransactions: made thread-safe (#1807) via NachoSoto (@NachoSoto)
    • Purchases.shared and Purchases.isConfigured are now thread-safe (#1813) via NachoSoto (@NachoSoto)
    • PriceFormatterProvider: Sendable conformance and fixed thread-safety (#1818) via NachoSoto (@NachoSoto)
    • StoreKitConfigTestCase.changeStorefront: re-enabled on iOS 16 (#1811) via NachoSoto (@NachoSoto)

    Other Changes

    • DeviceCache: no longer set cache timestamp before beginning request (#1839) via NachoSoto (@NachoSoto)
    • MagicWeatherSwiftUI: updated to use async APIs (#1843) via NachoSoto (@NachoSoto)
    • Release train (#1842) via Cesar de la Vega (@vegaro)
    • Adds hotfixes section to RELEASING doc (#1837) via Cesar de la Vega (@vegaro)
    • Update fastlane plugin (#1838) via Toni Rico (@tonidero)
    • Update migration doc from didReceiveUpdatedCustomerInfo to receivedUpdatedCustomerInfo (#1836) via Josh Holtz (@joshdholtz)
    • PurchasesDelegate: added test for latest cached customer info always being sent (#1830) via NachoSoto (@NachoSoto)
    • CallbackCache: Sendable conformance (#1835) via NachoSoto (@NachoSoto)
    • CallbackCache: simplified implementation using Atomic (#1834) via NachoSoto (@NachoSoto)
    • PurchasesLogInTests: added test to verify logIn updates offerings cache (#1833) via NachoSoto (@NachoSoto)
    • Created PurchasesLoginTests (#1832) via NachoSoto (@NachoSoto)
    • SwiftLint: cleaned up output (#1821) via NachoSoto (@NachoSoto)
    • Link to sdk reference (#1831) via aboedo (@aboedo)
    • Atomic: ExpressibleByBooleanLiteral (#1822) via NachoSoto (@NachoSoto)
    • SwiftLint: fixed build warning (#1820) via NachoSoto (@NachoSoto)
    • Adds an approval job that will tag the release (#1815) via Cesar de la Vega (@vegaro)
    • Atomic: ExpressibleByNilLiteral (#1804) via NachoSoto (@NachoSoto)
    • PurchasesAttributionDataTests: fixed potential race condition in flaky test (#1805) via NachoSoto (@NachoSoto)
    • Fixed warnings for unnecessary try (#1816) via NachoSoto (@NachoSoto)
    • Moved AttributionFetcherError inside AttributionFetcher (#1808) via NachoSoto (@NachoSoto)
    • Update documentation for presentCodeRedemptionSheet (#1817) via Joshua Liebowitz (@taquitos)
    • Dangerfile: added "next_release" as supported label (#1810) via NachoSoto (@NachoSoto)
    • PurchaseTester- Update Podfile.lock (#1814) via Joshua Liebowitz (@taquitos)
    • Update to latest fastlane plugin (#1802) via Toni Rico (@tonidero)
    • Clean up: moved BackendIntegrationTests.xctestplan to TestPlans folder (#1812) via NachoSoto (@NachoSoto)
    • SK2StoreProduct: conditionally removed @available workaround (#1794) via NachoSoto (@NachoSoto)
    • SwiftLint: fixed deprecation warning (#1809) via NachoSoto (@NachoSoto)
    • Update gems (#1791) via Joshua Liebowitz (@taquitos)
    • Replace usages of replace_in with replace_text_in_files action (#1803) via Toni Rico (@tonidero)
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(51.49 MB)
    RevenueCat.xcframework.zip(160.24 MB)
  • 4.10.1(Aug 15, 2022)

  • 4.10.0(Aug 8, 2022)

    New Features

    • New AdServices Integration (#1727) via Josh Holtz (@joshdholtz)

    Bugfixes

    • OfferingsManager: expose underlying error when ProductsManager returns an error (#1792) via NachoSoto (@NachoSoto)
    • Add missing logs to ProductsFetcherSK2 (#1780) via beylmk (@beylmk)

    Other Changes

    • AdServices: Fix failing tests on main in iOS 12 and 13 - IOSAttributionPosterTests (#1797) via Josh Holtz (@joshdholtz)
    • Invalidates gem caches and separates danger and macOS caches (#1798) via Cesar de la Vega (@vegaro)
    • Pass CircleCI branch to prepare_next_version job (#1796) via Toni Rico (@tonidero)
    • Configure Danger, enforce labels (#1761) via Cesar de la Vega (@vegaro)
    • Support for new fastlane internal plugin for automation (#1779) via Toni Rico (@tonidero)
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(51.26 MB)
    RevenueCat.xcframework.zip(159.38 MB)
  • 4.9.1-adservices.beta.2(Aug 4, 2022)

    ⚠️ ⚠️ ⚠️ Please do not use this version unless you have been in communication with the RevenueCat team about joining the AdServices beta. This functionality will not work otherwise, as it requires special RevenueCat setup. ⚠️ ⚠️ ⚠️

    AdServices Beta

    New method: Purchases.shared.attribution.enableAdServicesAttributionTokenCollection() to be called after configuration and after successful permission request (if advanced data is desired).

    Please refer to the docs for detailed information on setup.

    Source code(tar.gz)
    Source code(zip)
  • 4.9.1(Aug 1, 2022)

    Fixes:

    • CustomerInfoResponseHandler: return CustomerInfo instead of error if the response was successful (#1778) via NachoSoto (@NachoSoto)
    • Error logging: logErrorIfNeeded no longer prints message if it's the same as the error description (#1776) via NachoSoto (@NachoSoto)
    • fix another broken link in docC docs (#1777) via aboedo (@aboedo)
    • fix links to restorePurchase (#1775) via aboedo (@aboedo)
    • fix getProducts docs broken link (#1772) via aboedo (@aboedo)

    Improvements:

    • Logger: wrap message in @autoclosure to avoid creating when LogLevel is disabled (#1781) via NachoSoto (@NachoSoto)

    Other changes:

    • Lint: fixed SubscriberAttributesManager (#1774) via NachoSoto (@NachoSoto)
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(50.46 MB)
    RevenueCat.xcframework.zip(157.31 MB)
  • 4.9.0(Jul 13, 2022)

  • 4.8.0(Jul 12, 2022)

    New API

    • EntitlementInfo: added isActiveInCurrentEnvironment and isActiveInAnyEnvironment (#1755) via NachoSoto (@NachoSoto)

    Other Changes

    • Plumb platformInfo in Configuration for PHC use (#1757) via Joshua Liebowitz (@taquitos)
    • added a log when autoSyncPurchases is disabled (#1749) via aboedo (@aboedo)
    • Re-fetch cached offerings and products after Storefront changes (3/4) (#1743) via Juanpe Catalán (@Juanpe)
    • bug_report.md: clarify SK2 support (#1752) via NachoSoto (@NachoSoto)
    • logErrorIfNeeded: also log message if present (#1754) via NachoSoto (@NachoSoto)
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(49.55 MB)
    RevenueCat.xcframework.zip(154.73 MB)
  • 4.7.0-adservices.beta.1(Jul 7, 2022)

    ⚠️ ⚠️ ⚠️ Please do not use this version unless you have been in communication with the RevenueCat team about joining the AdServices beta. This functionality will not work otherwise, as it requires special RevenueCat setup. ⚠️ ⚠️ ⚠️

    AdServices Beta

    New method: Purchases.shared.attribution.enableAdServicesAttributionTokenCollection() to be called after configuration and after successful permission request (if advanced data is desired).

    Please refer to the docs for detailed information on setup.

    Source code(tar.gz)
    Source code(zip)
  • 4.7.0(Jul 4, 2022)

    This release is compatible with Xcode 14 beta 2

    Changes:

    • Replaced CustomerInfo.nonSubscriptionTransactions with a new non-StoreTransaction type (#1733) via NachoSoto (@NachoSoto)
    • Purchases.configure: added overload taking a Configuration.Builder (#1720) via NachoSoto (@NachoSoto)
    • Extract Attribution logic out of Purchases (#1693) via Joshua Liebowitz (@taquitos)
    • Remove create alias (#1695) via Joshua Liebowitz (@taquitos)

    All attribution APIs can now be accessed from Purchases.shared.attribution.

    Improvements:

    • Improved purchasing logs, added promotional offer information (#1725) via NachoSoto (@NachoSoto)
    • PurchasesOrchestrator: don't log attribute errors if there are none (#1742) via NachoSoto (@NachoSoto)
    • FatalErrorUtil: don't override fatalError on release builds (#1736) via NachoSoto (@NachoSoto)
    • SKPaymentTransaction: added more context to warnings about missing properties (#1731) via NachoSoto (@NachoSoto)
    • New SwiftUI Purchase Tester example (#1722) via Josh Holtz (@joshdholtz)
    • update docs for showManageSubscriptions (#1729) via aboedo (@aboedo)
    • PurchasesOrchestrator: unify finish transactions between SK1 and SK2 (#1704) via NachoSoto (@NachoSoto)
    • SubscriberAttribute: converted into struct (#1648) via NachoSoto (@NachoSoto)
    • CacheFetchPolicy.notStaleCachedOrFetched: added warning to docstring (#1708) via NachoSoto (@NachoSoto)
    • Clear cached offerings and products after Storefront changes (2/4) (#1583) via Juanpe Catalán (@Juanpe)
    • ROT13: optimized initialization and removed magic numbers (#1702) via NachoSoto (@NachoSoto)

    Fixes:

    • logIn/logOut: sync attributes before aliasing (#1716) via NachoSoto (@NachoSoto)
    • Purchases.customerInfo(fetchPolicy:): actually use fetchPolicy parameter (#1721) via NachoSoto (@NachoSoto)
    • PurchasesOrchestrator: fix behavior dealing with nil SKPaymentTransaction.productIdentifier during purchase (#1680) via NachoSoto (@NachoSoto)
    • PurchasesOrchestrator.handlePurchasedTransaction: always refresh receipt data (#1703) via NachoSoto (@NachoSoto)
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(49.25 MB)
    RevenueCat.xcframework.zip(153.83 MB)
  • 4.6.1(Jun 10, 2022)

    This release is compatible with Xcode 14 beta 1

    Bug fixes

    • EntitlementInfo.isActive returns true if requestDate == expirationDate (#1684) via beylmk (@beylmk)
    • Fixed usages of seealso (#1689) via NachoSoto (@NachoSoto)
    • Fixed ROT13.string thread-safety (#1686) via NachoSoto (@NachoSoto)
    • PurchasesOrchestrator: replaced calls to syncPurchases with posting receipt for an individual product during SK2 purchases (#1666) via NachoSoto (@NachoSoto)
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(48.74 MB)
    RevenueCat.xcframework.zip(152.19 MB)
  • 4.6.0(Jun 9, 2022)

    This release is compatible with Xcode 14 beta 1

    New Features

    • EntitlementInfos: added activeInAnyEnvironment and activeInCurrentEnvironment (#1647) via NachoSoto (@NachoSoto)

    In addition to EntitlementInfos.active, two new methods are added to allow detecting entitlements from sandbox and production environments:

    customerInfo.entitlements.activeInCurrentEnvironment
    customerInfo.entitlements.activeInAnyEnvironment
    

    Bug fixes

    • MacDevice: changed usage of kIOMasterPortDefault to fix Catalyst compilation on Xcode 14 (#1676) via NachoSoto (@NachoSoto)
    • Result.init(value:error:): avoid creating error if value is provided (#1672) via NachoSoto (@NachoSoto)
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(48.75 MB)
    RevenueCat.xcframework.zip(152.20 MB)
  • 4.5.2(Jun 8, 2022)

    This version supports Xcode 14 beta 1

    • PurchasesOrchestrator.handleDeferredTransaction: check NSError.domain too (#1665) via NachoSoto (@NachoSoto)
    • PurchasesOrchestrator: replaced manual Lock with Atomic (#1664) via NachoSoto (@NachoSoto)
    • CodableStrings.decoding_error: added underlying error information (#1668) via NachoSoto (@NachoSoto)
    • Fixed Xcode 14 compilation: avoid @available properties (#1661) via NachoSoto (@NachoSoto)
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(48.48 MB)
    RevenueCat.xcframework.zip(151.53 MB)
  • 4.5.1(Jun 3, 2022)

    Fixes

    • Fixes a critical issue in 4.4.0 and 4.5.0 where entitlement identifiers and product identifiers would get converted to snake case and returned as empty. https://github.com/RevenueCat/purchases-ios/pull/1651 https://github.com/RevenueCat/purchases-ios/issues/1650

    Changes from 4.5.0

    New Features

    • Purchases.customerInfo(): added overload with a new CacheFetchPolicy (#1608) via NachoSoto (@NachoSoto)
    • Storefront: added sk1CurrentStorefront for Objective-C (#1614) via NachoSoto (@NachoSoto)

    Bug Fixes

    • Fix for not being able to read receipts on watchOS (#1625) via Patrick Busch (@patrickbusch)

    Other Changes

    • Added tests for PurchasesOrchestrator invoking listenForTransactions only if SK2 is enabled (#1618) via NachoSoto (@NachoSoto)
    • PurchasesOrchestrator: removed lazy hack for properties with @available (#1596) via NachoSoto (@NachoSoto)
    • PurchasesOrchestrator.purchase(sk2Product:promotionalOffer:): simplified implementation with new operator (#1602) via NachoSoto (@NachoSoto)
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(48.98 MB)
    RevenueCat.xcframework.zip(152.77 MB)
  • 4.4.1(Jun 3, 2022)

    Fixes

    • Fix a critical issue in 4.4.0 where entitlement identifiers and product identifiers would get converted to snake case and returned as empty. https://github.com/RevenueCat/purchases-ios/pull/1651 https://github.com/RevenueCat/purchases-ios/issues/1650

    Changes from 4.4.0

    Configuration updates:

    • You can now use a Configuration object to configure the SDK with a cleaner syntax. Example of how to configure using Configuration:
     Purchases.configure(
         with: Configuration.Builder(withAPIKey: Constants.apiKey)
                  .with(usesStoreKit2IfAvailable: true)
                  .with(observerMode: false)
                  .with(appUserID: "<app_user_id>")
                  .build()
         )
    

    ⚠️ The configure(withAPIKey:appUserID:) method and its overloads have been deprecated in favor of using configure(with:) and passing in a Configuration.

    New Features

    • Added new API key validation (#1581) via NachoSoto (@NachoSoto)
    • Sending X-Is-Sandbox header in API requests (#1582) via NachoSoto (@NachoSoto)
    • Added AmazonStore to Store enum (#1586) via Will Taylor (@fire-at-will)
    • Added Configuration object and API to configure Purchases (#1556) via Joshua Liebowitz (@taquitos)
    • Exposed shouldShowPriceConsent on PurchasesDelegate (#1520) via Joshua Liebowitz (@taquitos)

    Fixes

    • ManageSubscriptionsHelper: fixed discrepancy between SystemInfo.isAppleSubscription(managementURL:) and SystemInfo.appleSubscriptionsURL (#1607) via NachoSoto (@NachoSoto)
    • PurchasesOrchestrator: don't listen for StoreKit 2 transactions if it's disabled (#1593) via NachoSoto (@NachoSoto)
    • Added tests and fix to ensure RawDataContainer includes all data (#1565) via NachoSoto (@NachoSoto)
    • Added obsoletion for DeferredPromotionalPurchaseBlock (#1600) via NachoSoto (@NachoSoto)
    • StoreKit 2 purchases: don't throw when purchase is cancelled (#1603) via NachoSoto (@NachoSoto)
    • Ensure SubscriptionPeriods are represented as 1week instead of 7days (#1591) via Will Taylor (@fire-at-will)
    • PurchaseStrings: fixed transaction message formatting (#1571) via NachoSoto (@NachoSoto)
    • willRenew update comment for lifetime will be false (#1579) via Josh Holtz (@joshdholtz)
    • SK1StoreProductDiscount: handle SKProductDiscount.priceLocale being nil and created StoreKitWorkarounds (#1545) via NachoSoto (@NachoSoto)
    • Fixed ErrorUtils.logDecodingError (#1539) via NachoSoto (@NachoSoto)

    Other changes

    • GetIntroEligibilityOperation: replaced response parsing with Decodable (#1576) via NachoSoto (@NachoSoto)
    • PostOfferForSigningOperation: changed response parsing to using Decodable (#1573) via NachoSoto (@NachoSoto)
    • Converted CustomerInfo and related types to use Codable (#1496) via NachoSoto (@NachoSoto)
    • MagicWeatherSwiftUI: fixed usage of PurchaseDelegate (#1601) via NachoSoto (@NachoSoto)
    • Added tests for PeriodType/PurchaseOwnershipType/Store (#1558) via NachoSoto (@NachoSoto)
    • Fix description of StoreTransaction (#1584) via aboedo (@aboedo)
    • Prepare the codebase to listen to the Storefront changes (1/4) (#1557) via Juanpe Catalán (@Juanpe)
    • Purchases.canMakePayments: moved implementation to StoreKitWrapper (#1580) via NachoSoto (@NachoSoto)
    • BackendGetIntroEligibilityTests: fixed test that was passing before anything ran (#1575) via NachoSoto (@NachoSoto)
    • PeriodType/PurchaseOwnershipType/Store: conform to Encodable (#1551) via NachoSoto (@NachoSoto)
    • Improved EntitlementInfosTests (#1547) via NachoSoto (@NachoSoto)
    • ProductRequestData: added Storefront for receipt posting (#1505) via NachoSoto (@NachoSoto)
    • Added RawDataContainer conformances to APITesters (#1550) via NachoSoto (@NachoSoto)
    • Simplified EntitlementInfo.isEqual (#1548) via NachoSoto (@NachoSoto)
    • CustomerInfo: moved deprecated property to Deprecations (#1549) via NachoSoto (@NachoSoto)
    • PackageType: simplified typesByDescription and implemented CustomDebugStringConvertible (#1531) via NachoSoto (@NachoSoto)
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(48.68 MB)
    RevenueCat.xcframework.zip(151.81 MB)
  • 3.14.2(Apr 29, 2022)

  • 4.3.0(Apr 25, 2022)

    API updates:

    • Introduced new Storefront type to abstract SK1's SKStorefront and SK2's StoreKit.Storefront.
    • Exposed Storefront.currentStorefront.
    • Added new ErrorCode.offlineConnectionError to differenciate offline errors versus the more generic .networkError.
    • Added Purchases.setFirebaseAppInstanceID to allow associating RevenueCat users with Firebase.
    • Added Purchases.setPushTokenString as an overload to Purchases.setPushToken.
    • Renamed PurchasesDelegate.purchases(_:shouldPurchasePromoProduct:defermentBlock:) to PurchasesDelegate.purchases(_ purchases: Purchases, readyForPromotedProduct product: StoreProduct, purchase:) to clarify its usage (see #1460).

    Other:

    • Many improvements to error reporting and logging to help debugging.
    • Optimized StoreKit 2 purchasing by eliminating a duplicate API request.
    • A lot of under-the-hood improvements, mainly focusing on networking. If you see any issues we'd appreciate bug reports!
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(45.00 MB)
    RevenueCat.xcframework.zip(141.67 MB)
  • 4.2.1(Apr 8, 2022)

    Version 4.2.1 changes:

    • Fixed a potential race condition when syncing user attributes #1479

    Version 4.2.0 changes:

    API updates:

    • Added new method setMixpanelDistinctID as a convenience method for setting the required attribute for the Mixpanel integration #1397

    • getPromotionalOffer has been deprecated in favor of promotionalOffer #1405

    • getEligiblePromotionalOffers has been deprecated in favor of eligiblePromotionalOffers #1405

    • StoreProductDiscount now includes the numberOfPeriods property #1428

    Other:

    • Added workaround for StoreKit 1 incorrectly reporting purchase cancellations #1450

    • MagicWeatherSwiftUI now includes an example for using purchases(:shouldPurchasePromoProduct:defermentBlock:) #1459

    • Various documentation improvements

    • Additional under-the-hood improvements, continuing to focus on network requests and tests.

    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(48.13 MB)
    RevenueCat.xcframework.zip(147.31 MB)
  • 4.2.0(Apr 8, 2022)

    API updates:

    • Added new method setMixpanelDistinctID as a convenience method for setting the required attribute for the Mixpanel integration #1397

    • getPromotionalOffer has been deprecated in favor of promotionalOffer #1405

    • getEligiblePromotionalOffers has been deprecated in favor of eligiblePromotionalOffers #1405

    • StoreProductDiscount now includes the numberOfPeriods property #1428

    Other:

    • Added workaround for StoreKit 1 incorrectly reporting purchase cancellations #1450

    • MagicWeatherSwiftUI now includes an example for using purchases(:shouldPurchasePromoProduct:defermentBlock:) #1459

    • Various documentation improvements

    • Additional under-the-hood improvements, continuing to focus on network requests and tests.

    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(48.10 MB)
    RevenueCat.xcframework.zip(147.21 MB)
  • 4.1.0(Mar 14, 2022)

    API updates:

    • Added new method checkTrialOrIntroDiscountEligibility(product:), which allows you to check for intro or discount eligibility for a single StoreProduct. https://github.com/RevenueCat/purchases-ios/pull/1354

    • Added explicit parameter name for checkTrialOrIntroDiscountEligibility(productIdentifiers:). The existing method without the parameter name still work, but is now deprecated. Xcode will offer an auto fix-it for it. https://github.com/RevenueCat/purchases-ios/pull/1362

    • Made StoreProduct initializers public so they can be used for testing.

    Other:

    • Added auto-fix-it for invalidatePurchaserInfoCache rename https://github.com/RevenueCat/purchases-ios/pull/1379

    • Docs improvements

    • A lot of under-the-hood improvements, mainly focusing on network requests and tests.

    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(46.50 MB)
    RevenueCat.xcframework.zip(142.96 MB)
  • 4.0.0(Feb 25, 2022)

    RevenueCat iOS SDK v4 is here!!

    Dancing cats

    Full Changelog

    Migration Guide

    • See our RevenueCat V4 API update doc for API updates. Note: This release is based off of 4.0.0-rc.4. Developers migrating from that version shouldn't see any changes.

    API changes:

    There have been a lot of changes since v3!

    Here are the highlights:

    Async / Await alternative APIs

    New async / await alternatives for all APIs that have completion blocks, as well as an AsyncStream for CustomerInfo.

    New types and cleaned up naming

    New types that wrap StoreKit's native types, and we cleaned up the naming of other types and methods for a more consistent experience.

    New APIs for Customer Support

    You can now use showManageSubscriptions() and beginRefundRequest() to help your users manage their subscriptions right from the app.

    Rewritten in Swift

    We rewrote the SDK in 100% Swift. This made the code more uniform and easy to maintain, and helps us better support StoreKit 2.

    StoreKit 2 Support [Beta]

    [Experimental] Introduced support for using StoreKit 2 under the hood for compatible devices. This is currently in beta phase, and disabled by default. When enabled, StoreKit 2 APIs will be used under the hood for purchases in compatible devices. You can enable this by configuring the SDK passing useStoreKit2IfAvailable: true. On devices that don't support StoreKit 2, StoreKit 1 will be used automatically instead.

    Full API changes list

    Documentation:

    We built a new Documentation site with Docc with cleaner and more detailed docs. The new documentation can be found here.

    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(44.17 MB)
    RevenueCat.xcframework.zip(136.85 MB)
  • 4.0.0-rc.4(Feb 22, 2022)

    • Fourth RC for RevenueCat framework v4 🎉 100% Swift framework + ObjC support.

    Full Changelog

    RC 4 introduces the following updates:

    API changes:

    Breaking changes:

    • Replaced checkPromotionalDiscountEligibility with getPromotionalOffer, which returns a PromotionalOffer.
    • Renamed Purchases/purchase(package:discount:) and its variants to Purchases/purchase(package:promotionalOffer:). They now take a PromotionalOffer instead of a StoreProductDiscount.
    • [Objective-C only]: Updated type of StoreProduct.price and StoreProductDiscount.price from NSDecimal to the much more useful NSDecimalNumber.

    Additions:

    • Added StoreProduct.ProductType, and StoreProduct.ProductCategory, which provide extra information about whether a product is a consumable, non-consumable, auto-renewable or non-auto-renewable subscription.
    • Added currencyCode to StoreProduct and StoreProductDiscount.
    • Added localizedPriceString to StoreProductDiscount.

    Documentation:

    • Documentation can be found in https://revenuecat-docs.netlify.app/documentation/Revenuecat.
    • We've made several improvements to docstrings and added a few landing pages for the most important sections of the SDK.

    Other changes:

    • There are lots of under the hood improvements. If you see any issues we'd appreciate bug reports!

    Changes from previous RC

    These changes add to all of the changes from beta RC 2, listed here.

    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(44.17 MB)
    RevenueCat.xcframework.zip(136.85 MB)
  • 4.0.0-rc.3(Feb 14, 2022)

    • Third RC for RevenueCat framework v4 🎉 100% Swift framework + ObjC support.

    Full Changelog

    RC 3 introduces the following updates:

    API changes:

    • Added setCleverTapID, for integration with CleverTap.
    • Added .noIntroOfferExists as an IntroEligibilityStatus, for more granularity when checking for intro pricing eligibility.
    • Added StoreProductDiscount.type, which allows you to easily tell whether a discount represents a Promo Offer or an Intro Pricing.

    Documentation:

    • Documentation can be found in https://revenuecat-docs.netlify.app/documentation/Revenuecat.
    • We've made several improvements to docstrings and added a few landing pages for the most important sections of the SDK.

    Migration fixes

    • Fixed a few instances where Xcode's automatic migration tools wouldn't automatically suggest a fix-it for updated code.

    Other changes:

    • There are lots of under the hood improvements. If you see any issues we'd appreciate bug reports!

    Changes from previous RC

    These changes add to all of the changes from beta RC 2, listed here.

    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(46.67 MB)
    RevenueCat.xcframework.zip(135.57 MB)
  • 3.14.1(Feb 8, 2022)

  • 4.0.0-rc.2(Feb 2, 2022)

    • Second RC for RevenueCat framework v4 🎉 100% Swift framework + ObjC support.

    Full Changelog

    RC 2 introduces the following updates:

    API changes:

    • Removed SubscriptionPeriod.Unit.unknown. Subscriptions with empty SubscriptionPeriod values will have nil subscriptionPeriod instead.
    • Removed StoreProductDiscount.none, since it wasn't needed.
    • Added useStoreKit2IfAvailable (Experimental) configuration option. This is disabled by default. If enabled, the SDK will use StoreKit 2 APIs for purchases under the hood. This is currently in an experimental phase, and we don't recommend using it in production in this build.

    Documentation:

    • Documentation is now using DocC and it can be found in https://revenuecat-docs.netlify.app/documentation/Revenuecat.
    • We've made several improvements to docstrings and added a few landing pages for the most important sections of the SDK.

    Migration fixes

    • Fixed a few instances where Xcode's automatic migration tools wouldn't correctly update the code.

    Other changes:

    • There are lots of under the hood improvements. If you see any issues we'd appreciate bug reports!

    Changes from previous RC

    These changes add to all of the changes from beta RC 1, listed here.

    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(45.34 MB)
    RevenueCat.xcframework.zip(130.03 MB)
  • 4.0.0-rc.1(Jan 28, 2022)

    • First RC for RevenueCat framework v4 🎉 100% Swift framework + ObjC support.

    Full Changelog

    RC 1 introduces the following updates:

    API changes:

    • Purchases.paymentDiscount(forProductDiscount:product:completion:) and Purchases.paymentDiscount(forProductDiscount:product:) have been removed. Now, instead of obtaining the SKPaymentDiscount from a SKProductDiscount to then call purchase(package:discount:), you check eligibility for the promo offer by calling checkPromotionalDiscountEligibility(forProductDiscount:product:), then get the StoreProductDiscount directly from the StoreProduct and pass that into purchase(package:discount:).

    • StoreProduct and StoreProductDiscount, replace SKProduct and SKProductDiscount in the following methods:

      • Purchases.getProducts(_:completion:)
      • Purchases.products(_:)
      • Purchases.purchase(product:completion:)
      • Purchases.purchase(product:)
      • Purchases.purchase(product:discount:completion:)
      • Purchases.purchase(product:discount:)
      • Purchases.purchase(package:discount:completion:)
      • Purchases.purchase(package:discount:)
      • PurchasesDelegate.purchases(shouldPurchasePromoProduct:defermentBlock:)
    • StoreProduct.introductoryPrice has been renamed to StoreProduct.introductoryDiscount

    • StoreTransaction now includes quantity

    • Renamed Purchases.restoreTransactions to Purchases.restorePurchases

    • Lowered StoreProduct.introductoryDiscount availability to iOS 11.2 and equivalent OS versions

    • Added several @available annotations for automatic migration from StoreKit types

    In addition to all of the changes from beta 10, listed here.

    Other changes:

    • There are lots of under the hood improvements. If you see any issues we'd appreciate bug reports!
    Source code(tar.gz)
    Source code(zip)
    RevenueCat.framework.zip(42.46 MB)
    RevenueCat.xcframework.zip(122.86 MB)
  • 3.14.0(Jan 26, 2022)

Owner
RevenueCat
The best way to build, analyze, and grow in-app subscriptions
RevenueCat
Demonstrates how to integrate Stripe Subscriptions on iOS

Stripe Subscriptions with iOS This example app demonstrates how to integrate Stripe subscriptions with the prebuilt payment UI Requirements Create an

Conjure 0 Nov 26, 2021
Lightweight In App Purchases Swift framework for iOS 8.0+, tvOS 9.0+ and macOS 10.10+ ⛺

SwiftyStoreKit is a lightweight In App Purchases framework for iOS, tvOS, watchOS, macOS, and Mac Catalyst. Features Super easy-to-use block-based API

Andrea Bizzotto 6.1k Sep 22, 2022
A lightweight iOS library for In-App Purchases

#RMStore A lightweight iOS library for In-App Purchases. RMStore adds blocks and notifications to StoreKit, plus receipt verification, content downloa

Robot Media 2.4k Sep 12, 2022
A modern In-App Purchases management framework for iOS.

MerchantKit A modern In-App Purchases management framework for iOS developers. MerchantKit dramatically simplifies the work indie developers have to d

Benjamin Mayo 1.1k Sep 27, 2022
Handle in-app purchases in iOS in a convenient way

InAppPurchases Handle in-app purchases in iOS in a convenient way. Overview InAppPurchases covers all the basic aspects of in-app purchases in swift i

Umar Awais 5 Jul 18, 2022
Easy to use iOS library with components for input of Credit Card data.

AnimatedCardInput This library allows you to drop into your project two easily customisable, animated components that will make input of Credit Card i

Netguru 38 Aug 13, 2022
Easy, drop-in tip jar for iOS apps.

Installation TipJarViewController is available through CocoaPods. To install it, simply add the following line to your Podfile: pod 'TipJarViewControl

Lionheart Software 79 Apr 27, 2022
card.io provides fast, easy credit card scanning in mobile apps

card.io SDK for iOS card.io provides fast, easy credit card scanning in mobile apps. NEW!!! card.io is now an open-source project! As of December 2014

card.io 2.3k Sep 7, 2022
iOS SDK for cross-platform in-app purchase and subscription infrastructure, revenue analytics, engagement automation, and integrations

Qonversion is the data platform to power in-app subscription revenue growth. fast in-app subscriptions implementation back-end infrastructure to valid

Qonversion 243 Sep 15, 2022
Make and accept payments in your iOS app via Venmo

Venmo iOS SDK The Venmo iOS SDK lets you make and accept payments in your app using Venmo. Installation If you're using CocoaPods: If you don't have a

Venmo 167 Sep 26, 2022
Accept credit cards and PayPal in your iOS app

Important: PayPal Mobile SDKs are Deprecated. The APIs powering them will remain operational long enough for merchants to migrate, but the SDKs themse

PayPal 974 Sep 2, 2022
Easily integrate Credit Card payments module in iOS App. Swift 4.0

MFCard Buy me a coffee MFCard is an awesome looking Credit Card input & validation control. Written in Swift 3. YOoo, Now MFCard is on Swift 5. Swift

MobileFirst 359 Jul 6, 2022
In App Purchase Manager framework for iOS

InAppFramework In App Purchase Manager framework for iOS Disclaimer I know it's been too long since the last update, quite a few things happened in my

Sándor Gyulai 40 May 23, 2020
Square In-App Payments iOS SDK SwiftUI

Square In-App Payments iOS SDK SwiftUI Build remarkable payments experiences in

Ashley Bailey 2 Mar 8, 2022
SwiftUI BusinessCard - Created iOS Business card app to practice SwiftUI

SwiftUI_BusinessCard Created iOS Business card app to practice SwiftUI

null 0 Jan 29, 2022
A jailed in-app purchase cracker for iOS 12.2-15.6

Satella Jailed For, um, educational purposes only or something. Definitely don't use this to pirate in-app purchases in apps to which you don't have l

Lilly 160 Sep 20, 2022
OnTime - OnTime App is for Scheduling your day and prioritizing your task and also for saving notes

OnTime OnTime App is for Scheduling your day and prioritizing your task and also

Mohammed Sulaiman 1 Jan 29, 2022
TPInAppReceipt is a lightweight, pure-Swift library for reading and validating Apple In App Purchase Receipt locally.

TPInAppReceipt is a lightweight, pure-Swift library for reading and validating Apple In App Purchase Receipt locally. Features Read all

Pavel T 492 Sep 20, 2022
Ios-card-transition - iOS CocoaPod to create beautiful card transitions

CSCardTransition CSCardTransition is a small library allowing you to create wond

Creastel 11 Sep 28, 2022