3.0 KiB
Mac Software Updater
To make updating the Mac app easy, we're using the Sparkle framework.
This is added to the project via the Swift Package Manager (SPM), but at the time of writing, tagged versions of Sparkle do not yet support
SPM — the dependency can only be added from a branch or commit. To avoid any surprises arising from updates to the project's master
branch, we're using WriteFreely's fork of Sparkle. Updates to the forked repository from upstream should be considered dangerous and
tested thoroughly before merging into main
.
WriteFreely for Mac uses the v1.x branch of Sparkle, and is therefore not a sandboxed app.
Troubleshooting
If Xcode throws an error when you try to build the project
You may need to reset the package caches:
- From the File menu in Xcode, choose Swift Packages → Reset Package Caches
- Again from the File menu, choose Swift Packages → Update to Latest Package Versions
You should then be able to build and run the Mac target.
If you can't run generate_keys
because "Apple cannot check it for malicious software"
There may be a code signing issue with Sparkle. Right-click on generate_keys
in the Finder and choose Open (reference).
Deploying Updates
To publish an update to the app, you'll need the Sparkle-for-Swift-Package-Manager.zip archive — specifically, you'll need the
generate_appcast
tool. Download and de-compress the archive.
You will need some credentials and signing certificates to proceed with this process; speak to the project maintainer if you're responsible for creating the update, and confirm you have:
- the app's Developer ID Application certificate (check your Mac's system Keychain)
- the Sparkle EdDSA signing key (again, check your Mac's system Keychain)
Sign and notarize the app archive, then click on Export Notarized App in Xcode's Organizer window. Open the Terminal and navigate to where you de-compressed the Sparkle-for-Swift-Package-Manager archive, then create a zip file that preserves symlinks:
% ditto -c -k --sequesterRsrc --keepParent <source_path_to_app> <zip_destination>
For example, if you export the notarized app to the desktop, all prior updates are located in ~/Developer/WriteFreely/Updates
, and
the final archive should be called WFMac.zip
, you would run:
% ditto -c -k --sequesterRsrc --keepParent ~/Desktop/WriteFreely\ for\ Mac.app ~/Developer/WriteFreely/Updates/WFMac.zip
Then, generate an appcast file:
% ./bin/generate_appcast ~/Developer/WriteFreely/Updates
Once that's done, upload the appcast.xml and WFMac.zip files to the update distribution server (files.writefreely.org/apps/mac
)
and they'll be made available to users.