Guide

Compiler votre app .NET MAUI pour iOS sans posséder de Mac

Vous pouvez écrire une app .NET MAUI dans Visual Studio sous Windows. Le build iOS demande quand même un Mac, car il demande Xcode. La réponse de Microsoft est Pair to Mac, qui pilote un Mac en SSH. Cette page montre une voie plus simple que nous avons testée : installer .NET sur un Mac et compiler avec dotnet dans son terminal.

Pourquoi MAUI demande un Mac pour iOS

La page Pair to Mac de Microsoft est claire. Compiler des apps iOS demande les outils de build d’Apple, et ils ne tournent que sur un Mac. Visual Studio sous Windows envoie le build à un Mac en SSH. Le Mac compile et signe l’app.

L’ancien contournement a disparu. Microsoft a arrêté Visual Studio pour Mac le 31 août 2024. Sur un Mac, vous utilisez maintenant la ligne de commande dotnet, ou un éditeur comme VS Code avec le C# Dev Kit.

La voie testée : dotnet sur le Mac

Connectez-vous au Mac en SSH et installez le SDK .NET. Ajoutez ensuite le workload MAUI et compilez. Notre test a utilisé le script d’installation de Microsoft et une nouvelle app créée avec le template MAUI. Voici le job de build du workflow, tel qu’il a réussi sur le runner macos-26 de GitHub le 19 octobre 2026.

name: maui-ios
on: workflow_dispatch
jobs:
  build-ios-xcode-26-6:
    runs-on: macos-26
    steps:
      - name: Install .NET SDK 10.0.401 into the home folder
        run: |
          curl -sSL https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh
          bash dotnet-install.sh --version 10.0.401 --install-dir "$HOME/.dotnet"
          echo "DOTNET_ROOT=$HOME/.dotnet" >> "$GITHUB_ENV"
          echo "$HOME/.dotnet" >> "$GITHUB_PATH"
      - run: dotnet --version
      - name: Install the MAUI workload (workload set 10.0.401)
        run: time dotnet workload install maui --version 10.0.401
      - run: dotnet workload --info
      - run: sudo xcode-select -s /Applications/Xcode_26.6.app
      - run: xcodebuild -version && sw_vers
      - run: dotnet new maui -n MauiDemo
      - run: grep -n "TargetFrameworks" MauiDemo/MauiDemo.csproj
      - name: Build for the iOS Simulator (Debug)
        run: time dotnet build -f net10.0-ios -c Debug
        working-directory: MauiDemo
      - name: Build for a device, unsigned (Release, ios-arm64)
        run: time dotnet build -f net10.0-ios -c Release -r ios-arm64 -p:EnableCodeSigning=false
        working-directory: MauiDemo
      - name: Publish for a device, unsigned
        continue-on-error: true
        run: time dotnet publish -f net10.0-ios -c Release -r ios-arm64 -p:EnableCodeSigning=false
        working-directory: MauiDemo
      - run: find bin -maxdepth 5 \( -name "*.app" -o -name "*.ipa" \) -print -exec du -sh {} \;
        working-directory: MauiDemo

Sur votre propre Mac, lancez les mêmes commandes en SSH. Le script d’installation met .NET dans votre dossier personnel, donc il n’a pas besoin de sudo. Définissez ces deux variables dans chaque nouveau terminal, ou ajoutez-les à ~/.zshrc :

export DOTNET_ROOT=$HOME/.dotnet
export PATH=$PATH:$DOTNET_ROOT:$DOTNET_ROOT/tools

Installez le workload maui complet, pas maui-ios. Notre premier run a essayé maui-ios seul. La restauration a échoué avec NETSDK1147, car le template cible aussi Android et le workload android manquait.

EnableCodeSigning=false vous permet de tester un build pour appareil sans certificat. Le résultat ne peut aller ni sur un téléphone ni chez Apple. Il prouve seulement que votre code compile pour ios-arm64.

Ce que le run a affiché

Ces lignes sont copiées du journal du job. Le job complet a pris 3 minutes 21 secondes.

Xcode 26.6
Build version 17F113
 Workload version: 10.0.401
