Loading In-App Product Identifiers

Load the unique identifiers for your in-app products in order to retrieve product information from the App Store.


Implementing an in-app purchase flow can be divided into three stages. In the first stage of the purchase process, your app retrieves information about its products from the App Store, presents its store UI to the user, and lets the user select products. Your app requests payment when the user selects a product in your app's store, and finally, your app delivers the product. The steps performed by your app and the App Store in the first stage are highlighted in Figure 1.

Figure 1

Begin the purchase process by retrieving product information from the App Store

A flow chart depicting the steps of the in-app purchase process. The product information retrieval stage is diagrammed as three steps between your app and the App Store. First, your app makes a request for a product; the App Store provides the product information requested; and finally, your app displays its store UI with the product information.

To begin the purchase process, your app must know its product identifiers so it can retrieve information about the products from the App Store and present its store UI to the user. Every product sold in your app has a unique product identifier. You provide this value in App Store Connect when you create a new in-app purchase product (see Create an In-App Purchase for more information). Your app uses these product identifiers to fetch information about products available for sale in the App Store, such as pricing, and to submit payment requests when users purchase those products.

There are several strategies for storing a list of product identifiers in your app, such as embedding in the app bundle or storing on your server. You can then retrieve the product identifiers by reading them locally in the app bundle or fetching them from your server. Choose the method that best serves your app's needs.

Retrieve Product IDs from the App Bundle

Embed the product identifiers in your app bundle if:

  • Your app has a fixed list of in-app purchase products. For example, apps with an in-app purchase to remove ads or unlock functionality can embed the product identifier list in the app bundle.

  • You expect users to update the app in order to see new in-app purchase products.

  • The app or product does not require a server.

Include a property list file in your app bundle containing an array of product identifiers, such as the following:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
<plist version="1.0">

To get product identifiers from the property list, locate the file in the app bundle and read it.

guard let url = Bundle.main.url(forResource: "product_ids", withExtension: "plist") else { fatalError("Unable to resolve url for in the bundle.") }
do {
    let data = try Data(contentsOf: url)
    let productIdentifiers = try PropertyListSerialization.propertyList(from: data, options: .mutableContainersAndLeaves, format: nil) as? [String]
   } catch let error as NSError {

Retrieve Product IDs from Your Server

Store the product identifiers from your server if:

  • You update the list of in-app products frequently, without updating your app. For example, games that supports additional levels or characters should fetch the product identifiers list from your server.

  • The products consist of delivered content.

  • Your app or product requires a server.

Host a JSON file on your server with the product identifiers. For example, the following JSON file contains three product IDs:


To get product identifiers from your server, fetch and read the JSON file.

func fetchProductIdentifiers(from url: URL) { .default).async {
        do {
            let jsonData = try Data(contentsOf: url)
            let identifiers = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String]

            guard let productIdentifiers = identifiers else {fatalError("Identifiers are not of type String.")}

            DispatchQueue.main.async {
           self.delegate?.display(products: productIdentifiers) 

      } catch let error as NSError {

Consider versioning the JSON file so that future versions of your app can change its structure without breaking older versions of your app. For example, you could name the file that uses the old structure products_v1.json and the file that uses a new structure products_v2.json. This is especially useful if your JSON file is more complex than the simple array in the example.

To ensure that your app remains responsive, use a background thread to download the JSON file and extract the list of product identifiers. To minimize the data transferred, use standard HTTP caching mechanisms, such as the Last-Modified and If-Modified-Since headers.

After loading all in-app product identifiers, pass them into the product information request to the App Store. For details on obtaining product information, see Fetching Product Information from the App Store.

See Also

Product Information

Fetching Product Information from the App Store

Retrieve up-to-date information about the products for sale in your app to display to the user.

class SKProductsRequest

An object that can retrieve localized information from the App Store about a specified list of products.

class SKProductsResponse

An App Store response to a request for information about a list of products.

class SKProduct

Information about a product previously registered in App Store Connect.