How IPATool Searches for visionOS Apps: Technical Implementation Guide

IPATool uses a dedicated HTML-scraping pipeline that queries the Apple Vision Pro storefront directly, extracts app identifiers from embedded serialized JSON, and hydrates them through the iTunes Lookup API to deliver complete app metadata.

IPATool is an open-source command-line utility developed by majd for downloading IPA files from Apple's App Store. While standard iOS and macOS searches utilize Apple's public JSON Search API, the platform requires a specialized workflow to search for visionOS apps because Apple does not expose a public search endpoint for the Vision Pro ecosystem.

The visionOS Search Architecture

The implementation diverges from standard platform searches through a five-stage pipeline defined in pkg/appstore/appstore_search.go and pkg/appstore/appstore_storefront.go.

Platform Detection and Routing

When the Search method receives a request, it inspects the Platform field of the SearchInput struct. If the value equals PlatformVisionOS—defined in pkg/appstore/platform.go as the literal string "visionos"—the execution diverts from the standard JSON API path to the visionOS-specific routine.

// Simplified logic from appstore_search.go L32-L34
if input.Platform == PlatformVisionOS {
    return a.searchVisionOS(ctx, input)
}

Scraping the Vision Pro Storefront

Instead of calling the iTunes Search API, IPATool issues a raw HTTP GET request against the visionOS storefront URL. The visionSearchURL function constructs the endpoint using the country code and search term, targeting URLs like https://apps.apple.com/us/vision/search?term=photo+editor.

Unlike other platforms that return structured JSON, the visionOS storefront responds with raw HTML, requiring IPATool to parse the page content to extract application data.

Extracting App Data from HTML

The HTML response contains a <script id="serialized-server-data"> tag that embeds a JSON blob with the search results. The storefrontVisionApps function in pkg/appstore/appstore_storefront.go (lines 69-75) performs three critical operations:

  1. HTML Parsing: The serializedServerData function locates the script tag by ID and extracts its inner JSON content.
  2. Vision-Specific Filtering: The containsVisionPurchaseConfiguration helper walks the JSON structure, identifying items that carry a purchaseConfiguration object with metricsPlatformDisplayStyle: "vision" and a valid appExtVrsId.
  3. Result Limiting: The constant maxVisionOSSearchResults = 12 caps the number of apps processed, preventing oversized pages from overwhelming the CLI interface.

Metadata Hydration via Lookup API

The storefront extraction yields only minimal app identifiers. To populate complete metadata—including pricing, version numbers, and bundle IDs—the collected app IDs are sent to the standard iTunes Lookup API through the lookupIDsRequest method.

This request explicitly uses the PlatformVisionOS entity type to ensure the API returns visionOS-compatible app information. The full App structs returned replace the minimal stub entries extracted from the HTML, creating the final SearchOutput containing the count and fully-hydrated Results slice.

Implementation Details

Platform Constants and URL Construction

The PlatformVisionOS constant is defined in pkg/appstore/platform.go, mapping the "visionos" string to a typed platform value. When constructing requests, the visionSearchURL function (lines 43-48 of appstore_storefront.go) formats the storefront URL with the appropriate country code and URL-encoded search terms.

HTML Parsing and JSON Extraction

The serializedServerData function implements defensive parsing logic to handle Apple's server-side rendering. It searches the HTML document for the specific script tag ID, extracts the raw JSON text, and returns trimmed bytes ready for unmarshaling into Go structs.

Vision-Specific Filtering Logic

Not all items in the storefront HTML represent visionOS applications. The containsVisionPurchaseConfiguration function performs deep inspection of each JSON node, specifically looking for:

  • A purchaseConfiguration object
  • A metricsPlatformDisplayStyle field set to "vision"
  • A valid appExtVrsId field

Only entries meeting all criteria are included in the final result set.

Practical Usage Examples

Searching via CLI

To search for visionOS applications from the command line, specify the visionos platform flag:


# Search the Vision Pro App Store for "photo editor", limiting results to 5

ipatool search --term "photo editor" --platform visionos --limit 5

The CLI parses the platform flag into PlatformVisionOS, triggers the HTML-scraping workflow, and outputs a formatted table containing the app name, bundle ID, App Store ID, and price.

Programmatic Search in Go

Developers integrating IPATool as a library can invoke the search programmatically:

import (
    "github.com/majd/ipatool/v2/pkg/appstore"
)

func main() {
    input := appstore.SearchInput{
        Account:  myAccount,
        Term:     "photo editor",
        Limit:    5,
        Platform: appstore.PlatformVisionOS,
    }

    client := appstore.New()
    out, err := client.Search(input)
    if err != nil {
        log.Fatalf("search failed: %v", err)
    }

    for _, app := range out.Results {
        fmt.Printf("%s (%s) – ID:%d\n", app.Name, app.BundleID, app.ID)
    }
}

This snippet executes the same raw-HTML fetch, JSON extraction, and metadata lookup described above, returning a slice of fully-populated appstore.App structs ready for further processing.

Summary

  • Platform Branching: IPATool detects visionOS requests via the PlatformVisionOS constant and routes to a specialized handler in appstore_search.go.
  • HTML Scraping: The tool queries apps.apple.com vision storefronts directly and parses the HTML response instead of using JSON APIs.
  • JSON Extraction: App identifiers are extracted from the serialized-server-data script tag, with filtering logic that validates visionOS compatibility through purchase configuration metadata.
  • Result Hydration: Raw app IDs are enriched using the standard iTunes Lookup API with visionOS entity parameters to provide complete metadata.
  • Safety Limits: The search caps results at 12 applications via maxVisionOSSearchResults to ensure CLI responsiveness.

Frequently Asked Questions

Why does IPATool use HTML scraping for visionOS instead of the standard Search API?

Apple does not expose a public JSON Search API endpoint for visionOS equivalent to the iOS or macOS interfaces. According to the majd/ipatool source code, the visionOS App Store storefront only returns server-rendered HTML containing embedded JSON data, necessitating the storefrontVisionApps parsing logic in pkg/appstore/appstore_storefront.go.

How does IPATool distinguish between visionOS apps and other platforms in the search results?

The implementation uses the containsVisionPurchaseConfiguration function to inspect each candidate's JSON structure. It specifically checks for a purchaseConfiguration object containing metricsPlatformDisplayStyle: "vision" and a valid appExtVrsId, ensuring only applications explicitly configured for Apple Vision Pro are included in the final output.

The codebase defines maxVisionOSSearchResults = 12 in pkg/appstore/appstore_storefront.go. This constant limits the parser to process only the first 12 valid visionOS applications found in the storefront HTML, preventing memory overhead and maintaining CLI performance when handling large result pages.

Can I use IPATool to download visionOS apps after searching?

Yes. Once the search returns valid App structs containing bundle IDs and App Store identifiers, you can use IPATool's standard download command with the --platform visionos flag. The search ensures the apps are compatible with visionOS by verifying the purchase configuration metadata before the download process begins.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →