Catalina, App Notarization, and Sparkle • furbo.org


We lately began updating our macOS apps for Catalina: to this point there have been only a few points with APIs and frameworks. The largest hurdle has been the brand new notarization course of that’s required for apps signed with a Developer ID: prospects will probably be unable to obtain and launch your product simply till this step is accomplished.

Notarization entails an additional step in your construct course of: you add an archived binary to Apple’s server with Xcode’s Organizer window and a short while later, you possibly can export the binary. In the event you’ve automated your construct course of, you’ll have to make adjustments to your scripts to accommodate this new guide step. Apple’s documentation explains the method properly.

Earlier than you possibly can notarize the app, you’ll have to allow the hardened runtime within the goal’s Capabilities panel. After flipping the change you’ll see a array of exceptions and entry permissions. You’ll wish to survey this record rigorously: for one product we would have liked Apple Occasions, for an additional Location was required.

Issues begin to get tough if you go to add the binary: when you’re utilizing Sparkle, it’s in all probability been codesigned with out the hardened runtime, so that you’ll instantly see an error.

Sparkle With out a Sandbox

The way you cope with this error depends upon which of the Sparkle variations you’re utilizing. In case your app isn’t sandboxed, your life will probably be a bit less complicated as a result of there are fewer belongings you’ll have to signal manually.

After the goal’s Copy Information construct part the place the Sparkle.framework is moved into the appliance bundle, you’ll have to create a brand new Run Script step: I known as ours “Signal Frameworks”. The script seems like this:


codesign --verbose --force --deep -o runtime --sign "$IDENTITY" "$LOCATION/Sparkle.framework/Variations/A/Assets/AutoUpdate.app"
codesign --verbose --force -o runtime --sign "$IDENTITY" "$LOCATION/Sparkle.framework/Variations/A"

The important thing half on this step is the -o runtime. The codesign guide web page describes this flag as:

On macOS variations >= 10.14.0, opts signed processes right into a hardened runtime surroundings which incorporates runtime code signing enforcement, library validation, exhausting, kill, and debugging restrictions. These restrictions could be selectively relaxed through entitlements. Be aware: macOS variations older than 10.14.0 ignore the presence of this flag within the code signature.

The excellent news right here is that the construct adjustments we’re making gained’t have an effect on your app when it runs on an older model of macOS.

Sparkle in a Sandbox

In case your macOS app is in a sandbox, you’ll be utilizing the model that depends on XPC companies to carry out the replace. Like all the pieces else in your utility bundle, these will have to be signed appropriately earlier than you possibly can submit your app for notarization.

The “Signal Frameworks” construct part ought to appear to be this:


codesign --verbose --force -o runtime --sign "$IDENTITY" "$LOCATION/Sparkle.framework/Variations/A/Assets/AutoUpdate"
codesign --verbose --force --deep -o runtime --sign "$IDENTITY" "$LOCATION/Sparkle.framework/Variations/A/Assets/Updater.app"
codesign --verbose --force -o runtime --sign "$IDENTITY" "$LOCATION/Sparkle.framework/Variations/A"

You’ll additionally add a brand new Run Script construct part simply earlier than the XPC Companies are embedded in your utility bundle. Because you’ll solely want to do that for launch builds, the script seems like this:


if [ "${CONFIGURATION}" = "Release" ]; then
    $PROJECT_DIR/Sparkle/bin/codesign_xpc "$IDENTITY" $BUILT_PRODUCTS_DIR/*.xpc

However wait, we’re not finished but! You’ll additionally have to replace the codesign_xpc Python script with the -o runtime flag. It seems like this if you’re finished:

def _codesign_service(id, path, entitlements_path=None):
    command = ["codesign", "-f", "-o", "runtime", "-s", identity, path] + ([] if entitlements_path is None else ["--entitlements", entitlements_path])
    log_message(" ".be part of(map(sanitize, command)))

You’re Not Carried out But

At this level, you need to have the ability to do a construct the place all the pieces in your app is utilizing the hardened runtime. It’s extra seemingly that you simply’ve had some sort of challenge alongside the best way: this Apple doc helped get me over the tough patches. (Fortunately, I didn’t should write it this time round.)

After the notarization add completes, you’ll see “Uploaded to Apple” within the organizer, then after a couple of minutes you’ll get an e-mail and Xcode notification that your app is “Able to distribute”. Within the righthand panel beneath “Distribute App”, you’ll see that the “Export Notarized App” button is enabled and can be utilized to position the signed bundle anyplace in your Mac for additional processing.

In our case, we needed to break up up the construct scripts into two elements: beforehand we had a single script that did the construct, signed it with the Developer ID, after which created an appcast. Sparkle’s XML file is now created with a separate script that additionally prepares the discharge to be checked into our repositories.

One remaining be aware: these directions are primarily based on Xcode 10, which is at the moment the one improvement software that can be utilized to submit an app for notarization or the Mac App Retailer. Earlier than we figured that out, we discovered that Xcode 11 does a greater job passing alongside the -o runtime flag throughout a framework’s Code Signal On Copy. It’s seemingly that every one this work you simply did will solely be wanted for a number of months. Sigh.



Leave a Comment