.NET MAUI iOS target publishing/archiving
See original GitHub issueTL;DR
- Archiving and publishing a .NET MAUI iOS app (both .NET MAUI and .NET MAUI Blazor) to an ipa works, I have been able to sign the binary. Additionally I could upload the ipa to the App Store, put it through Testflight, download and run it successfully. See the steps below.
- This is all through the command-line, UI support in Visual Studio is not there (yet)
Description
I have been trying to see if publishing an iOS app through .NET MAUI works at the moment. This description assumes that you have basic knowledge of publishing to the Apple App Store.
1. Prerequisites
- All the required tools and bits are installed to create and run .NET MAUI iOS apps successfully, both on your Windows machine as well as a macOS build host
- That includes connecting to a macOS build host
- You will have need to connected to the macOS build host before, in which case your password is cached, or you need to know the credentials to the user account that is used on your macOS build host that is used to build your app
- In addition to the credentials you will need the IP address of your macOS build host
- Make sure that your
info.plist
file contains a valid version number and package identifier (i.e.com.mycompany.app
)
2. Gather Signing Requirements
If you currently have a certificate and provisioning profile that you can use, for example when you are updating an existing app, you can skip this step. However, you do need to know the name of the certificate in the Keychain app. See Find Certificate Name below. And you’ll need to know the name of the provisioning profile, see Creating a Distribution Profile below.
These can also be obtained from your current project, probably in the iOS project csproj file.
2.1 Creating a Distribution Certificate
This process is no different between Xamarin, Xamarin.Forms, .NET MAUI or even a native app. Follow the steps in the current doc we have about this, under “Creating a Distribution Certificate”.
2.2 Find Certificate Name
After following the guide above, and the certificate is installed, make sure to open the Keychain app and localize the certificate you just added. In the screenshot below the name would be iPhone Distribution: Gerald Versluis (AY5KBJ6RN9)
. You will need this to sign your ipa file.
2.3 Creating a Distribution Profile
Next thing we need is a distribution profile. Like the distribution certificate, this process is no different for Xamarin, Xamarin.Forms, .NET MAUI or a native app. Follow the steps in the current doc we have about this, under “Creating a Distribution Profile”.
Make sure that with step 6, where you name your distribution profile, note the name down. You will need that to sign your ipa file. In the screenshot below the name would be iosmauisigning
.
3. Build your .NET MAUI iOS app
3.1 Add a (dummy) Entitlements.plist
File (Optional)
At the time of writing the default templates do not have a Entitlements.plist
file, this could be needed depending on what iOS features you’re using, see this doc for more info. Add a new file under Platforms/iOS/Entitlements.plist
.
If you don’t have a specific need for it, fill it with the default contents down below. If you have an existing app, you can copy it from there as well.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
</dict>
</plist>
3.2 Update Your csproj File With Signing Information
We need to add the information we got from above into our csproj file. If you have an existing app, you can copy this from your iOS csproj file. The information will look like this, and needs to be contained within the <Project></Project>
node
<PropertyGroup Condition="$(TargetFramework.Contains('-ios')) and '$(Configuration)' == 'Release'">
<RuntimeIdentifier>ios-arm64</RuntimeIdentifier>
<!-- Only needed when you have a need for entitlements -->
<!-- <CodesignEntitlement>Entitlements.plist</CodesignEntitlement> -->
<CodesignKey>iPhone Distribution: Gerald Versluis (AY5KBJ6RN9)</CodesignKey>
<CodesignProvision>iosmauisigning</CodesignProvision>
</PropertyGroup>
This information will only be added if you are building the iOS target and building the release configuration. Tweak this as needed.
I think all the info speaks for itself, the runtime identifier is a fixed value, all the others are values we got from the steps above.
3.3 Build and Sign Your App
Navigate to the folder that holds the source for your .NET MAUI iOS app, and execute the following command:
dotnet publish -f:net6.0-ios -c:Release /p:ServerAddress={macOS build host IP address} /p:ServerUser={macOS username} /p:ServerPassword={macOS password} /p:TcpPort=58181 /p:ArchiveOnBuild=true /p:_DotNetRootRemoteDirectory=/Users/{macOS username}/Library/Caches/Xamarin/XMA/SDKs/dotnet/
A few things to note here:
- Replace the IP address in
/p:ServerAddress
- Replace the username in
/p:ServerUser
- Either replace the password in
/p:ServerPassword
or leave out that switch altogether. If you have connected with your macOS build host before, your password is cached and it shouldn’t be needed. - The
/p:_DotNetRootRemoteDirectory
option seems to be required. Note that you need to replace the username in the path.
An example of this command could look like:
dotnet publish -f:net6.0-ios -c:Release /p:ServerAddress=192.168.1.77 /p:ServerUser=jfversluis /p:TcpPort=58181 /p:ArchiveOnBuild=true /p:_DotNetRootRemoteDirectory=/Users/jfversluis/Library/Caches/Xamarin/XMA/SDKs/dotnet/ /p:EnableAssemblyILStripping=false /p:ServerPassword=D0tN€T-M@uI-iS-@w€s0mE
After this command had completed successfully you should see your App Store ready ipa file under bin\Release\net6.0-ios\ios-arm64\publish
.
Note: during building I got a popup on my macOS machine asking for permission to run codesign
. Make sure to have a look at your macOS machine if the process seems to take really long/fail. I suspect clicking “Always Allow” should prevent that from happening with future builds.
I was able to upload this through the Transporter app, make it available through Testflight and download and run the app successfully
Notes
- Instead of specifying all the options with the
dotnet publish
command you can also add all of those to your csproj. The part after/p:
would be the node name. E.g./p:ArchiveOnBuild=true
would be<ArchiveOnBuild>true</ArchiveOnBuild>
- In extend to that, the options that I added to the csproj file can also be options in the
dotnet publish
command. E.g.<CodesignProvision>iosmauisigning</CodesignProvision>
would become/p:CodesignProvision=iosmauisigning
.
Related Resources
- https://docs.microsoft.com/xamarin/ios/deploy-test/app-distribution/app-store-distribution/
- https://docs.microsoft.com/xamarin/ios/deploy-test/provisioning/entitlements
- https://stackoverflow.com/questions/70437037/net-6-publishing-android-application
Also See
Issue Analytics
- State:
- Created 2 years ago
- Reactions:8
- Comments:21 (2 by maintainers)
Official docs for this are now live here: https://docs.microsoft.com/dotnet/maui/ios/deployment/overview
So with RC1 it does not build at all