◉RORK LABJP
●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…
Articles/Business
⟐ Business/2026-04-07Advanced

Advanced Apple Search Ads Strategy — Competitor Bidding, Custom Product Pages & CPP Optimization

A comprehensive advanced guide to Apple Search Ads: competitor keyword bidding, Custom Product Pages (CPP), match type strategy, cohort-based LTV analysis, and budget allocation for maximizing ROI on your Rork Max app.

Apple Search Ads3ASAASO27user acquisition3CPPcustom product pagesRork Max236

Apple Search Ads (ASA) is one of the highest-intent paid acquisition channels available to iOS developers — users searching the App Store are actively looking for a solution. But most guides stop at "create a campaign, set a bid, and review results." This guide goes further.

We'll cover competitor bidding, Custom Product Pages (CPP), campaign architecture, match type strategy, and cohort-based LTV analysis — the advanced techniques that separate apps spending efficiently from those burning budget.

Understanding the ASA Advanced Campaign Architecture

ASA Advanced uses a three-tier structure: Campaign → Ad Group → Keywords/Ads. The most important design principle is intent separation — grouping keywords by search intent and pairing each group with a CPP that matches what the user is looking for.

A well-structured campaign hierarchy for a photo editing app might look like this:

Campaign: Brand Keywords
  ├── Ad Group: Own Brand
  │   Keywords: [AppName], [AppName free], [AppName review]
  └── Ad Group: Competitor Brand
      Keywords: [CompetitorA app], [CompetitorB photo editor]

Campaign: Generic Keywords
  ├── Ad Group: Core Function
  │   Keywords: photo editor, image editing app, photo filter
  ├── Ad Group: Use Case — Social Media
  │   Keywords: instagram photo edit, tiktok thumbnail, reels editor
  └── Ad Group: Competitor Conquesting
      Keywords: [CompetitorA alternative], [CompetitorA vs]

Campaign: Search Match Discovery
  └── Ad Group: Auto Discovery
      (Search Match ON — no manual keywords)

Competitor Keyword Bidding Strategy

Bidding on competitor brand terms is one of the highest-ROI moves in ASA. Users searching for a competitor by name are already problem-aware and comparison-shopping — exactly the right moment to present your alternative.

Finding the Right Competitors to Target

Start with the "You Might Also Like" and "More by This Developer" sections on your App Store page to identify direct competitors. Then mine your Search Match reports — any competitor brand names appearing in impression data are prime candidates.

Third-party tools like AppFollow, Sensor Tower, or data.ai can show which keywords competitors rank for and where they're likely buying ads.

Setting Maximum Bid Amounts

Competitor keywords are typically more expensive and convert at lower rates than branded terms. Calculate your tolerable CPA before setting bids:

Target CPA = ARPU × Payback Period (months) × Gross Margin

Example:
  ARPU (monthly premium revenue per active user) = $2.00
  Payback period = 6 months
  Gross margin = 70%
  → Target CPA = $2.00 × 6 × 0.70 = $8.40

Competitor keyword average CVR = 3%
  → Max CPT (cost per tap) = $8.40 × 0.03 = $0.25

Apply this calculation per campaign and ad group, updating monthly as you gather more data.

Negative Keywords: Precision Over Volume

When targeting competitor keywords, you want comparison shoppers — not die-hard loyal users or support seekers. Use negative keywords to filter out low-intent traffic:

  • [Competitor] login — existing users, not prospects
  • [Competitor] cancel — churning users unlikely to switch
  • [Competitor] customer service — support-seeking, low conversion intent
  • [Competitor] update — feature-checking existing users

Custom Product Pages (CPP) + Campaign Pairing

CPPs let you show a different App Store page — different screenshots and promotional text — to users landing from specific ad groups. Combined with ASA, they unlock significant conversion rate improvements.

The Core Principle

The message in the ad group's keywords must match the promise shown on the CPP.

| Ad Group Intent | CPP Focus | | Core photo editing queries | Showcase editing tools, filters, precision controls | | Social media / Instagram queries | Show finished social-ready images, share flows | | Competitor brand queries | Lead with your key differentiators: speed, price, features |

Creating CPPs in App Store Connect

Navigate to App Store Connect → Your App → Custom Product Pages → tap "+" to create a new page. Customize the screenshots and promotional text for the specific audience, submit for App Review, and once approved, it becomes available for selection in ASA Advanced.

Linking CPPs to Ad Groups in ASA

In ASA Advanced, navigate to an Ad Group → Ads → select "Custom Product Page" instead of the default store page, then choose your specific CPP.

This single change — matching CPP to keyword intent — consistently yields 20–50% CVR improvements compared to sending all traffic to the default product page.

A/B Testing CPPs

Within one ad group, you can run multiple ads simultaneously to compare CPP performance:

Ad Group: Competitor Conquesting
  ├── Ad A: CPP_Feature_Focused (highlight your unique features)
  ├── Ad B: CPP_Price_Focused (emphasize free trial / lower price)
  └── Ad C: Default Product Page (baseline)

Run for 2–3 weeks, compare CVR and downstream CPA, and shift budget to the winner once statistical significance is reached.

Match Type Strategy

The Three Match Types

Exact Match: Ads appear only for searches closely matching your specified keyword. Highest precision, easiest CPA management — but limited reach. Use for proven high-performers.

Broad Match: Ads appear for close variants and related searches. Broader reach, good for discovering new high-intent terms, but requires active negative keyword management to avoid waste.

