Installer for macOS (Sign and Notarize in Unity)

I have made a macOS Installer Generator (I was tired of doing this in the commandline all the time).

Asset

Try before you buy
See for yourself how the installer will look like. Download the Demo Installer package.

Links: Manual | Demo

If anyone has some feedback I’d be glad to have it .-)

Hey! I’m very interested in purchasing this, but had a quick question:
I see that it’s a step-by-step process. Is there a way to automate the steps one after the other for a single-click export?

Thanks!

Hi, sadly no (or at least not without some custom coding by you).

One reason is that certain steps include wait times from Apple servers. You have to upload the app twice to their servers and then wait for the reply.

BUT the source code is included in the asset and if you want you can use the API to write your own automation script.

Cool, thanks for the info!

1 Like

Hey, I purchased the asset and am having some trouble.
I followed all the steps, but when I try to sign the .app, I get an error saying No Such File or Directory.
I dragged the .app onto the Source App field, and it is displaying the path.
It looks like it’s relative to the project folder. I store the .app in a Builds folder in the project’s root (next to Assets folder).

The path being displayed in the Source App field is Builds/APP_NAME.app

Is that incorrect?
Thanks!

Edit: After filling in the entire path (starting with /Users/) it moved forward. But dragging the app onto the field only gives the relative path. Maybe that’s a bug?

Edit 2: So after moving forward, it still fails because of another asset I’m using. Not sure what could be the trouble here. I did reach out to the developer of that asset, but figured I’d ask here too.
This is the error:

replacing existing signature
/Users/judahmantell/Documents/GitHub/SceneForge Master/SceneForge Master/Assets/Kamgam/MacInstaller/MacInstallerBuild/tmp~/app-signed/Intel_SceneForge Studio-signed.app: bundle format unrecognized, invalid, or unsuitable
In subcomponent: /Users/judahmantell/Documents/GitHub/SceneForge Master/SceneForge Master/Assets/Kamgam/MacInstaller/MacInstallerBuild/tmp~/app-signed/Intel_SceneForge Studio-signed.app/Contents/Frameworks/__MACOSX/UniversalDeepLink.framework
ProcessHelper: Exec was done with exitCode 1 after 7 seconds.

Hi,

Q: The path being displayed in the Source App field is Builds/APP_NAME.app
A: Thanks for reporting this. Hm, if dragged in it should actually resolve the absolute path. That’sodd.
I’ll check if I can reproduce that behaviour. May I ask what exact Unity version you are using? I might help to track this down.

Q: it still fails because of another asset I’m using
A: Can you please try without the mentioned framework. Does it sign then?

At what step exactly does it fail. The “App Sign” or the “Installer Create”?

Another thing to try (for signing) is to remove the “–deep” flag from the “sign-app.sh” script.
You can find it here:
9061150--1252921--upload_2023-6-6_17-21-15.png

Just remove the “–deep” text from the file.
Change this:


to this:

Unity also has some docs on signing: Unity - Manual: Code sign and notarize your macOS application

If you can it would also help if you could send a download link for your project to office@kamgam.com so I can give it a try myself.

Thank you for your help and your patience :slight_smile:

Thank you for the detailed info, I appreciate it!
I’m using the latest 2022 LTS that was released last week or so.

It fails on the App Sign process, the first one.

I’m working with the developer of that asset, and it’s tricky because it uses an external process/application to do its thing, so maybe it’s conflicting. He also asked if the app is being deep signed, so maybe removing that will fix it.

Do you want a copy of the project, or a built application?

Also, having an option to toggle deep signing within the editor would be helpful as well, rather than manually editing the file. Just some feedback :slight_smile:

I’m trying what you suggested now. But had a quick follow up question, if you don’t mind.
I’m having trouble running a built Apple Silicon build, and it gives an error relating to invalid code signature. I was wondering if you had any thoughts on that? I’m hoping that the asset will help fix that.
Here’s info on that:
https://forum.unity.com/threads/apple-silicon-build-crashes-on-startup-code-signature-invalid.1443934/

Edit: Removing the --deep flag did not fix it :frowning: Thank you though!

Edit 2:
For more reference, here’s the full log:

