Now Reading
Sparkle :: TrozWare

Sparkle :: TrozWare

2023-04-11 08:45:23

Final month, I posted about writing my new todo app referred to as To-Day: why I wrote it and the way I wrote it. On the time, I discussed that I had set it as much as set up updates utilizing Sparkle however there was an excessive amount of element to incorporate within the preliminary submit. So right here, as promised, is the article about implementing Sparkle.

One of many nice conveniences of App Retailer distribution is the replace dealing with. When (or if) an replace passes the app evaluation course of, Apple does the remainder, propagating updates via the App Retailer app. For those who’re distributing your apps externally, you want an alternate methodology.

Sparkle is an open-source replace framework for macOS. It’s extremely popular and I’m certain you’ll have seen it used, even for those who didn’t recognise it. However setting it up isn’t completely straight-forward, no less than I didn’t discover it so, which I why I’m utilizing this submit to doc the method.

The Sparkle documentation is superb and comprises the whole lot that you must know, however they permit for a variety of use instances and configurations, which makes it troublesome to observe at instances. For this app, I’ve the next necessities:

  • SwiftUI app
  • Sandboxed
  • Set up framework utilizing Swift Package deal Supervisor
  • Distribution as a disk picture

This information offers with these necessities solely.

Desk of Contents

Set up

Open your app in Xcode and choose the mission on the high of the mission navigator. Click on on the mission itself within the subsequent sidebar after which select Package deal Dependencies from the tabs throughout the highest.

Click on the + on the backside of the record so as to add a brand new bundle. Enter this URL into the search area and when the bundle seems, click on Add Package deal.

https://github.com/sparkle-project/Sparkle

Install Sparkle

Xcode will obtain the bundle after which present one other dialog with the Sparkle library checked. Click on Add Package deal once more to connect it to your mission.

Including a Public Key to your App

The following step will depend on whether or not you’ve used Sparkle earlier than. You should create a non-public and public key pair for safety causes, however you possibly can then use the identical keys for your whole apps (I believe).

Checking for a Current Key

To verify if you have already got a key, open the Keychain Entry app from Functions/Utilities. Seek for sparkle and when you’ve got a key, you’ll see it listed. For those who don’t discover something, skip forward to the next section to create a brand new one.

Double-click the important thing to indicate its particulars which conveniently consists of the general public key within the feedback.

Existing Sparkle keys

Choose and replica the general public key, then soar to Installing the Public Key.

Making a New Key

For those who don’t have already got a key pair, you’ll use one in every of Sparkle’s instruments to create it.

Again in Xcode, right-click on Sparkle within the mission navigator and choose Present in Finder which opens a folder buried deep in your Library. Press Command-3 to indicate the folder in Columns mode after which click on the artifacts folder that’s one degree above the Sparkle folder.

From there, navigate via sparkle to Sparkle the place you’ll see a bin folder:

Opening the Sparkle folder

Open your most popular Terminal app and kind cd adopted by a area. Drag within the Sparkle folder with the uppercase S.

Then enter and run this command:

This generates the keys, saves them to your keychain and shows the general public key. Copy the general public key to be used within the subsequent part.

Putting in the Public Key

To insert the important thing into your app, return to Xcode and choose the mission and goal. Select Data from the tabs on the high. Click on the + blob that seems beside the final entry if you mouse over it, and kind in the important thing title:

SUPublicEDKey

The sort is String (which ought to be the default) and the worth is the general public key you simply copied:

Adding the Sparkle public key

Sandboxing

Mac apps are sandboxed by default, which quarantines their information into their very own container and protects the remainder of your system. Including Sparkle to a sandboxed app requires some extra steps, but when your app will not be sandboxed, move on to the next section.

First, that you must give your app entry to the web, so it could actually retrieve the replace data and obtain any updates.

Within the app’s goal settings, choose Signing and Capabilities and activate Outgoing Connections (Consumer):

Sand-box connection setting

Subsequent, add one other setting to the goal’s Data:

  • Key: SUEnableInstallerLauncherService
  • Kind: Boolean
  • Worth: YES

The following settings go into the <Your-App-Identify>.entitlements file which you’ll discover within the mission navigator. Proper-click the entitlements file and choose Open As > Supply Code which makes it attainable to stick within the subsequent chunk.

Simply earlier than the final </dict>, add a brand new line and insert:

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

Now the app is configured to permit Sparkle to work with the Mac sandbox.

Finding the Updates

