For the complete documentation index, see llms.txt. This page is also available as Markdown.

Fetching Products

Fetch your product catalog from Onside with a products request, read product details, and handle errors.

Before you can sell anything, fetch the product details from Onside using each product's identifier, which you configure in the Onside Developer Console.

A product identifier in OnsideKit is the Onside product identifier (slug) you configure in the console and pass to the request — it is not the App Store / StoreKit SKU. You request and match products by this identifier.

The flow is: create a request, assign a delegate, retain it, start it, and handle the result.

Create and start a request

@MainActor static func makeProductsRequest(productIdentifiers: Set<String>) -> OnsideProductsRequest
import OnsideKit

final class ProductsViewController: UIViewController {

    private var productsRequest: OnsideProductsRequest?
    private var products: [OnsideProduct] = []

    func fetchProducts() {
        let identifiers: Set<String> = [
            "premium_feature",
            "subscription_monthly",
        ]

        let request = Onside.makeProductsRequest(productIdentifiers: identifiers)
        request.delegate = self
        self.productsRequest = request   // retain it for the whole request
        request.start()
    }
}

Handle the response

Conform to OnsideProductsRequestDelegate. All methods are @MainActor.

Exactly one of onsideProductsRequest(_:didReceive:) or onsideProductsRequest(_:didFailWithError:) fires per run, always followed by onsideProductsRequestDidFinish(_:) (which has a default empty implementation). Calling start() while a request is already running is a no-op; the same request object can be re-start()ed after it finishes.

The response object

  • products — the products that resolved successfully.

  • invalidProductIdentifiers — an array of requested identifiers the backend didn't find. This is a partial-success channel: one response can contain both valid products and unknown identifiers. (This is different from the .invalidProductIdentifier error, which means the whole request was rejected — see below.)

Read a product

OnsideProduct exposes everything you need to build your store UI:

Property
Description

productIdentifier: String

The Onside identifier (slug) you requested.

localizedTitle: String

Display name for the user's locale.

localizedDescription: String

Display description.

iconUrl: URL?

Product icon, if available.

price: OnsidePrice

Price (value: Double, currencyCode: String).

subscriptionPeriod: OnsidePeriod?

Set for subscriptions only.

subscriptionGroupIdentifier: String?

Subscription group, subscriptions only.

For subscriptions, the billing period is covered in Subscriptions.

Errors

onsideProductsRequest(_:didFailWithError:) delivers an OnsideProductsRequestError:

Case
Cause
Suggested handling

.connectionError

Network failure.

Offer a retry.

.serviceUnavailable

Server returned 5xx.

Retry later.

.appNotRegistered

The app/install isn't recognized by Onside (HTTP 404).

Check your app registration/configuration.

.invalidProductIdentifier

The request was rejected (HTTP 422).

Check the identifiers you sent.

.cancelled

The request was cancelled (e.g. stop()).

Usually ignore.

.internalError

Parsing or other unexpected error.

Report if persistent.

See the full Error Reference.

Fetching across regions

You can — and should — fetch products before the user logs in, using a best-guess region, then re-fetch once the storefront is known. See Regions & Storefronts.

Last updated

Was this helpful?