Files
FTStore/ios/HOW_IT_WORKS.md
Felitendo ff0d3108fe feat: merge the web dashboard into the monorepo as ftstore admin
FTStore now holds both halves of the product:

  ios/   the swift app — the fork of claration/Feather, unchanged apart
         from its new home
  web/   FTStore Admin, formerly its own repository. serves the
         dashboard at /admin, the ftstore.json feed and IPA downloads

app-repo.json and Images/ stay at the repo root on purpose: the former is
a published AltStore source whose raw.githubusercontent URL is what
installed copies resolve updates through, so moving it would break every
subscriber.

The admin server is renamed throughout: package ftstore-admin, images
ghcr.io/<owner>/ftstore-admin-{app,worker}, postgres role/db ftstore,
session cookie ftstore_session, temp dir /tmp/ftstore, backup type
ftstore-settings, outbound user-agent FTStoreAdmin. backups written under the old
name still import, and compose is pinned to name: ftstore so the
volume prefix does not follow the directory name.

apply-rebrand.sh gains a relocation step: upstream's tree is rooted at
the repo root while ours lives in ios/, so a merge drops Feather's files
next to ios/ and the script folds them in before renaming. it never
touches web/. still idempotent.

release tags are namespaced — v* for the app, web-v* for the server —
so a server release no longer triggers a macOS build or rewrites
app-repo.json. workflows are prefixed ios-/web- and path-filtered.
2026-08-03 10:25:03 +02:00

3.2 KiB

How does it work?

How FTStore works is a bit complicated, with having multiple ways to install, app management, tweaks, etc. However, I'll point out how the important features work here.

To start off, we need a validly signed IPA. We can achieve this with Zsign, using a provided IPA using a .p12 and .mobileprovision pair.

Install (Server)

  • Use a locally hosted server for hosting the IPA files used for installation, including other assets such as icons, etc.
    • On iOS 18, we need a few entitlements: Associated Domains, Custom Network Protocol, MDM Managed Associated Domains, Network Extensions
  • Make sure to include valid https SSL certificates as the next URL requires a valid HTTPS connection, for us we use *.backloop.dev.
  • We then use itms-services://?action=download-manifest&url=<PLIST_URL> to attempt to initiate an install, by using UIApplication.open.

However, due to the changes with iOS 18 with entitlements we will need to provide an alternative way of installing. We have two options here, a way to install locally fully using the local server (the one I have just shown) or use an external HTTPS server that serves as our middle man for our PLIST_URL, while having the files still local to us. Lets show the latter.

  • This time, lets not include https SSL certificates, rather just have a plain insecure local server.
  • Instead of a locally hosting our PLIST_URL, we use plistserver to host a server online specifically for retrieving it. This still requires a valid HTTPS connection.
  • Now, to even initiate the install (due to lack of entitlements from the former) we need to trick iOS into opening the itms-services:// URL, we can do this by summoning a Safari webview to a locally hosted HTML page with a script to forcefully redirect us to that itms-services URL.

Since itms-services initiates the install automatically, we don't need to do anything extra after the process. Though, what we do is monitor the streaming progress of the IPA being sent.

Install (Pairing)

  • Establish a heartbeat with a TCP provider (the app will need this for later).
  • Once we have these and the connection was successfully established, we can move on to the installation part.
    • Before installing, we need to check for the connection to the socket that has been created, routed to 10.7.0.1, if this succeeds we're ready.
  • When preparing for installation, we need to establish another connection but for AFC using the TCP provider.
  • Once the connection was established we need to created a staging directory to /PublicStaging/ and upload our IPA there.
  • Then, using our connection to AFC we can command it to install that IPA directly. Similar to ideviceinstaller, but fully on your phone.

Due to how it works right now we need both a VPN and a lockdownd pairing file, this means you will need a computer for its initial setup. Though, if you don't want to do these you can just use the server way of installing instead (but at a cost of less reliability).