Measure and Scale Apple Search Ads Effectively

Qonversion collects Apple Search Ads attribution data independently of IDFA and SKAdNetowork and measures your return on ad spend (ROAS) accurately. See exactly wich keyword, ad group, and campaign performs better.
 




Reviews widget

“Qonversion allows us to see accurate subscription statistics and trends over time, visualised in an aesthetically appealing manner on an interactive dashboard. This means we know how we're doing, and what effect our changes are having on the business.”

“Qonversion is an excellent server that perfectly complements our in-app subscription analytics system. Thanks to Qonversion, we managed to improve our financial metrics quite quickly. It also has some very useful integrations, which we use to optimize the marketing of our apps, such as Facebook and AppsFlyer.”

“Thanks to Qonversion, I was able to move my first app over to subscriptions with minimal fuss and can see at a glance exactly how the app is performing in real-time on the dashboard.”

“Qonversion took away the hassle of implementing my own-server receipt validation mechanism which would have taken me months to perfect in terms of edge cases. Now I can sit back and focus more on my app, where my users are awaiting new features!”

“Qonversion is invaluable — previously we could not get the analytics we needed in Firebase or Mixpanel as they do not verify app store receipts. The subscription analytics provided are very high quality and granular — as well as being presented clearly and concisely with interactive visualisation dashboards to plot KPIs over time. This has enabled us to better understand our business and inform our decision making.”



Email collector widget

GET BLOG UPDATES

By subscribing, you are agreeing to have your personal information managed in accordance with the terms of Qonversion Privacy Policy


Code snippet widget

Qonversion.offerings { (offerings, error) in
  if let products = offerings?.main?.products {
    // Display products for sale
  }
}
Qonversion.purchaseProduct(product) {
  (permissions, error, isCancelled)
      in if let premium : Qonversion.Permission =
      permissions["premium"],
                          premium.isActive {
    // Flow for success state
  }
}
Qonversion.checkPermissions { (permissions, error) in
  if let error = error {
    // handle error
    return
  }

  if let premium: Qonversion.Permission =
    permissions["premium"], premium.isActive
  {
    // handle active permission
  }
}
[Qonversion
    offerings:^(QNOfferings* _Nullable offerings,
                NSError* _Nullable error) {
      if (offerings.main.products.count > 0) {
        // Display products for sale
      }
    }];
[Qonversion
    purchaseProduct:product
         completion:^(
             NSDictionary
                 *_Nonnull permissions,
             NSError *_Nullable error, BOOL cancelled) {
           QNPermission *premiumPermission =
               permissions[@"premium"];

           if (premiumPermission &&
               premiumPermission.isActive) {
             // Flow for success state
           }
         }];
[Qonversion
    checkPermissions:^(
        NSDictionary
            *_Nonnull permissions,
        NSError *_Nullable error) {
      QNPermission *premiumPermission =
          permissions[@"premium"];
      if (premiumPermission &&
          premiumPermission.isActive) {
        // handle active permission
      }
    }];
Qonversion.offerings(
    new QonversionOfferingsCallback() {
      @Override
      public void onSuccess(
          @NotNull QOfferings offerings) {
        if (offerings.getMain() != null
            && !offerings.getMain()
                    .getProducts()
                    .isEmpty()) {
          // Display products for sale
        }
      }
      @Override
      public void onError(
          @NotNull QonversionError error) {
        // handle error here
      }
    });
Qonversion.purchase(
    this, product,
    new QonversionPermissionsCallback() {
      @Override public void onSuccess(
          @NotNull Map
              permissions) {
        QPermission premiumPermission =
            permissions.get("premium");

        if (premiumPermission != null &&
            premiumPermission.isActive()) {
          // handle active permission here
        }
      }

      @Override public void onError(
          @NotNull QonversionError error) {
        // handle error here
      }
    });
Qonversion.purchase(this, product,
    new QonversionPermissionsCallback() {
      @Override
      public void onSuccess(@NotNull
          Map permissions) {
        QPermission premiumPermission =
            permissions.get("premium");

        if (premiumPermission != null
            && premiumPermission.isActive()) {
          // handle active permission here
        }
      }

      @Override
      public void onError(
          @NotNull QonversionError error) {
        // handle error here
      }
    });
Qonversion.offerings(
    object
    : QonversionOfferingsCallback{
        override fun onSuccess(offerings
                               : QOfferings){
            val mainOffering =
                offerings.main if (mainOffering
                        != null
                    && mainOffering.products
                           .isNotEmpty()){
                    // Display products for sale
                }} override fun
            onError(error
                    : QonversionError){
                // handle error here
            }})
Qonversion.purchase(
    this, product, callback = object
    : QonversionPermissionsCallback{
        override fun onSuccess(
            permissions
            : Map){
            val premiumPermission =
                permissions["premium"] if (
                    premiumPermission != null
                    && premiumPermission
                           .isActive()){
                    // handle active permission
                    // here
                }}

        override fun onError(error
                             : QonversionError){
            // handle error here
        }})
Qonversion.checkPermissions(
    object
    : QonversionPermissionsCallback{
        override fun onSuccess(
            permissions
            : Map){
            // Handle new permissions here
        }

        override fun onError(error
                             : QonversionError){
            // Handle the error
        }})