How to develop auto-update for MacOS application in Objective C?

I have a desktop MacOS app written in Objective-C. I want to add this functionality:

I assume that somewhere on a server sits new app version xx.1.1.dmg

  1. app shows that an update is available
  2. user agrees to update
  3. app downloads the update
  4. app prompts user to agree to install & restart the app
  5. magic happens


QUESTIONs:


A. Is there a framework to start the download, display the progress and then update the running application or do I have to implement all this? The update process of many applications look like very similar so it seams like some shared functionality is used.

B. Once you have the update archive on local drive. How to you "replace" the old app with the new one. Do you "just" unpack the archive over the existing app folder? This could be problematic because of open files.

C. How do you force app restart?

D. Is there a way to schedule "after-app-quit" actions which would solve the issues described in B? Could these actions also include the new app start?

Accepted Reply

There may be a framework available somewhere, but it is so simple that it is probably easier to do it yourself.


A. What I do in my own code is run the download in the background – it's a GET with If-Modified-Since set, so that it will only download if a newer version exists on the server. I store the downloaded file in the Application Support directory. None of this is particularly complicated. Once the download has completed, I quietly include a button in the UI to say that an update is available to be installed. (I could equally have chosen to pop up a message – perhaps on the next app startup).


B. The best thing is not to upload a

.dmg
but a
.pkg
file. (Xcode can create these files). Simply opening this file will do the whole installation process, and it will automatically close the app before installing the update. You start it simply with


[[NSWorkspace sharedWorkspace] openFile:filenameOfDownloadedPkgFile]
  • Hi universalis, hopefully you see this message

    Your answer above was literally one of the - let's say specifically - five must useful things I have ever seen, having spent 20 yrs reading sites like this and SO !

    Really, thanks.

Add a Comment

Replies

There may be a framework available somewhere, but it is so simple that it is probably easier to do it yourself.


A. What I do in my own code is run the download in the background – it's a GET with If-Modified-Since set, so that it will only download if a newer version exists on the server. I store the downloaded file in the Application Support directory. None of this is particularly complicated. Once the download has completed, I quietly include a button in the UI to say that an update is available to be installed. (I could equally have chosen to pop up a message – perhaps on the next app startup).


B. The best thing is not to upload a

.dmg
but a
.pkg
file. (Xcode can create these files). Simply opening this file will do the whole installation process, and it will automatically close the app before installing the update. You start it simply with


[[NSWorkspace sharedWorkspace] openFile:filenameOfDownloadedPkgFile]
  • Hi universalis, hopefully you see this message

    Your answer above was literally one of the - let's say specifically - five must useful things I have ever seen, having spent 20 yrs reading sites like this and SO !

    Really, thanks.

Add a Comment

Many Mac apps use the Sparkle framework (sparkle-project.org) for downloading and installing updates.

A. Sparkle does this. However, Sparkle has has security issues in the past. More recently, it didn't work on Mojave. I don't know if that has been fixed or not. I tried it once and found it quite difficult. I could get pretty much the same functionality with my own, hand-rolled solution. I've only had a couple of complaints.

B. It would probably be safer to unpack in a safe location and quickly swap out the old for the new. You will want to ensure that the old software is no longer running before you do this.

C. You don't. You ask first. Then, depending on what you've installed, there are different procedures to gracefully shut things down.

D. Sure.


E. You didn't mention this, but I will. You have to be careful about automatic updates these days. That is going to require a network connection. A user's IP is personally identifiable information. You are legally required to ask for consent first. The fines start at $10 million and go up from there. Technically, this only pertains to people in the EU. But the only way to find out if someone is in the EU is to make a network request, which you have to ask for in case they are in the EU.

F. A better solution to either a DMG or a PKG is a simple .APP. Let the user drag it where it needs to go and drag it in the trash to uninstall. Anything you need to do can be done inside an app bundle. If you need to do something else, first consider not doing that. If you must run something in the background, consider a modern login item.