You should have a web-based location for the app and its replace data. Since my To-Day app is on GitHub, I made a decision to make use of GitHub for distribution too, however I might have used this website online, AWS or every other on-line service. It’s greatest if it’s coming from an https server.

Open my GitHub repo and have a look at the file construction. The Releases folder has a disk picture (dmg) containing the app and an XML file generated by Sparkle with the replace data.

Work out the place you’re going to place these two recordsdata in your app and discover the precise URL for the appcast.xml file.

This offers you the final piece of knowledge that your app wants. Add one other setting to your goal’s Data:

For those who’re utilizing GitHub, add a pretend file so you will get the URL, remembering to get the URL for the uncooked file, not its GitHub web page.

Coding the Replace Verify

You’ve completed all of the setup work now, however there’s nothing to set off a verify within the app. I copied and pasted a lot of the instructed code from the Sparkle docs.

First, I created a brand new file referred to as Updater.swift which comprises:

import SwiftUI
import Sparkle

// This view mannequin class publishes when new updates will be checked by the consumer
ultimate class CheckForUpdatesViewModel: ObservableObject {
  @Revealed var canCheckForUpdates = false

  init(updater: SPUUpdater) {
    updater.writer(for: .canCheckForUpdates)
      .assign(to: &$canCheckForUpdates)
  }
}

// That is the view for the Verify for Updates menu merchandise
// Observe this intermediate view is critical for the disabled state on the menu merchandise to work correctly earlier than Monterey.
// See https://stackoverflow.com/questions/68553092/menu-not-updating-swiftui-bug for more information
struct CheckForUpdatesView: View {
  @ObservedObject personal var checkForUpdatesViewModel: CheckForUpdatesViewModel
  personal let updater: SPUUpdater

  init(updater: SPUUpdater) {
    self.updater = updater

    // Create our view mannequin for our CheckForUpdatesView
    self.checkForUpdatesViewModel = CheckForUpdatesViewModel(updater: updater)
  }

  var physique: some View {
    Button("Verify for Updates…", motion: updater.checkForUpdates)
      .disabled(!checkForUpdatesViewModel.canCheckForUpdates)
  }
}

The feedback are from the Sparkle workforce.

In my To-Day app, I’ve an AppGroup view to supply the SwiftUI view for the final part of the menu that controls the app itself.

Inside this view, I added an updaterController property:

personal let updaterController = SPUStandardUpdaterController(
  startingUpdater: true,
  updaterDelegate: nil,
  userDriverDelegate: nil
)

This required one other import Sparkle line on the high of this file.

To set off the replace checker, I added CheckForUpdatesView as one of many views within the menu, offering it with this controller’s updater:

CheckForUpdatesView(updater: updaterController.updater)

Exporting the App

Now that the app is coded, that you must export it from Xcode, signing it along with your Developer ID and getting it notarised by Apple. This assumes that you’ve got an Apple Developer account.

In Xcode, choose Archive from the Product menu. This builds the app and opens the Organiser window. Click on Distribute App, verify Developer ID and click on Subsequent.

Ensure Add is chosen and click on Subsequent once more. Select Mechanically handle signing and click on Subsequent once more. When the following dialog seems, click on Add.

This sends the app off to Apple’s servers to be checked for malicious code. It’s not doing any app evaluation, simply checking for viruses and many others.

It could take a couple of minutes, however the app ought to then be notarised. You’ll have to go to a different show within the Organiser and again once more to power a show refresh so you possibly can see this. If there’s an error, click on Present Standing Log to see what went unsuitable.

Assuming all went properly, click on Export Notarised App and put it aside someplace handy.

For those who don’t have an Apple Developer account, choose Copy App from the distribution dialog and save a folder containing the app. If a consumer has the default Gatekeeper settings on their Mac, they’ll have to right-click the app and choose Open to run it, after getting previous a few warnings.

Making a Disk Picture

The following step is to create the disk picture for distribution. You should use a zipper file or a disk picture, however I want a disk picture as a result of it offers you a solution to information customers to put in the app of their Functions folder.

See Also

The method for that is:

  1. Make a writeable disk picture.
  2. Add the app and a hyperlink to Functions.
  3. Set the view choices, together with a background picture.
  4. Convert the picture right into a read-only copy.

Open Disk Utility from Functions/Utilities. Choose New Picture > Clean Picture… from the File menu. Set its title in two locations and its measurement. The scale ought to be about 2 x the dimensions of your app to permit for future updates.

