macOS Distribution
macOS applications are typically distributed in a .app
application bundle. To make .NET Core and Avalonia projects work in a .app
bundle, some extra legwork has to be done after your application has gone through the publishing process.
With Avalonia, you'll have a .app
folder structure that looks like this:
MyProgram.app
|
----Contents\
|
------_CodeSignature\ (stores code signing information)
| |
| ------CodeResources
|
------MacOS\ (all your DLL files, etc. -- the output of `dotnet publish`)
| |
| ---MyProgram
| |
| ---MyProgram.dll
| |
| ---Avalonia.dll
|
------Resources\
| |
| -----MyProgramIcon.icns (icon file)
|
------Info.plist (stores information on your bundle identifier, version, etc.)
------embedded.provisionprofile (file with signing information)
For more information on Info.plist
, see Apple's documentation here.
Making the application bundle
There are a few options available for creating the .app
file/folder structure. You can do this on any operating system, since a .app
file is just a set of folders laid out in a specific format and the tooling isn't specific to one operating system. However, if you build on Windows outside of WSL, the executable may not have the right attributes for execution on macOS -- you may have to run chmod +x
on the published binary output (the output generated by dotnet publish
) from a Unix machine. This is the binary output that ends up in the folder MyApp.app/Contents/MacOS/
, and the name should match CFBundleExecutable
.
The .app
structure relies on the Info.plist
file being properly formatted and containing the right information. Use Xcode to edit Info.plist
, it has auto-completion for all properties. Make sure that:
- The value of
CFBundleExecutable
matches the binary name generated bydotnet publish
-- typically this is the same as your.dll
assembly name without.dll
. CFBundleName
is set to the display name for your application. If this is longer than 15 characters, setCFBundleDisplayName
too.CFBundleIconFile
is set to the name of youricns
icon file (including extension)CFBundleIdentifier
is set to a unique identifier, typically in reverse-DNS format -- e.g.com.myapp.macos
.NSHighResolutionCapable
is set to true (<true/>
in theInfo.plist
).CFBundleVersion
is set to the version for your bundle, e.g. 1.4.2.CFBundleShortVersionString
is set to the user-visible string for your application's version, e.g.Major.Minor.Patch
.
If you need a protocol registration or file associations - open plist files from other apps in Applications folder and check out their fields.
Example protocol:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>AppName</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>CFBundleURLSchemes</key>
<array>
<string>i8-AppName</string>
</array>
</dict>
</array>