Search Match: No manual keywords needed — ASA automatically matches your app to relevant queries based on metadata and category. Ideal for the discovery phase of a new campaign.

The Three-Phase Campaign Build

Phase 1 — Discovery (Weeks 1–4) Run a Search Match campaign with no manual keywords. Let ASA find you. Review the "Search Terms" impression report weekly, noting which queries drive installs.

Phase 2 — Exact Harvest (Weeks 3–8) Promote top-performing Search Match queries to a dedicated Exact Match ad group. Add those same keywords as negatives in the Search Match campaign to prevent overlap.

Phase 3 — Broad Expansion (Week 6+) For keywords that are stable and profitable in Exact, create Broad Match variants to capture related queries. Add negatives aggressively as you see irrelevant traffic appear.

Timeline:
Weeks 1-4:  Search Match Discovery
Weeks 3-8:  Exact Match (from Discovery winners)
Week 6+:    Broad Match (expansion from Exact winners)

Cohort Analysis: Measuring Post-Install Quality

Install count and CPA are lagging indicators. What really matters is whether the users you're acquiring convert to subscribers and stay. Cohort analysis by ad group reveals which campaigns bring high-LTV users.

Apple Ads Attribution API Integration

import AdServices
 
// Request attribution token on first app open
func requestAttributionToken() async throws -> String {
    if #available(iOS 14.3, *) {
        return try await AAAttribution.attributionToken()
    }
    throw AttributionError.unsupported
}
 
// Send token to your backend for server-side resolution
func sendTokenToBackend(_ token: String) async {
    var request = URLRequest(url: URL(string: "https://yourapi.com/attribution")!)
    request.httpMethod = "POST"
    request.httpBody = try? JSONEncoder().encode(["token": token])
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    _ = try? await URLSession.shared.data(for: request)
}

Resolving Attribution on the Backend

const resolveAppleAttribution = async (token: string) => {
  const response = await fetch('https://api-adservices.apple.com/api/v1/', {
    method: 'POST',
    headers: { 'Content-Type': 'text/plain' },
    body: token,
  });
 
  if (response.status === 200) {
    const data = await response.json();
    // data.attribution — true if from ASA
    // data.campaignId, data.adGroupId, data.keywordId
    return data;
  }
  return null;
};
 
const saveAttribution = async (userId: string, attr: AppleAttributionData) => {
  await db.insert('user_attributions').values({
    user_id: userId,
    source: attr.attribution ? 'apple_search_ads' : 'organic',
    campaign_id: attr.campaignId,
    ad_group_id: attr.adGroupId,
    keyword_id: attr.keywordId,
    created_at: new Date(),
  });
};

LTV by Ad Group

SELECT
  a.ad_group_id,
  COUNT(DISTINCT u.user_id) AS installs,
  AVG(r.revenue_30d) AS avg_ltv_30d,
  COUNT(CASE WHEN u.is_premium THEN 1 END)::FLOAT /
    NULLIF(COUNT(DISTINCT u.user_id), 0) AS conversion_rate
FROM user_attributions a
JOIN users u ON a.user_id = u.id
LEFT JOIN user_revenue_30d r ON u.id = r.user_id
WHERE a.source = 'apple_search_ads'
  AND a.created_at >= NOW() - INTERVAL '90 days'
GROUP BY a.ad_group_id
ORDER BY avg_ltv_30d DESC;

This query surfaces which ad groups drive high-LTV subscribers versus cheap but low-quality installs — enabling you to reallocate budget toward the campaigns that actually move the business.

Budget Allocation Framework

Daily budget = Target daily installs × Target CPI

Example: 10 installs/day at $5 target CPI = $50/day total

Initial allocation:
  Brand Keywords:         20% — efficient, high CVR, protect brand
  Generic Keywords:       50% — core volume
  Competitor Conquesting: 20% — test and expand
  Search Match Discovery: 10% — exploration

For automated bidding, ASA's target CPA (tCPA) mode works well once each ad group has accumulated 30–50+ installs. Before that threshold, manual bidding gives you more control and avoids the auto-optimizer overfitting to sparse data.

Closing Thoughts

Apple Search Ads rewards iteration. The teams getting the best ROI aren't those who set up a campaign and walk away — they're the ones running the Search Match → Exact Harvest → CPP A/B test cycle continuously.

Start simple: one Search Match campaign to collect data. Then gradually add Exact Match groups for proven queries, layer in CPPs aligned to each intent cluster, and use cohort LTV data to concentrate budget on what actually converts. Each cycle tightens your acquisition efficiency and builds a scalable, defensible growth engine for your Rork Max app.

Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⟐ Business2026-04-26
Taking a Rork Max Native App Up the App Store Charts — The Order I Build Ads, StoreKit 2, and Subscriptions
The order I follow to grow a Rork Max SwiftUI app into one that stays near the top of its App Store category: a single AdGate that decides when ads may show, StoreKit 2 Transaction.updates monitoring, and where I draw the lines on ASO and retention — with working code.
⟐ Business2026-04-09
How to Get Your Rork App Featured on the App Store — 7 Design Strategies That Impress Apple's Editorial Team
How to design, build, and nominate your Rork app for App Store featuring — Apple HIG compliance, accessibility, performance, and a field-by-field walkthrough of Featuring Nominations in App Store Connect.
⟐ Business2026-10-01
Multiseat Purchases Are Already On: Decide Whether to Keep Them Before October 22
Multiseat purchases for subscriptions have been on by default in App Store Connect since September 16. Before Volume Purchasing starts on October 22, here is how an indie developer can decide, in four questions, whether to keep them.