Question

App failing to retrieve package in production for about 20% of users on iOS

  • 22 November 2022
  • 2 replies
  • 96 views

Badge +4

We’ve been using RevenueCat forever and recently updated to 4.13.1 and instrumented the app properly so this behaviour might have been present in the past but we wouldn’t have known it.

About 20% of our users who attempt purchase fail due to RevenueCat returning a nil package. We’re not sure what could cause such a large percent of them to fail and if that’s normal (i.e. 20% of users are launching our app for the first time without Internet connectivity?). Has anyone else seen those failure rates that high?


2 replies

Userlevel 6
Badge +8

Hey @Slaven!

Do you mean that when fetching Offerings, you’re receiving nil packages? Or during the purchase process it’s failing?

That seems like a pretty big share of attempts, but it seems like there might be something else happening here causing the issue. Are you able to reproduce it? Do you have any debug logs?

Badge +2

Hi @cody , I’m Slaven’s teammate, jumping in for him – it’s the former, it seems like we’re receiving nil packages. We don’t have any detailed logs on this, just analytics events that fire depending on purchase attempt outcomes.

When a new user runs the app, we try to grab packages from RevenueCat (getAvailableProductsAndLicenses() below). We then try to offer them one of those packages when the user has completed our onboarding flow.

Looking at our analytics, 40% of intro purchase attempts (triggered by doSubscribe() below) reach the “else” branch at the bottom of the below snippet, due to package being nil. 

Abbreviated code: 

// On app launch

LicenseController.shared.getAvailableProductsAndLicenses()

// LicenseController

@Published public var Package_Annual: RevenueCat.Package?
// ... etc

public func getAvailableProductsAndLicenses() {
Purchases.shared.getOfferings { (offerings, error) in
let packages: [RevenueCat.Package]? = offerings?.current?.availablePackages

if let packages {

for package in packages {

if package.packageType == .annual {
self.Package_Annual = package
}
// ... etc
}
}
}
}

// Subscribe button action
public func doSubscribe() {

let package = LicenseController.shared.Package_Annual

if let package {

Purchases.shared.purchase(package: package) { (transaction, customerInfo, error, userCancelled) in
if customerInfo?.entitlements.active.first != nil {

// Purchase succeeded

} else if userCancelled {
// Purchase canceled by user
}
}

} else {
// Package was nil
}
}

Thanks for taking a look.

Reply