ProcessHelper: Executing in /Users/judahmantell/Documents/GitHub/SceneForge Master/SceneForge Master/Assets/Kamgam/MacInstaller/MacInstallerBuild/: bash -c ‘./sign-app.sh “/Users/judahmantell/Documents/GitHub/SceneForge Master/SceneForge Master/Builds/Intel_SceneForge Studio.app” “secret” “/Users/judahmantell/Documents/GitHub/SceneForge Master/SceneForge Master/Builds/Intel_SceneForge Studio-signed.app”’
Source app path : /Users/judahmantell/Documents/GitHub/SceneForge Master/SceneForge
Master/Builds/Intel_SceneForge Studio.app
File name : Intel_SceneForge Studio
Apple Developer APPLICATION ID : secret
Signed app output path : /Users/judahmantell/Documents/GitHub/SceneForge Master/SceneForge Master/Builds/Intel_SceneForge Studio-signed.app
[2023-06-06 13:50:14][INFO] Signing App process started.
[2023-06-06 13:50:14][INFO] Cleaning /Users/judahmantell/Documents/GitHub/SceneForge Master/SceneForge Master/Assets/Kamgam/MacInstaller/MacInstallerBuild/tmp~/app-signed directory.
/Users/judahmantell/Documents/GitHub/SceneForge Master/SceneForge Master/Assets/Kamgam/MacInstaller/MacInstallerBuild/tmp~/app-signed
[2023-06-06 13:50:14][INFO] Signing app
/Users/judahmantell/Documents/GitHub/SceneForge Master/SceneForge Master/Assets/Kamgam/MacInstaller/MacInstallerBuild/tmp~/app-signed/Intel_SceneForge Studio-signed.app: replacing existing signature
/Users/judahmantell/Documents/GitHub/SceneForge Master/SceneForge Master/Assets/Kamgam/MacInstaller/MacInstallerBuild/tmp~/app-signed/Intel_SceneForge Studio-signed.app: code object is not signed at all
In subcomponent: /Users/judahmantell/Documents/GitHub/SceneForge Master/SceneForge Master/Assets/Kamgam/MacInstaller/MacInstallerBuild/tmp~/app-signed/Intel_SceneForge Studio-signed.app/Contents/Frameworks/UniversalDeepLink.framework
ProcessHelper: Exec was done with exitCode 1 after 4 seconds.

Yes, I was thinking about adding it :slight_smile:
I am sorry to hear that did not help in your case.

I glanced over your other error. It reports “SIGKILL (Code Signature Invalid)”. Probably the issue will go away once you have everything properly signed.

Ideally the whole (buildable) project. Though, complete projects are always complicated because you would have to ask all your third-party vendors (asset devs) to allow you to send me the whole project. An alternative is to strip it bare and make a minimum repro case (that’s what I would prefer).
This might be a good approach for debugging your case anyways. Make a new empty project and try to sign that. If it works then you know the toolchain is okay. Then keep adding stuff until it breaks.

It says “code object is not signed at all … UniversalDeepLink.framework”. This means that your UniversalDeepLink.framework is NOT sigend. Therefore it is logical that the gatekeeper on mac os would kill it.

I’ve found this post by a Unity employee here:
https://discussions.unity.com/t/686782 page-7#post-6974387

I’d suggest you try to sign the framework yourself and then try signing the app again (without --deep and with --deep, just to be sure).

codesign -s 'developer_id' -f pathToApp.app/Contents/Frameworks/UniversalDeepLink.framework

Ideally you would sign all your code libs like that and then use my tool to do the final signing without --deep.

Hope this helps :slight_smile:

1 Like

That is incredibly helpful, I sincerely appreciate your time. I’ll do my best to send over a project via email.
Thanks!

Just a heads up for other users: I removed the --deep flag for testing, and I got an error saying that it was not signed with a valid Developer ID certificate.

Everything worked beautifully once I reimported the package to use the default build script. :smile:

Edit: Quick question though: I see that it creates a special build with the suffix “-signed.” In the final, installed application, does the user see that suffix? It’s not showing on my machine, but with MacOS development, I’ve learned not to trust results on the dev machine!

1 Like

That one is just a temporary filename. It won’t show up in the final app (the one in the /Applications) or the installer process. I like to keep the resulting file for each step around for debugging purposes. That’s where this is comping from.

If at some point you need the signed app without the installer then you can use that file :slight_smile:

1 Like

One more question, if you don’t mind.
Some of the installer resources (like the banner image) get included in the Unity build because it’s in a “Resources” folder.
I don’t want to rename the folder myself because I assume it’s referenced in some of your build scripts. Do they need to be in a “Resources” folder?
Thanks!

Hi, good question. It’s is not necessary to include the resources files in the build. They are just for the installer and are added separately. I’ll have to check if the apple installer format requires it to be named like that.

I think you should be able to make it work if you replace “Resources” with your new folder name in “build-macos-x64.sh”. Just make sure you are replacing case-sensitive as there are a bunch of lowercase “–resources” flags in there too.

I admit, no one has brought this up yet and I myself missed it too. Thank you for reporting it.
I’ll address this in a future update.

1 Like

UPDATE: I just gave it a try and renaming the folder to “Res” and just replacing in the file I mentioned works fine. I’ll submit the update today.

1 Like

Hi! @_geo1 I’ve been a hardcore user of this product since I purchased it, and now something strange is happening:
Every new install (with an incremented version number) is installing my app in a new self-titled subfolder within Applications.
So my applications folder now looks like:

  • Mail.app, Safari.app, Etc.
  • My App.app (original installation)
  • My App / My App.app
  • My App / My App.app