Double-click the picture to open it and drag your exported app into the disk picture window. Command-Possibility-drag your Functions folder in. You’ll know you’re holding down the proper modifiers for those who see a curved black arrow on the backside left of the icon. This provides an alias to the present Functions folder, slightly than a replica of yours.

Now configure the disk picture window utilizing Finder’s View menu and View Choices. I flip off all the additional views: toolbar, path bar, standing bar and many others. then I set the view choices like this:

Configuring the disk image

Setting a background picture takes a couple of steps. First, discover a picture you want. Not being graphically minded, I used a rectangle full of a gradient and added a curved arrow that pointed from the app to the Functions folder. My file is a png, however I believe a jpg will work high quality. You possibly can click on this hyperlink if you wish to see my pattern background image.

Drag the picture file into your disk picture. Don’t fear about positioning it – you’re about to make the file invisible. With Finder lively, press Shift-Command-. to indicate invisible recordsdata. Now, rename the background picture file to .background.png. The main interval makes this an invisible file, however you possibly can see it in the mean time. Open the View Choices once more and choose Image for the Background. Drag your picture file into the properly. This may occasionally present that that you must re-position the arrow, so repeat the method till you get a picture that appears proper. Then press Shift-Command-. once more to cover invisible recordsdata. Re-position the seen icons to go well with and regulate the dimensions of the window to what you wish to present.

Now that the disk picture is configured, eject it. Again in Disk Utility, choose Pictures > Convert… and select your dmg. On the following dialog, change Picture Format to read-only and click on Convert. That is the disk picture that goes into your Releases folder, so change its title to match your app and transfer it. Maintain the read-write disk picture too – it’s a lot simpler to edit it when updating as an alternative of going via this course of each time.

Open the read-only picture and verify that it’s arrange the best way your need. I’ve discovered that generally the background picture doesn’t stick. If this occurs to you, eject and trash the read-only picture. Mount the read-write picture once more, verify its settings and re-convert.

Producing the appcast.xml

Now to create the file that Sparkle makes use of to see if there’s an replace.

Use the tactic from if you generated a key to open a Terminal on the Sparkle listing. Kind in:

./bin/generate_appcast /path/to/your/Releases/folder

When you’re typed the command and an area, you possibly can drag your Releases folder in to get its path.
Press Return and wait whereas Sparkle generates the appcast.xml file.

And eventually, you’re able to launch. Add your Releases folder to wherever you determined to place it, ensuring that the URL for the appcast.xml file is identical as in your app’s data.

Testing

Transfer the notarised app into your purposes folder and run it. If all has labored, it is best to have the ability to verify for updates and see that you’ve got the newest model.

For those who get an error, verify again via all of the setup phases. I do know I made each mistake attainable when setting it up first, so verify the sandbox setting, the data and the entitlements. Use an internet browser to substantiate that the appcast.xml file is the place you mentioned it will be.

Testing an replace requires a brand new model, so make some small, seen change to your app. Increment the model and construct numbers, then archive, notarise and export as earlier than. Discover the read-write disk picture and mount it. Change the app there along with your new model after which eject the disk picture. Create a brand new read-only disk picture and exchange the copy in your Releases folder with it.

Run the ./bin/generate_appcast once more and it’ll add a brand new entry to your appcast.xml file with the brand new model information.

If you wish to add some launch notes, open appcast.xml in a textual content editor. The highest entry is the newest. You possibly can embody an outline tag and for those who use the <![CDATA[ ... ]]> wrapper, you possibly can add HTML:

Adding release notes

Add the Releases folder as earlier than after which run your first model of the app. Verify for updates and see what occurs.

If it doesn’t work, verify the Console app and see for those who can see any errors there that may level you in the proper course.

This is usually a irritating course of, however after you have all of it arrange appropriately, it really works very properly. I added a ReadMe to my mission itemizing the steps I have to observe when publishing an replace, in order that I don’t have to recollect them each time. I like to recommend this or one thing related.

Abstract

Sparkle is a superb instrument and after you have the whole lot configured, it really works rather well. Configuring it may be tough, particularly as their docs cowl so many various use instances.

Try the GitHub repo for my To-Day app to see how I’ve configured it.

You probably have any recommendations or for those who run into any issues following this information, please contact me utilizing one of many hyperlinks under or via the Contact web page. And for those who discovered this text helpful, I’d love you to buy me a coffee.

Source Link

What's Your Reaction?
Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0
View Comments (0)

Leave a Reply

Your email address will not be published.

2022 Blinking Robots.
WordPress by Doejo

Scroll To Top