Sparkle supports “delta updates” for your application: when possible, users can download only the bits that have changed. These updates can be much smaller to download and faster to install.
For each new version you release, you can provide a list of .delta
files in addition to the “full” archive of the version. Each .delta
contains the information necessary to upgrade from a single older version.
If the user is running a version of the app for which you haven’t provided a .delta
, or if the patch doesn’t apply cleanly, they’ll use the non-delta “full” update.
The ./bin/generate_appcast
tool that comes with Sparkle automatically generates and signs delta updates.
To generate a .delta
, you use the BinaryDelta
tool included with Sparkle like this:
BinaryDelta create --version=$FORMAT_VERSION path/to/old/MyApp.app path/to/new/MyApp.app patch.delta
Please see the compatibility section below on what $FORMAT_VERSION
to use.
To verify that your generated patch applies correctly:
BinaryDelta apply path/to/old/MyApp.app path/to/patched/MyApp.app patch.delta
Sign each .delta
file and add an enclosure to your appcast’s <item>
in <sparkle:deltas>
for each .delta
file:
<item>
<title>Version 2.0 </title>
<link>https://myproductwebsite.com</link>
<sparkle:version>2.0</sparkle:version>
<description>foo bar baz</description>
<pubDate>Wed, 09 Jan 2006 19:20:11 +0000</pubDate>
<enclosure url="http://you.com/2.0_full.zip"
length="123"
type="application/octet-stream"
sparkle:edSignature="..." />
<sparkle:deltas>
<enclosure url="http://you.com/1.5-2.0.delta"
sparkle:deltaFrom="1.5"
length="1485"
type="application/octet-stream"
sparkle:edSignature="..." />
<enclosure url="http://you.com/1.6-2.0.delta"
sparkle:deltaFrom="1.6"
length="1428"
type="application/octet-stream"
sparkle:edSignature="..."
sparkle:deltaFromSparkleExecutableSize="1844096"
sparkle:deltaFromSparkleLocales="en,ca,fr,hr,hu" />
</sparkle:deltas>
</item>
Sparkle 2.3 introduces two optional attributes for testing if a delta update can be applied before downloading a delta update. These are the sparkle:deltaFromSparkleExecutableSize
and sparkle:deltaFromSparkleLocales
attributes. The sparkle:deltaFromSparkleExecutableSize
attribute refers to the file size in bytes of Sparkle.framework/Versions/B/Sparkle
from the older application. The deltaFromSparkleLocales
refers to a comma-delimited partial list of .lproj
locale directory names (minus the path extension) in Sparkle.framework/Versions/B/Resources/
from the old application. These attributes help Sparkle detect cases where a user strips your application’s localizations or architecture slices. In these cases, Sparkle can skip attempting to download and apply a delta update.
When you create a delta update between two versions of your application, you must ensure you are using a delta format version that your older application knows how to patch. Below is a table describing the requirements for each binary delta version.
Delta Format | Supports | Changes |
---|---|---|
3 | Sparkle 2.1 | More efficient custom delta container format, lzma compression + other compression options, file rename heuristic tracking. |
2 | Sparkle 1.10 | Improved and changed hash function for reducing collisions. |
1 | Sparkle 1.5 | Added initial binary delta format using libxar and bzip2 compression. Tracking of insertions, deletions, and binary file diffs using bsdiff. |
Note if you are using generate_appcast
, picking the delta version to use is automatically handled. If you are using BinaryDelta create
though, you will need to pass the appropriate delta version via the --version
argument.
Older delta format versions will eventually be phased out. Please do not create new patches using an older version than necessary. Always use the latest tools when creating delta patches because they may contain minor bug fixes that don’t require a major format change.
In any case where a binary delta update fails to install, Sparkle falls back to downloading and installing the regular full update. Sparkle verifies a checksum to ensure the resulting application has been patched successfully.
We recommend reading Apple’s article on reducing the download size for iOS app updates, which is applicable here too. To reword:
BinaryDelta --verbose
will show a diff of what has changed.*.framework/Versions/
has changed.Binary delta updates do not support and will reject the following metadata:
0755
.Binary delta updates will pass but ignore or warn about the following metadata:
0755
are ignored, and 0755
will always be used instead. A warning will be issued. Some filesystems, e.g. Linux ones, do not support file permissions on symbolic links.0755
or 0644
will be respected, but a warning may be issued (from Sparkle 2.1 onwards).Get Info
window) are ignored/preserved when applying patches, but prohibited when creating patches (from Sparkle 2.2 onwards).Binary delta updates do support the following meta changes:
foo
-> FOO
) changes.ditto --hfsCompression
(i.e, we don’t track this compression on a per file basis).