How the ipatool Search Command Queries the App Store Across Different Platforms
The ipatool search command queries the App Store through a platform-aware architecture that branches between a dual-request flow for VisionOS and a single iTunes API request for all other platforms.
The ipatool search command is a thin CLI wrapper around the AppStore service in majd/ipatool. According to the source code, it adapts its HTTP strategy based on the target platform, handling VisionOS as a special case while using a unified approach for iOS, iPadOS, tvOS, and macOS.
CLI Entry Point and Input Parsing
The search workflow begins in cmd/search.go, where the command registers the --platform flag and assembles user input into a structured request.
The searchCmd() function constructs an appstore.SearchInput containing:
- The search term
- The result limit (
--limit) - The parsed platform from
appstore.ParsePlatform
This input struct is passed directly to the core AppStore service method Search() defined in pkg/appstore/appstore_search.go.
Platform-Aware Request Routing
The appstore.Search() method in pkg/appstore/appstore_search.go implements the core branching logic for platform-specific queries.
iOS, iPadOS, tvOS, and macOS: Standard Search Flow
For all platforms except VisionOS, the code path is:
- Call
searchRequest()→searchURL() - Build the iTunes Search API URL using:
platform.searchEntity()— determines the correct entity parameter- Country code derived from the user's storefront
- URL-encoded search term
- Requested limit
The searchEntity() method (in pkg/appstore/platform.go) maps internal platform constants to iTunes API entity strings like software, iPadSoftware, tvSoftware, or macSoftware.
VisionOS: Dual-Request Storefront Flow
VisionOS triggers a fundamentally different approach via searchVisionOS():
- First request — Hits the storefront endpoint (
visionSearchURL) to retrieve a lightweight list of app IDs - Second request — Enriches results with full metadata via lookup requests
This two-phase design exists because VisionOS apps are not indexed through the standard iTunes Search API, requiring direct storefront interaction.
HTTP Execution and Response Handling
Both code paths use the shared http.Client (t.searchClient for standard platforms, t.storefrontClient for VisionOS storefront calls). Requests are issued as GET operations with format-specific decoding:
- Standard platforms: JSON response decoded via
http.ResponseFormatJSON - VisionOS: Raw data handling for storefront responses
The response is marshaled into SearchOutput with Count and Results []App fields. Any non-200 status code converts to a structured appstore.Error containing request metadata for debugging.
Platform Constants and Entity Mapping
The pkg/appstore/platform.go file defines the platform abstraction:
| Platform | Internal Constant | Search Entity |
|---|---|---|
| iPhone | PlatformIOS |
software |
| iPad | PlatformIPadOS |
iPadSoftware |
| Apple TV | PlatformTVOS |
tvSoftware |
| Vision | PlatformVisionOS |
storefront API |
| Mac | PlatformMacOS |
macSoftware |
The ParsePlatform() function normalizes CLI flag values to these constants, while searchEntity() and lookupEntity() methods determine the correct iTunes API parameters.
Usage Examples
Search for iPhone apps (default platform):
ipatool search "candy crush" --limit 5
Explicit platform selection:
# iPad apps
ipatool search "procreate" --platform ipad
# macOS apps
ipatool search "final cut pro" --platform macos
# VisionOS apps (triggers storefront flow)
ipatool search "spatial game" --platform visionos
Summary
- The
ipatool searchcommand routes queries throughpkg/appstore/appstore_search.gowhere platform type determines the HTTP strategy - VisionOS uses a specialized
searchVisionOS()implementation with storefront API calls - All other platforms use standard iTunes Search API requests constructed via
searchURL()with platform-specific entities - Platform parsing and entity mapping live in
pkg/appstore/platform.gowithParsePlatform()andsearchEntity() - Responses unify to
SearchOutputregardless of underlying request complexity
Frequently Asked Questions
How does ipatool handle VisionOS differently from other platforms?
VisionOS requires a two-phase query through the storefront API instead of the iTunes Search API. The searchVisionOS() function first retrieves a lightweight app list from visionSearchURL, then performs secondary lookup requests to fetch complete metadata. This compensates for VisionOS apps not being indexed in the standard search endpoint.
What file contains the platform-to-entity mapping logic?
The mapping lives in pkg/appstore/platform.go. The searchEntity() method returns software for iPhone, iPadSoftware for iPad, tvSoftware for Apple TV, and macSoftware for Mac. VisionOS bypasses this entirely and uses storefront endpoints.
Can I search without specifying a platform flag?
Yes. When omitted, the platform defaults based on context, and the ParsePlatform() function handles normalization. The CLI in cmd/search.go constructs the SearchInput with whatever platform value is provided (or default), and the core service handles the rest.
Where does the actual HTTP request happen?
The appstore.Search() method in pkg/appstore/appstore_search.go delegates to t.searchClient.Send() for standard platforms and t.storefrontClient.Send() for VisionOS. Both use the shared HTTP client abstraction defined elsewhere in the pkg/appstore package.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →