Skip to content

detail: tap a search row to open app detail with version timeline#4

Merged
Evil0ctal merged 1 commit into
mainfrom
feat/m2-detail
May 6, 2026
Merged

detail: tap a search row to open app detail with version timeline#4
Evil0ctal merged 1 commit into
mainfrom
feat/m2-detail

Conversation

@Evil0ctal
Copy link
Copy Markdown
Owner

what

tap any search result -> app detail view with a timeline of historic
versions. needs a borrowed Account to populate the timeline; without one
the screen explains how to recover.

why

  • version timeline is the product's headline feature
  • exercises the private storefront protocol end-to-end (POST plist,
    cookies, DSID/GUID headers) so M3 download can reuse the wiring
  • AccountStore env-object becomes the single place where stealth ->
    storefront bridges happen

changes

  • AppDetailView + AppDetailViewModel
  • AccountStore (probes CompositeImporter on launch, caches Account)
  • AppStoreClient.listVersions + ListVersions.run plist roundtrip
  • PlistCoder helper + Endpoints.privateStorefront()
  • VersionInfo model (m2: external id only; m2.5 fills display version)
  • SearchView row -> NavigationLink to detail
  • EvilStoreApp bootstraps AccountStore on launch

test

  • xcodebuild Debug + Release archive both green
  • tipa carries every entitlement through ldid
  • expected on real device:
    • tap an app row -> detail page opens
    • if storeaccountd readable: timeline shows extX entries with
      latest pinned at top
    • if not: "no system session yet" with link back to diagnostics
  • no public itunes regression: search tab still works without auth

next

m2.5 = PartialZipReader (HTTP Range -> zip CD -> Info.plist) to resolve
display version + releaseDate per external id, replacing the bare
"ext NNNNN" labels with "9.7.2 - 2026-04-30".

m2 ships the navigation shell + listVersions over the private storefront.
when stealth borrowed an account at launch, taps load softwareVersion
ExternalIdentifiers and render a tappable timeline. without an account
the detail screen explains how to recover (Settings > Stealth diagnostics).

* AppDetailView + AppDetailViewModel
* AccountStore env-object: walks CompositeImporter on launch and caches
  the active Account; debug Settings can override via setActive()
* AppStoreClient.listVersions backed by ListVersions.run — POST plist to
  /WebObjects/MZFinance.woa/wa/volumeStoreDownloadProduct, parse
  songList[0].metadata.softwareVersionExternalIdentifiers, reverse so
  callers see latest first
* PlistCoder + Endpoints.privateStorefront() helper (download endpoint
  is shared with listVersions; payload distinguishes them)
* VersionInfo model — m2 only fills externalIdentifier; displayVersion
  + releaseDate land in m2.5 via PartialZipReader
* SearchView row -> NavigationLink to detail
* EvilStoreApp wires AccountStore env-object and kicks bootstrap()

ios 14 baseline preserved (no .monospaced(), no .task(id:)).

without an account this is still useful: the search tab keeps working
on public itunes apis and the detail page renders the header so users
can verify they picked the right app.
@Evil0ctal Evil0ctal merged commit ab80166 into main May 6, 2026
3 checks passed
@Evil0ctal Evil0ctal deleted the feat/m2-detail branch May 6, 2026 00:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant