Photo credits: Safar Safarov

How to integrate the Sparkle framework into a SwiftUI app for MacOS

…using Github Pages and GitHub Releases as hosting

Matteo Spada
8 min readAug 19, 2022

--

Introduction

If like me you are trying to release an app outside the App Store, you are probably wondering how update your app after the release of the first version. I asked my self the same questions developing my own App Store Optimization tool, and after a quick research, I found Sparkle an open source framework that permit you to update your app remotely.

The best way to start integrate sparkle in your app is use the Basic Setup guide, unfortunately this guide is not easy to comprehend because you need to know different things that are not explained in the guide, so I decided to write this article where I will try to explain in the most simple way the entire process.

This article doesn’t replace the official documentation, (which I strongly advise you to read carefully), but it integrates some parts and provides a complete explanation of the whole process.

Preparing the hosting

When our app will be live, we need a place where to go to retrieve our updates. You can choose the host service that most you like, but In this guide we will use GitHub Project Pages and GitHub Releases. Why? Simple are free.

We have to create a new Github public repository where we will upload the update files. In this article we are going to use a simple .dmg file, but you can also use other formats please refer to the official documentation for more information.

Create a new Github Repository and enable Github Pages, you can also upload a very simple html file to test if everything works fine. At the end of this configuration your website will be public accessible via https. The URL format of the repository web page will be:

https://your_github_username.github.io./your_repository_name

Configuring the project.

Create a new SwiftUI Project, we can call it Sparkle-test.

Project configuration

Update the ContenentView file with a Text that identify the bundle version, When the app will be update by Sparkle automatically the bundle version will change.

Remember: Sparkle use the Bundle version to understand if our app is updated or not, in this article we will update from 0.9 to 1.0

Now we can use the Swift Package manager to add Sparkle Framework to our app, so we will follow the Sparkle documentation.

if you want integrate sparkle in your project using Cocoa pods or manually you can follow the point one of the basic setup.

If you use Swift Package Manager:

In your Xcode project: File › Add Packages…

Enter https://github.com/sparkle-project/Sparkle as the package repository URL

Choose the Package Options. The default options will let Xcode automatically update versions of Sparkle 2.

Prepare EdDSA (ed25519) signatures

Now that we have the frameworks added to our project is time to create our pair of EdDSA keys, nothing complex but basically Sparkle for security reasons wants that every update is signed with our private key, in order to be sure that the update file really come from us, and not from someone else.

From Xcode’s project navigator, if you right click and show the Sparkle package in Finder, you will find Sparkle’s tools to generate and sign updates in ../artifacts/Sparkle/

Don’t make this error: When you will click show in finder, you will bring in the checkout directory, you have to back to the previous directory to find the artifacts folder, with all the tools that we need.

Run ./bin/generate_keys tool (from the Sparkle distribution root). This needs to be done only once. This tool will do two things:

It will generate a private key and save it in your login Keychain on your Mac. You don’t need to do anything with it, but do keep it safe. See further notes below if you happen to lose your private key.

It will print your public key to embed into applications. Copy that key (it’s a base64-encoded string). You can run ./bin/generate_keys again to see your public key at any time.

Save your public key somewhere, we will use it soon, fon any doubt read the official documentation.

Continue the project configuration

Now we have to create other 2 file, to integrate Sparkle in our SwiftUI app, and the best way is simply copy and paste the example file that you can find in the Sparkle documentation for programmatic setup (Create an Updater in SwiftUI). For any doubt you can always take a look to the final project implementation on my GitHub account. I simply divided the example code in two distinct file for a better separation.

To permit outbound and inbound connection, go to Project Target and select Incoming Connections (Server) and Outgoing Connections (Client), under Signing & Capabilities.

Add some extra keys to our plist file:

SUEnableInstallerLauncherService Bool 1

SUFeedURL String

https://your_github_username.github.io./your_repository_name/appcast.xml

SUPublicEDKey String your_previous_generated_public_Key

At the end, your plist file should be contain these keys, remember to add appcast.xml at the end of your SUFeedURL Path. This file is an .xml file with all the information about our new update, description version etc.

To complete the configuration we have to add some extra keys to our entitlements file, you can find more info about this step in the Sparkle official documentation. The entitlements files is located in the root of our projects, the keys that we have to add are:

<key>com.apple.security.temporary-exception.mach-lookup.global-name</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)-spks</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)-spki</string>
</array>

The final result should be like this:

Export and Signing our code

Our app is finally ready, but if we run the project and trying to update our app we receive this error, the reason is simple we did’t yet upload our appcast.xml on Github, do you remember? This file permit to Sparkle to understand if update or not our app.

To create the appcast.xml file we have first export our project in order to create an executable version.

In Xcode go on Product > Archive > Distribuite app > Developer ID, Upload > Automatically manage signing > Upload.

This process will be signing the executable file with our developer profile and at the same time will be sent our file to apple notary service to be sure that our code is free of malware. You can find more info about Apple Notary service at this page.

Now it’s time to take a coffee and wait that Apple notary service finish to analyze our code.

When the process is finished click on export app and save the app on your Desktop inside a folder called version1.0

Create the dmg file

Now we have to create a dmg file that will contain our app. The simplest way that I found to do it is using create-dmg. This tool permit us to completely configure our dmg file (including background, icon image, and other options) and also sign it with our developer profile and send it to apple for notarization, and yes, we have to send to apple also our dmg.

After the installation, you can create the dmg file using this script:

You can find your developer profile using this command.

security find-identity

You have to create your notary profile using this command.

Attention: your_spacific_app_password is not the password of your appleID.

xcrun notarytool store-credentials “Your Profile Name” — apple-id “yourappleide@mail.com” — password “your_specific_app_password” — team-id “your_team_id

Useful Link
Create a specific password
Check your Team ID

Create the appcast.xml file

Now it’s time to sign our dmg file with our EdDSA (ed25519) signatures, Sparkle make this step super simple with the generate_appcast tool.

First thing, copy the dmg file inside a new folder you can call this folders updates.
Open ../artifacts/Sparkle/In your terminal and launch this command

./bin/generate_appcast /path/to/your/updates_folder/

The dmg file will be signed and a new appcast file will be created.

Upload the .dmg file on GitHub releases

Go on Github releases and upload the dmg file just created. You can find a complete guide about how manage releases in your project in this page.

Github releases

Now that the file is online copy the release path and edit the .appcast.xml file to be sure that it point to the same path.

Upload the appcast file

We are almost there, upload the appcast.xml file in the root of your repository using git.

Consider that it takes 5 minutes before the file is updated in the Github pages.

Test the update

We are at the end of this tutorial the last thing that we have to do is run the project.

If you click on Check Updates from the menu bar command you will see that our app version is correctly updated.

Now let’s try to change the bundle ID, to 0.9 and check the updates again.

A new version of Sparkle Test is available! Now you can click on Install update to Update your app!

If Xcode has issues running your application using Sparkle and its XPC Services (such as being unable to attach to the process), try editing your project’s Scheme and disable Debug XPC services used by app or test your application detached from Xcode to see if it works there.

Conclusion

For any question or doubt feel free to leave a comment or write me on twitter. If you find an error in this procedure please let me know so I can correct it.

--

--