Successfully installed workload(s) maui.
  MauiDemo -> .../bin/Debug/net10.0-ios/iossimulator-arm64/MauiDemo.dll
Build succeeded.
Time Elapsed 00:00:23.70
  MauiDemo -> .../bin/Release/net10.0-ios/ios-arm64/MauiDemo.dll
Build succeeded.
Time Elapsed 00:02:06.70
  Created the package: bin/Release/net10.0-ios/ios-arm64/publish//MauiDemo.ipa
 97M	bin/Debug/net10.0-ios/iossimulator-arm64/MauiDemo.app
 16M	bin/Release/net10.0-ios/ios-arm64/publish/MauiDemo.ipa

Le build pour le simulateur a pris 24 secondes. Le build pour appareil a pris un peu plus de 2 minutes, car un build Release compile à l’avance pour arm64.

Accorder le workload et Xcode

Chaque version de .NET pour iOS demande une version exacte de Xcode. Les notes de version sur GitHub, dans dotnet/macios, la donnent. Au 19 octobre 2026, voici les workload sets de .NET 10 :

  • 10.0.402.1 (iOS 27.1.10018) demande Xcode 27.1. Il est sorti le 19 octobre 2026, avec le SDK .NET 10.0.402.
  • 10.0.402 (iOS 27.0.10722) demande Xcode 27.0.
  • 10.0.401 (iOS 26.5.10318) demande Xcode 26.6. C’est la paire que nous avons lancée.

Nous avons aussi lancé exprès la mauvaise paire. Avec le workload set 10.0.402.1 et Xcode 26.6 sélectionné, le build s’est arrêté sur cette erreur :

error : This version of .NET for iOS (27.1.10018) requires Xcode 27.1.
The current version of Xcode is 26.6. Either install Xcode 27.1, or use
a different version of .NET for iOS.

Pour Xcode 27.1, la version par défaut sur nos Mac, les notes de version donnent cette paire. Nous n’avons pas pu la lancer, car l’image macos-26 de GitHub n’a pas Xcode 27.

bash dotnet-install.sh --version 10.0.402 --install-dir "$HOME/.dotnet"
dotnet workload install maui --version 10.0.402.1

L’autre solution de Microsoft est de garder plusieurs Xcode et de passer de l’un à l’autre. Vérifiez lequel est actif, listez ceux qui sont installés, et choisissez-en un :

xcode-select -p
ls -d /Applications/Xcode*.app
sudo xcode-select -s /Applications/Xcode.app
xcodebuild -version

Sur un Mac MacRun, /Applications/Xcode.app est Xcode 26.6 et /Applications/Xcode-27.1.app est Xcode 27.1, la version par défaut. Sur un autre Mac, utilisez le nom exact affiché par ls. Vous pouvez aussi définir DEVELOPER_DIR pour une seule session de terminal. Microsoft signale aussi un changement cassant pour Xcode 27. Les apps iOS doivent adopter le cycle de vie UIScene, sinon elles plantent au lancement.

Lancer, signer et publier sur le Mac

Pour lancer l’app dans le simulateur, le guide CLI de Microsoft utilise la cible Run. Vous regardez le simulateur sur l’écran du Mac, depuis Windows en VNC.

dotnet build -t:Run -f net10.0-ios

Pour l’App Store, ajoutez votre identité de signature et votre profil. Voici l’exemple de Microsoft avec net8.0 remplacé par net10.0. Nous n’avons pas pu le lancer, car notre test n’avait pas de certificat.

dotnet publish -f net10.0-ios -c Release -p:ArchiveOnBuild=true \
  -p:RuntimeIdentifier=ios-arm64 \
  -p:CodesignKey="Apple Distribution: John Smith (AY2GDE9QM7)" \
  -p:CodesignProvision="MyMauiApp"

Le .ipa arrive dans bin/Release/net10.0-ios/ios-arm64/publish. Microsoft conseille Transporter pour l’envoi. Notre guide pour publier sans Mac couvre les clés API et TestFlight.

Pair to Mac depuis Visual Studio : ce que demande la documentation

