Skip to content

feat: app update checker#654

Open
tanakrit-d wants to merge 1 commit into
claration:mainfrom
tanakrit-d:add-update-checker
Open

feat: app update checker#654
tanakrit-d wants to merge 1 commit into
claration:mainfrom
tanakrit-d:add-update-checker

Conversation

@tanakrit-d

Copy link
Copy Markdown

Description

A point of friction has been visually reconciling the app version to see if an update is available. Well, be the change you want to see in the world.

I've implemented a simple update checker available from the Library screen. Ideally I would've liked to also add automatic update checking and notifications but that herculean task is quite outside of my skillset at the moment. Baby steps :^)

The user simply presses the refresh button, and any available updates are displayed in the action pill (apologies - unsure of the correct UI terminology here). They can then trigger a download via. the update button.

Screenshots

screenshots_resized

Testing Notes

I've built and installed the app, and verified the implemented functionality.

@claration

Copy link
Copy Markdown
Owner

one of the main problems with an update checker is that we have no way of knowing where the app properly came from, with feather v1 this often caused issues with it getting an entirely different app with the same bundle id.

@tanakrit-d

Copy link
Copy Markdown
Author

Oh. You raise an excellent point.

Could we store metadata for each app and then perform a comparison based on that? This would create a relationship between the source and the app.

Manually added apps would be out of the scope of checking - which also kind of makes sense anyway.

@claration

Copy link
Copy Markdown
Owner

Ideally we would store the repository associated with the app, or even maybe use the "unique" identifier feather generates so it tries to keep track of that certain app.

Possibly even have a whitelist/blacklist on what repositories should have updates, maybe even only whitelist the recommended list Feather already provides.

I thought of having an option to disallow repositories from containing identifiers present in other repositories, lets say you have one that contains Discord (com.hammerandchisel.discord), this option would disallow new repositories with this identifier from being added. This is horrible UX though.

@tanakrit-d tanakrit-d force-pushed the add-update-checker branch from 8743b09 to 8a8af1c Compare June 7, 2026 23:22
@tanakrit-d

Copy link
Copy Markdown
Author

Okay this turned into a massive headache.
But I believe I've arrived at a robust implementation after an annoying amount of testing and regression throughout, including weird shenanigans like two outdated versions but only one shows an update available.
The changes have absolutely ballooned from the initial implementation 🗿

Design

The new implementation uses a provenance approach (associated metadata for IPA origin).
Repo sourced downloads record:

  • Source URL
  • Source app id
  • Version
  • Download URL

Manual URL/file imports are exempt from this process. Update checks only consider apps with source metadata or an explicit repo source URL, then match back to the same source before comparing versions, which aims to prevent bundle collisions between sources.

Signed apps inherit provenance from the imported app they were signed from, so they can display update state while still prioritising certificate expiry in the main action.

UI Changes

  • Update icon animates when checking in order to provide feedback to the user
  • Imported apps:
    • App icon receives update badge
    • Pill displays update
  • Signed apps:
    • App icon receives update badge
    • Pill retains expiry date
    • Pill expands to choice dialogue
      • Update Available: Install Current Version / Download Update

New/Modified Files

  • Feather/Backend/Observable/DownloadManager.swift: Carries optional source provenance on downloads and prevents manual/source downloads from sharing the same record
  • Feather/Backend/Observable/UpdateManager.swift: Adds metadata update checks using stored source identity, with a safe source URL fallback for repo originating apps
  • Feather/Backend/Storage/Feather.xcdatamodeld/Feather.xcdatamodel/contents: Adds AppSourceMetadata for persisted app provenance
  • Feather/Backend/Storage/Storage+SourceMetadata.swift: Adds provenance models and helpers for source metadata
  • Feather/Backend/Storage/Storage+Shared.swift: Deletes provenance with apps and exposes source through AppInfoPresentable
  • Feather/Backend/Storage/Storage.swift: Migration and loading
  • Feather/Utilities/FR.swift: Allows package handling to receive explicit source provenance
  • Feather/Utilities/Handlers/AppFileHandler.swift: Saves source URL and metadata only when imports have repo provenance
  • Feather/Utilities/Handlers/SigningHandler.swift: Carries source URL and source metadata from imported apps to signed apps
  • Feather/Views/Library/LibraryCellView.swift: Shows update badges/actions and handles signed app update confirmation
  • Feather/Views/Library/LibraryView.swift: Adds animated update-check feedback and running update scans from the full library
  • Feather/Views/Settings/Reset/ResetView.swift: Clears source metadata when deleting imported or signed apps
  • Feather/Views/Sources/Apps/Detail/SourceAppsDetailView.swift: Passes source context into downloads and version history
  • Feather/Views/Sources/Apps/Detail/VersionHistoryView.swift: Records provenance for previous version downloads (almost missed this one!)
  • Feather/Views/Sources/Apps/DownloadButtonView.swift: Creates source provenance for normal repo downloads
  • Feather/Views/Sources/Apps/SourceAppsCellView.swift: Passes source URL into source app cells
  • Feather/Views/Sources/Apps/SourceAppsView.swift: Tracks repositories together with their source URLs
  • Feather/Views/Sources/Apps/UIKit/SourceAppsTableRepresentableView.swift: Preserves source context

Screenshots!

IMG_1721 IMG_1720

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.

2 participants