I accidentally changed my Company Name in Player Settings, but I did change it back, and make sure the Installer Product ID and company name are back to the way they were in previous installs, but I’m still having this problem.

Our big product launch is next week, so any help would be greatly appreciated.
Thank you!

Edit: To clarify, even if I install an older version of the installer, it now puts new versions of the app in its own folder. It should overwrite the previous one.

Hi,
thanks for letting me know. I’ll have to try and reproduce this. So the thing that causes the behaviour is the version number increase, right? Does it wokr (properly replace) if you keep the version number the same?
Have there been any other changes, like os upgrades, xCode upgrades? Do you have an old build that works or has it been like that forever and you noticed just now?

Sorry for asking so many questions but the first step in fixing is always reproducing. Thank you :slight_smile:

I just did a test run on my mac (OSX 12.0.1) and there it worked as expected. Maybe it’s something in the new OS 13? What OS are you on?

Thank you for the reply!

I changed the company name, which changed the installer product ID. I have a feeling that’s what caused it. I then changed it back to what it was before (copied and pasted exactly from my version control), and the issue still happens.
I don’t think the version number is doing anything here.
When running the installer, I am getting a popup saying it detects a previous version, but nevertheless, it still acts as if its a new application and installs it in a subfolder.

I’m using MacOS Ventura 13, but I have been for a long time now.Z

Thank you for your help!!

Hi,

hm that’s odd. The “already installed” check is located in the /Template/Distribution file. This is the relevant code used:

function installCheck() {
    /// ...
    if(system.files.fileExistsAtPath('/Applications/__PRODUCT__.app')) {
        my.result.title = 'Previous Installation Detected';
        my.result.message = 'A previous installation of __PRODUCT__ exists at /Applications/__PRODUCT__. This installer will remove the previous installation prior to installing. Please back up any data before proceeding.';
        my.result.type = 'Warning';
        return false;
    }
    return true;
}

The code checks for the existence of the PRODUCT.app in /Applications where PRODUCT will be replaced with the Product Name from the Infos section. If it finds one then the warning is shown. It does not change the install location.

I have not yet tried what happens if you change the product id but leave the product name the same. That might be an issue, though it should install in the same location and not create new folders.

Maybe this is something macOS does if two different IDs try to occupy the same app name. I’ll have to check. - If the OS intervenes here then this might be tricky to resolve. I am not sure if I can track product ID changes in the script.

Can you please try uninstalling all your previous versions and then try installing the old and new ones and check against these assumptions:

  • If you change both ID and NAME then it should not show the dialog and install normally.
  • If you change only the ID then maybe the OS will create a new folder (possibly every time).
  • If you change only the NAME then if should install normally.

UPDATE:
Okay, I have been able to reproduce the folder generation behaviour. To me it only happens if I use the SAME NAME but a DIFFERENT ID. I would guess macOS does that automatically. I’d have to dig into this. As of now I would recommend you stay with the last ID you used to ship to your customers. That should enable you to install normally.

At the moment the install script does not take that into account so it will warn the user even if the app will not get replaced in the end. My guess would be that macOS will treat an app with a new ID as a new app and does not allow it to replace old apps that happen to have the same binary name. After all, the ID is, well, the identifier for the app, not the binary name. To me this makes sense, right? Not sure if Apple even allows to change that behaviour.

What I can do is try to make the “already installed script” check the ID instead of the binary location and only display the warning then, though I am not yet sure the API for this exists.

Hope this helps. Please let me know what your own test results have been. Do you see the same behaviour?

Thank you for doing the deep dive, that makes sense! Yes, so what happened was I changed the ID but kept the name the same. The thing is, after changing the ID back to how it was previously, it still is generating new folders as if it was a different. I did ensure that the value is identical in the settings file too.
Thank you again!

I’d guess this is due to you having the new ID version (with the same binary name) still installed. It would trigger the folder creation every time a binary with the same name exists in /Applications.

Can you try removing all your installs. Then install one old version that you have already shipped to your customers (and you know the ID of). And then make a new install with the same ID. What happens if you install it?

When I try installing the same ID with a different name then I simply get two installs (with different names). When I try install two different IDs with the same name then I get the folder you described.

The multi-folder scenario only happens to me if I still have and install with the OTHER ID in /Applications. As soon as I remove that I don’t get multiple folders anymore. There has to be something mixed up with the IDs in your case or macOS 13 behaves differently. But I admit, with all these IDs I am getting confused. It’s hard to keep track of.

Can you please also check the ID in the build settings for mac store. That sometimes gets me as chainging the company name at the top is not enough.

9268509--1297467--Screenshot 2023-09-02 at 21.27.31.png