Vous préférez peut-être rester dans Visual Studio sous Windows. Pair to Mac demande alors ceci, d’après la documentation de Microsoft :

  • Remote Login activé dans les réglages Partage du Mac, avec l’accès complet au disque pour les utilisateurs distants.
  • Xcode installé et ouvert une fois. Pair to Mac ne peut pas installer Xcode.
  • Mono installé, et Rosetta sur un Mac Apple silicon.
  • Un Mac que Windows peut joindre. S’il n’apparaît pas dans la liste, utilisez Add Mac et tapez son adresse.

Visual Studio installe ensuite .NET sur le Mac en SSH. Sur un Mac MacRun, l’adresse serait son adresse Tailscale. Nous n’avons pas testé Pair to Mac via Tailscale, donc considérez-le comme non testé. La voie dotnet ci-dessus est celle que nous avons lancée.

Qui ne devrait pas louer un Mac pour ça

  • Le build seul. Le workflow ci-dessus tourne tel quel sur GitHub. Les dépôts publics ne paient rien pour les runners standard. Les dépôts privés paient $0.062 la minute pour macOS, d’après la page de facturation de GitHub. Notre job de 3 minutes 21 secondes est facturé 4 minutes, environ 25 cents.
  • Déboguer sur votre propre iPhone. Hot Restart dans Visual Studio 2022 déploie les builds Debug sur un iPhone branché en USB, sans Mac. Il n’est pas pris en charge dans Visual Studio 2026.
  • Le travail iOS quotidien. Si vous avez besoin du Mac tous les jours, en acheter un peut revenir moins cher sur un an.

Quand un Mac loué convient

Un job CI ne peut pas vous montrer l’app. Un Mac loué vous donne le simulateur, le débogueur et une configuration de signature que vous pouvez corriger à la main. Un pass journée MacRun est un Mac mini M6 dédié pour $15, et une semaine coûte $59. Xcode 27.1 est la version par défaut et Xcode 26.6 est installé aussi. .NET n’est pas préinstallé. Vous l’installez avec les commandes ci-dessus. L’installation du workload a pris 34 secondes dans notre test.

Le Mac est effacé à la fin du pass. Poussez votre code et copiez votre .ipa avant. Voyez Xcode depuis Windows pour configurer l’écran à distance.

Questions fréquentes

Puis-je compiler une app iOS .NET MAUI sous Windows sans Mac ?

+

Pas un build complet. La documentation de Microsoft dit que les outils de build iOS ne tournent que sur un Mac. Visual Studio envoie le build à un Mac via Pair to Mac, ou vous compilez directement sur un Mac avec dotnet.

Quel Xcode faut-il pour .NET 10 MAUI ?

+

Cela dépend du workload set. Au 19 octobre 2026, le workload set 10.0.402.1 demande Xcode 27.1, et 10.0.401 demande Xcode 26.6. Les notes de version de dotnet/macios donnent le Xcode de chaque version.

Pourquoi mon build MAUI demande-t-il un autre Xcode ?

+

Votre workload et le Xcode sélectionné ne correspondent pas. Changez de Xcode avec sudo xcode-select -s, ou installez le workload set qui correspond à votre Xcode avec dotnet workload install maui --version.

Visual Studio pour Mac existe-t-il encore ?

+

Non. Microsoft a arrêté Visual Studio pour Mac le 31 août 2024. Sur un Mac, utilisez la ligne de commande dotnet ou VS Code avec le C# Dev Kit.

Pair to Mac marche-t-il avec un Mac dans le cloud ?

+

Microsoft demande un Mac que Windows peut joindre, avec Remote Login activé. Nous n’avons pas testé Pair to Mac via Tailscale. Compiler avec dotnet dans le terminal du Mac est la voie que nous avons testée.

Puis-je compiler une app iOS MAUI non signée ?

+

Oui. Dans notre test, dotnet build avec -r ios-arm64 et -p:EnableCodeSigning=false a produit une app pour appareil sans certificat. Elle ne peut être ni installée ni envoyée tant que vous ne l’avez pas signée.

Guides associés