diff --git a/.openpublishing.publish.config.json b/.openpublishing.publish.config.json index 589c2f746b..36a9f2e251 100644 --- a/.openpublishing.publish.config.json +++ b/.openpublishing.publish.config.json @@ -7,6 +7,7 @@ "locale": "en-us", "monikers": [], "moniker_ranges": [ + ">=net-maui-7.0" ], "open_to_public_contributors": true, "xref_query_tags": [ diff --git a/docs/TOC.yml b/docs/TOC.yml index b239c7ee83..f34af0b85d 100644 --- a/docs/TOC.yml +++ b/docs/TOC.yml @@ -115,6 +115,8 @@ href: xaml/fundamentals/mvvm.md - name: Compilation href: xaml/xamlc.md + - name: Class modifiers + href: xaml/class-modifiers.md - name: Field modifiers href: xaml/field-modifiers.md - name: Generics @@ -471,6 +473,8 @@ href: user-interface/menu-bar.md - name: Display menu items href: user-interface/menuitem.md + - name: Keyboard accelerators + href: user-interface/keyboard-accelerators.md - name: Shadows href: user-interface/shadow.md - name: Styles @@ -784,8 +788,10 @@ items: - name: Overview href: windows/deployment/overview.md - - name: Publish with the .NET CLI + - name: Publish a packaged app with the .NET CLI href: windows/deployment/publish-cli.md + - name: Publish an unpackaged app with the .NET CLI + href: windows/deployment/publish-unpackaged-cli.md - name: Publish with Visual Studio to a folder href: windows/deployment/publish-visual-studio-folder.md - name: Troubleshooting diff --git a/docs/android/deployment/index.md b/docs/android/deployment/index.md index 310d2686f8..e1a9b6aeed 100644 --- a/docs/android/deployment/index.md +++ b/docs/android/deployment/index.md @@ -8,10 +8,9 @@ ms.date: 04/05/2023 > [!div class="op_single_selector"] > -> - [Publish for Android](index.md) -> - [Publish for iOS](../../ios/deployment/index.md) -> - [Publish for macOS](../../mac-catalyst/deployment/index.md) -> - [Publish for Windows](../../windows/deployment/overview.md) +> - [Publish for Google Play distribution](publish-google-play.md) +> - [Publish for ad-hoc distribution](publish-ad-hoc.md) +> - [Publish using the command line](publish-cli.md) The final step in the development of a .NET Multi-platform App UI (.NET MAUI) app is to publish it. Publishing is the process of creating a package that contains the app and is ready for users to install on their devices. Publishing involve two essential tasks: diff --git a/docs/android/deployment/publish-ad-hoc.md b/docs/android/deployment/publish-ad-hoc.md index 163335c933..09a5631168 100644 --- a/docs/android/deployment/publish-ad-hoc.md +++ b/docs/android/deployment/publish-ad-hoc.md @@ -6,6 +6,11 @@ ms.date: 05/15/2023 # Publish an Android app for ad-hoc distribution +> [!div class="op_single_selector"] +> +> - [Publish for Google Play distribution](publish-google-play.md) +> - [Publish using the command line](publish-cli.md) + When distributing Android apps outside Google Play, and other marketplaces, *ad-hoc* distribution enables you to make the app available for download on a website or server. Android requires that apps created for ad-hoc distribution use the Android Package (APK) format. To distribute a .NET Multi-platform App UI (.NET MAUI) Android app, you'll need to sign it with a key from your keystore. Keystores are binary files that serve as repositories of certificates and private keys. diff --git a/docs/android/deployment/publish-cli.md b/docs/android/deployment/publish-cli.md index dc33f634cc..701a1a1583 100644 --- a/docs/android/deployment/publish-cli.md +++ b/docs/android/deployment/publish-cli.md @@ -6,6 +6,11 @@ ms.date: 05/16/2023 # Publish an Android app using the command line +> [!div class="op_single_selector"] +> +> - [Publish for Google Play distribution](publish-google-play.md) +> - [Publish for ad-hoc distribution](publish-ad-hoc.md) + To distribute a .NET Multi-platform App UI (.NET MAUI) Android app, you'll need to sign it with a key from your keystore. A *keystore* is a database of security certificates that's created by using `keytool` from the Java Development Kit (JDK). A keystore is required when publishing a .NET MAUI Android app, as Android won't run apps that haven't been signed. ## Create a keystore file @@ -59,7 +64,7 @@ To build your app from the command line, and sign it using your keystore, open a | Parameter | Value | |------------------------------|-------------------------------------------------------------------------------------------------| -| `-f` or `--framework` | The target framework, which is `net7.0-android`. | +| `-f` or `--framework` | The target framework, which is `net8.0-android`. | | `-c` or `--configuration` | The build configuration, which is `Release`. | > [!WARNING] @@ -91,19 +96,21 @@ For a full list of build properties, see [Build properties](/xamarin/android/dep Run the `dotnet publish` command with the following parameters to build and sign your app: ```console -dotnet publish -f net7.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore={filename}.keystore -p:AndroidSigningKeyAlias={keyname} -p:AndroidSigningKeyPass={password} -p:AndroidSigningStorePass={password} +dotnet publish -f net8.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore={filename}.keystore -p:AndroidSigningKeyAlias={keyname} -p:AndroidSigningKeyPass={password} -p:AndroidSigningStorePass={password} ``` +[!INCLUDE [dotnet publish in .NET 8](~/includes/dotnet-publish-net8.md)] + For example, use the following command to build and sign your app using the previously created keystore: ```console -dotnet publish -f net7.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=myapp.keystore -p:AndroidSigningKeyAlias=myapp -p:AndroidSigningKeyPass=mypassword -p:AndroidSigningStorePass=mypassword +dotnet publish -f net8.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=myapp.keystore -p:AndroidSigningKeyAlias=myapp -p:AndroidSigningKeyPass=mypassword -p:AndroidSigningStorePass=mypassword ``` Both the `AndroidSigningKeyPass` and `AndroidSigningStorePass` properties support `env:` and `file:` prefixes that can be used to specify an environment variable or file that contains the password. Specifying the password in this way prevents it from appearing in build logs. For example, to use an environment variable named `AndroidSigningPassword`: ```console -dotnet publish -f net7.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=myapp.keystore -p:AndroidSigningKeyAlias=myapp -p:AndroidSigningKeyPass=env:AndroidSigningPassword -p:AndroidSigningStorePass=env:AndroidSigningPassword +dotnet publish -f net8.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=myapp.keystore -p:AndroidSigningKeyAlias=myapp -p:AndroidSigningKeyPass=env:AndroidSigningPassword -p:AndroidSigningStorePass=env:AndroidSigningPassword ``` > [!IMPORTANT] @@ -112,10 +119,10 @@ dotnet publish -f net7.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSi To use a file located at *C:\Users\user1\AndroidSigningPassword.txt*: ```console -dotnet publish -f net7.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=myapp.keystore -p:AndroidSigningKeyAlias=myapp -p:AndroidSigningKeyPass=file:C:\Users\user1\AndroidSigningPassword.txt -p:AndroidSigningStorePass=file:C:\Users\user1\AndroidSigningPassword.txt +dotnet publish -f net8.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=myapp.keystore -p:AndroidSigningKeyAlias=myapp -p:AndroidSigningKeyPass=file:C:\Users\user1\AndroidSigningPassword.txt -p:AndroidSigningStorePass=file:C:\Users\user1\AndroidSigningPassword.txt ``` -Publishing builds and signs the app, and then copies the AAB and APK files to the *bin\\Release\\net7.0-android\\publish* folder. There are two AAB files - one unsigned and another signed. The signed variant has **-signed** in the file name. +Publishing builds and signs the app, and then copies the AAB and APK files to the *bin\\Release\\net8.0-android\\publish* folder. There are two AAB files - one unsigned and another signed. The signed variant has **-signed** in the file name. For more information about the `dotnet publish` command, see [dotnet publish](/dotnet/core/tools/dotnet-publish). diff --git a/docs/android/deployment/publish-google-play.md b/docs/android/deployment/publish-google-play.md index cb9a91bd3b..319f7b0067 100644 --- a/docs/android/deployment/publish-google-play.md +++ b/docs/android/deployment/publish-google-play.md @@ -6,6 +6,11 @@ ms.date: 05/15/2023 # Publish an Android app for Google Play distribution +> [!div class="op_single_selector"] +> +> - [Publish for ad-hoc distribution](publish-ad-hoc.md) +> - [Publish using the command line](publish-cli.md) + The most common approach to distributing Android apps to users is through the Google Play. The first time an app is submitted to Google Play it must be submitted through the Google Play Console. Subsequent versions of the app can be submitted through Visual Studio. In both cases, a Google Play Developer account is required. Apps submitted to Google Play require approval from Google. To distribute a .NET Multi-platform App UI (.NET MAUI) Android app, you'll need to sign it with a key from your keystore, prior to upload to Google Play. Keystores are binary files that serve as repositories of certificates and private keys. diff --git a/docs/android/linking.md b/docs/android/linking.md index b86bef10fb..2f2becd554 100644 --- a/docs/android/linking.md +++ b/docs/android/linking.md @@ -30,6 +30,8 @@ Linker behavior can be configured for each build configuration of your app. By d # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + 1. In the **Solution Window**, right-click on your .NET MAUI app project and select **Properties**. 1. In the **Project Properties** window, select the **Build > Android > Linker** tab. 1. In the **Project Properties** window, ensure the **Configuration** drop-down is set to **Release** and set the **Linker Behavior** drop-down to your desired linker behavior: diff --git a/docs/android/manifest.md b/docs/android/manifest.md index 21fbc2d696..0ea443b53e 100644 --- a/docs/android/manifest.md +++ b/docs/android/manifest.md @@ -8,7 +8,7 @@ ms.date: 03/07/2023 Every .NET Multi-platform App UI (.NET MAUI) app on Android has an *AndroidManifest.xml* file, located in the *Platforms\\Android* folder, that describes essential information about your app to build tools, the Android operating system, and Google Play. -The manifest file for your .NET MAUI Android app is generated as part of the .NET MAUI build process on Android. This build process takes the XML in the *Platforms\\Android\\AndroidManifest.xml* file, and merges it with any XML that's generated from specific attributes on your classes. The resulting manifest file can be found in the *obj* folder. For example, it can be found at *obj\\Debug\\net7.0-android\\AndroidManifest.xml* for debug builds on .NET 7. +The manifest file for your .NET MAUI Android app is generated as part of the .NET MAUI build process on Android. This build process takes the XML in the *Platforms\\Android\\AndroidManifest.xml* file, and merges it with any XML that's generated from specific attributes on your classes. The resulting manifest file can be found in the *obj* folder. For example, it can be found at *obj\\Debug\\net8.0-android\\AndroidManifest.xml* for debug builds on .NET 8. +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +- , of type `bool`, indicates whether the event should be canceled. +- , of type , indicates the data package that accompanies the drag source. This is a read-only property. +- `PlatformArgs`, of type `PlatformDragStartingEventArgs?`, represents the platform-specific arguments associated with the event. + + + +# [Android](#tab/android) + +On Android, the `PlatformDragStartingEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `MotionEvent`, of type , represents the event containing information for drag and drop status. + +In addition, on Android the `PlatformDragStartingEventArgs` class defines the following methods: + +- `SetDragShadowBuilder`, which sets the to use when dragging begins. +- `SetClipData`, which sets the the to use when dragging begins. +- `SetLocalData`, which sets the local data to use when dragging begins. +- `SetDragFlags`, which sets the to use when dragging begins. + +For example, use the `SetClipData` method to associate with the dragged item: + +```csharp +void OnDragStarting(object sender, DragStartingEventArgs e) +{ +#if ANDROID + string content = "insert your content here"; + e.PlatformArgs.SetClipData(Android.Content.ClipData.NewPlainText("Drag data", content)); +#endif +} +``` + +# [iOS/Mac Catalyst](#tab/macios) + +On iOS and Mac Catalyst, the `PlatformDragStartingEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `GestureRecognizer`, of type , indicates the native event or handler attached to the view. + +In addition, on iOS and Mac Catalyst the `PlatformDragStartingEventArgs` class defines the following methods: + +- `SetItemProvider`, which sets the to use when dragging begins. +- `SetPreviewProvider`, which sets the to use when dragging begins. +- `SetDragItems`, which sets the array of to use when dragging begins. +- `SetPrefersFullSizePreview`, which sets the func that requests that drag previews are full-sized when dragging begins. + +For example, use the `SetPreviewProvider` method to set the object to use as a preview of the item being dragged: + +```csharp +void OnDragStarting(object sender, DragStartingEventArgs e) +{ +#if IOS || MACCATALYST + Func action = () => + { + var image = UIKit.UIImage.FromFile("dotnet_bot.png"); + UIKit.UIImageView imageView = new UIKit.UIImageView(image); + imageView.ContentMode = UIKit.UIViewContentMode.Center; + imageView.Frame = new CoreGraphics.CGRect(0, 0, 250, 250); + return new UIKit.UIDragPreview(imageView); + }; + + e.PlatformArgs.SetPreviewProvider(action); +#endif +} +``` + +In this example, the preview of the dragged item is replaced with an image. + +To set the drag preview to full size, use the `SetPrefersFullSizePreview` method: + +```csharp +void OnDragStarting(object sender, DragStartingEventArgs e) +{ +#if IOS || MACCATALYST + e.PlatformArgs.SetPrefersFullSizePreviews((interaction, session) => { return true; }); +#endif +} +``` + +# [Windows](#tab/windows) + +On Windows, the `PlatformDragStartingEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `DragStartingEventArgs`, of type , provides event data for the native event. +- `Handled`, of type `bool`, determines if the event arguments have changed. This property should be set to `true` when changing the `DragStartingEventArgs` so that the changes aren't overridden. + +--- + + + +The object that accompanies the event defines a `PlatformArgs` property, of type `PlatformDropCompletedEventArgs?`, which represents the platform-specific arguments associated with the event. + + + +# [Android](#tab/android) + +On Android, the `PlatformDropCompletedEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `DragEvent`, of type , represents the event that's sent at various times during a drag and drop operation. + +# [iOS/Mac Catalyst](#tab/macios) + +On iOS and Mac Catalyst, the `PlatformDropCompletedEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `DragInteraction`, of type , indicates the interaction used for dragging items. This property is used when `PlatformDropCompletedEventArgs` is called from `SessionWillEnd`. +- `DragSession`, of type , retrieves the associated information from the drag session. This property is used when `PlatformDropCompletedEventArgs` is called from `SessionWillEnd`. +- `DropOperation`, of type , represents the response to a drop. This property is used when `PlatformDropCompletedEventArgs` is called from `SessionWillEnd`. +- `DropInteraction`, of type , indicates the interaction used for dropping items. This property is used when `PlatformDropCompletedEventArgs` is called from `PerformDrop`. +- `DropSession`, of type , retrieves the associated information from the drop session. This property is used when `PlatformDropCompletedEventArgs` is called from `PerformDrop`. + +# [Windows](#tab/windows) + +On Windows, the `PlatformDropCompletedEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `DropCompletedEventArgs`, of type , provides event data for the native event. + +--- + + + +::: moniker-end The following XAML example shows a attached to an : @@ -171,15 +296,122 @@ The class also defines class, which accompanies the and events, defines the following properties: +::: moniker range="=net-maui-7.0" + +- , of type `DataPackage`, which contains the data associated with the drag source. This property is read-only. +- , of type `DataPackageOperation`, which specifies which operations are allowed by the drop target. + +::: moniker-end + +::: moniker range=">=net-maui-8.0" + - , of type `DataPackage`, which contains the data associated with the drag source. This property is read-only. - , of type `DataPackageOperation`, which specifies which operations are allowed by the drop target. +- `PlatformArgs`, of type `PlatformDragEventArgs?`, represents the platform-specific arguments associated with the event. + + + +# [Android](#tab/android) + +On Android, the `PlatformDragEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `DragEvent`, of type , represents the event that's sent at various times during a drag and drop operation. + +# [iOS/Mac Catalyst](#tab/macios) + +On iOS and Mac Catalyst, the `PlatformDragEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `DropInteraction`, of type , indicates the interaction used for dropping items. +- `DropSession`, of type , retrieves the associated information from the drop session. + +In addition, on iOS and Mac Catalyst the `PlatformDragEventArgs` class defines the `SetDropProposal` method. This method sets the to use when dragging an item over a view: + +```csharp +void OnDragOver(object sender, DragEventArgs e) +{ +#if IOS || MACCATALYST + e.PlatformArgs.SetDropProposal(new UIKit.UIDropProposal(UIKit.UIDropOperation.Move)); +#endif +} +``` + +In this example, the specifies that the data represented by the drag item should be moved rather than copied. + +# [Windows](#tab/windows) + +On Windows, the `PlatformDragEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `DragEventArgs`, of type , provides event data for the native event. +- `Handled`, of type `bool`, determines if the event arguments have changed. This property should be set to `true` when changing the `DragEventArgs` so that the changes aren't overridden. + +For example, the `DragEventArgs` property can be used to access native properties: + +```csharp +void OnDragOver(object sender, DragEventArgs e) +{ +#if WINDOWS + var dragUI = e.PlatformArgs.DragEventArgs.DragUIOverride; + dragUI.IsCaptionVisible = false; + dragUI.IsGlyphVisible = false; +#endif +} +``` + +In this example, the drag glyph is disabled and caption text that overlays the drag visual is also disabled. + +--- + + + +::: moniker-end For information about the `DataPackageOperation` enumeration, see [Handle the DragOver event](#handle-the-dragover-event). The class that accompanies the `Drop` event defines the following properties: +::: moniker range="=net-maui-7.0" + +- , of type `DataPackageView`, which is a read-only version of the data package. +- , of type `bool`, indicates whether the event handler has handled the event or whether .NET MAUI should continue its own processing. + +::: moniker-end + +::: moniker range=">=net-maui-8.0" + - , of type `DataPackageView`, which is a read-only version of the data package. - , of type `bool`, indicates whether the event handler has handled the event or whether .NET MAUI should continue its own processing. +- `PlatformArgs`, of type `PlatformDropEventArgs?`, represents the platform-specific arguments associated with the event. + + + +# [Android](#tab/android) + +On Android, the `PlatformDropEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `DragEvent`, of type , represents the event that's sent at various times during a drag and drop operation. + +# [iOS/Mac Catalyst](#tab/macios) + +On iOS and Mac Catalyst, the `PlatformDropEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `DropInteraction`, of type , indicates the interaction used for dropping items. +- `DropSession`, of type , retrieves the associated information from the drop session. + +# [Windows](#tab/windows) + +On Windows, the `PlatformDropEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `DragEventArgs`, of type , provides event data for the native event. --> + +--- + +::: moniker-end The following XAML example shows a attached to an : @@ -291,3 +523,24 @@ void OnDrop(object sender, DropEventArgs e) ``` In this example, the `Square` object is retrieved from the property bag of the data package, by specifying the "Square" dictionary key. An action based on the retrieved value can then be taken. + +::: moniker range=">=net-maui-8.0" + +## Get the gesture position + +The position at which a drag or drop gesture occurred can be obtained by calling the `GetPosition` method on a , , or object. The `GetPosition` method accepts an `Element?` argument, and returns a position as a `Point?` object: + +```csharp +void OnDragStarting(object sender, DragStartingEventArgs e) +{ + // Position relative to screen + Point? screenPosition = e.GetPosition(null); + + // Position relative to specified element + Point? relativeToImagePosition = e.GetPosition(image); +} +``` + +The `Element?` argument defines the element the position should be obtained relative to. Supplying a `null` value as this argument means that the `GetPosition` method returns a `Point?` object that defines the position of the drag or drop gesture relative to the screen. + +::: moniker-end diff --git a/docs/fundamentals/gestures/pointer.md b/docs/fundamentals/gestures/pointer.md index 56e85f265e..a0ed13daff 100644 --- a/docs/fundamentals/gestures/pointer.md +++ b/docs/fundamentals/gestures/pointer.md @@ -1,13 +1,15 @@ --- title: "Recognize a pointer gesture" description: "Learn how to use the PointerGestureRecognizer class, to detect when the pointer enters, exits, and moves within a view on iPadOS, Mac Catalyst, and Windows." -ms.date: 10/24/2022 +ms.date: 10/16/2023 --- # Recognize a pointer gesture A .NET Multi-platform App UI (.NET MAUI) pointer gesture recognizer detects when the pointer enters, exits, and moves within a view and is implemented with the class. This class defines the following properties: +::: moniker range="=net-maui-7.0" + - , of type `ICommand`, which is the command to invoke when the pointer enters the bounding area of the view. - , of type `object`, which is the parameter that's passed to . - , of type `ICommand`, which is the command to invoke when the pointer that's in the view's bounding area leaves that bounding area. @@ -15,18 +17,80 @@ A .NET Multi-platform App UI (.NET MAUI) pointer gesture recognizer detects when - , of type `ICommand`, which is the command to invoke when the pointer moves while remaining within the bounding area of the view. - , of type `object`, which is the parameter that's passed to . +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +- , of type `ICommand`, which is the command to invoke when the pointer enters the bounding area of the view. +- , of type `object`, which is the parameter that's passed to . +- , of type `ICommand`, which is the command to invoke when the pointer that's in the view's bounding area leaves that bounding area. +- , of type `object`, which is the parameter that's passed to . +- , of type `ICommand`, which is the command to invoke when the pointer moves while remaining within the bounding area of the view. +- , of type `object`, which is the parameter that's passed to . +- `PointerPressedCommand`, of type `ICommand`, which is the command to invoke when the pointer initiates a press within the view. +- `PointerPressedCommandParameter`, of type `object`, which is the parameter that's passed to the `PointerPressedCommand`. +- `PointerReleasedCommand`, of type `ICommand`, which is the command to invoke when the pointer that has previously initiated a press is released, while within the view. +- `PointerReleasedCommandParameter`, of type `object`, which is the parameter that's passed to the `PointerReleasedCommand`. + +::: moniker-end + These properties are backed by objects, which means that they can be targets of data bindings, and styled. The class also defines the following events: +::: moniker range="=net-maui-7.0" + +- , that's raised when the pointer enters the bounding area of the view. +- , that's raised when the pointer that's in the view's bounding area leaves that bounding area. +- , that's raised when the pointer moves while remaining within the bounding area of the view. + +A object accompanies the events, and defines a `GetPosition` method that returns a `Point?` object that represents the position of the pointer when the gesture was detected. For more information about the `GetPosition` method, see [Get the gesture position](#get-the-gesture-position). + +::: moniker-end + +::: moniker range=">=net-maui-8.0" + - , that's raised when the pointer enters the bounding area of the view. - , that's raised when the pointer that's in the view's bounding area leaves that bounding area. - , that's raised when the pointer moves while remaining within the bounding area of the view. +- `PointerPressed`, that's raised when the pointer initiates a press within the view. +- `PointerReleased`, that's raised when the pointer that has previously initiated a press is released, while within the view. + +A object accompanies the events, and defines a `PlatformArgs` property of type `PlatformPointerEventArgs` that provides access to platform-specific arguments for the event. + + + +# [Android](#tab/android) + +On Android, the `PlatformPointerEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `MotionEvent`, of type , indicates the native event or handler attached to the view. + +# [iOS/Mac Catalyst](#tab/macios) + +On iOS and Mac Catalyst, the `PlatformPointerEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `GestureRecognizer`, of type , indicates the native event or handler attached to the view. + +# [Windows](#tab/windows) + +On Windows, the `PlatformPointerEventArgs` class defines the following properties: + +- `Sender`, of type , represents the native view attached to the event. +- `PointerRoutedEventArgs`, of type , indicates the native event or handler attached to the view. + +--- + + + +In addition, the object defines a `GetPosition` method that returns a `Point?` object that represents the position of the pointer when the gesture was detected. For more information about the `GetPosition` method, see [Get the gesture position](#get-the-gesture-position). -A object accompanies all three events, and defines a `GetPosition` method that returns a `Point?` object that represents the position of the pointer when the gesture was detected. For more information about the `GetPosition` method, see [Get the gesture position](#get-the-gesture-position). +::: moniker-end > [!IMPORTANT] -> Pointer gesture recognition is only supported on iPadOS, Mac Catalyst, and Windows. +> Pointer gesture recognition is supported on Android, iPadOS, Mac Catalyst, and Windows. .NET MAUI also defines a `PointerOver` visual state. This state can change the visual appearance of a view when it has a mouse cursor hovering over it, but isn't pressed. For more information, see [Visual states](~/user-interface/visual-states.md). diff --git a/docs/fundamentals/gestures/tap.md b/docs/fundamentals/gestures/tap.md index 531ef6c2a0..21c57189b9 100644 --- a/docs/fundamentals/gestures/tap.md +++ b/docs/fundamentals/gestures/tap.md @@ -8,14 +8,14 @@ ms.date: 10/03/2022 A .NET Multi-platform App UI (.NET MAUI) tap gesture recognizer is used for tap detection and is implemented with the class. This class defines the following properties: -- , of type , which defines whether the primary or secondary mouse button, or both, triggers the gesture on Mac Catalyst and Windows. For more information, see [Define the button masks](#define-the-button-mask). +- , of type , which defines whether the primary or secondary mouse button, or both, triggers the gesture on Android, Mac Catalyst, and Windows. For more information, see [Define the button masks](#define-the-button-mask). - , of type `ICommand`, which is executed when a tap is recognized. - , of type `object`, which is the parameter that's passed to the `Command`. - , of type `int`, which represents the number of taps required to recognize a tap gesture. The default value of this property is 1. These properties are backed by objects, which means that they can be targets of data bindings, and styled. -The class also defines a event that's raised when a tap is recognized. The object that accompanies the event defines a property of type `object` that indicates the value passed by the `CommandParameter` property, if defined. The object also defines a property, and a `GetPosition` method. The property is of type , and can be used to determine whether the primary or secondary mouse button triggered the gesture recognizer on Mac Catalyst and Windows. The `GetPosition` method returns a `Point?` object that represents the position at which the tap gesture was detected. For more information about button masks, see [Define the button mask](#define-the-button-mask). For more information about the `GetPosition` method, see [Get the gesture position](#get-the-gesture-position). +The class also defines a event that's raised when a tap is recognized. The object that accompanies the event defines a property of type `object` that indicates the value passed by the `CommandParameter` property, if defined. The object also defines a property, and a `GetPosition` method. The property is of type , and can be used to determine whether the primary or secondary mouse button triggered the gesture recognizer on Android, Mac Catalyst, and Windows. The `GetPosition` method returns a `Point?` object that represents the position at which the tap gesture was detected. For more information about button masks, see [Define the button mask](#define-the-button-mask). For more information about the `GetPosition` method, see [Get the gesture position](#get-the-gesture-position). > [!WARNING] > A can't recognize more than a double tap on Windows. @@ -58,7 +58,7 @@ By default the will respond to single taps. ## Define the button mask -A object has a property, of type , that defines whether the primary or secondary mouse button, or both, triggers the gesture on Mac Catalyst and Windows. The enumeration defines the following members: +A object has a property, of type , that defines whether the primary or secondary mouse button, or both, triggers the gesture on Android, Mac Catalyst, and Windows. The enumeration defines the following members: - represents the primary mouse button, which is typically the left mouse button. - represents the secondary mouse button, which is typically the right mouse button. diff --git a/docs/fundamentals/shell/navigation.md b/docs/fundamentals/shell/navigation.md index 0593d46e59..ea85fc4f2f 100644 --- a/docs/fundamentals/shell/navigation.md +++ b/docs/fundamentals/shell/navigation.md @@ -1,7 +1,7 @@ --- title: ".NET MAUI Shell navigation" description: "Learn how .NET MAUI Shell apps can utilize a URI-based navigation experience that permits navigation to any page in the app, without having to follow a set navigation hierarchy." -ms.date: 04/07/2022 +ms.date: 10/23/2023 --- # .NET MAUI Shell navigation @@ -352,7 +352,9 @@ async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEvent This example retrieves the currently selected elephant in the , and navigates to the `elephantdetails` route, passing `elephantName` as a query parameter. -Object-based navigation data can be passed with a `GoToAsync` overload that specifies an `IDictionary` argument: +### Pass multiple use object-based navigation data + +Multiple use object-based navigation data can be passed with a `GoToAsync` overload that specifies an `IDictionary` argument: ```csharp async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e) @@ -368,6 +370,38 @@ async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEvent This example retrieves the currently selected bear in the , as an `Animal`. The `Animal` object is added to a `Dictionary` with the key `Bear`. Then, navigation to the `beardetails` route is performed, with the `Dictionary` being passed as a navigation parameter. +Any data that's passed as an `IDictionary` argument is retained in memory for the lifetime of the page, and isn't released until the page is removed from the navigation stack. This can be problematic, as shown in the following scenario: + +1. `Page1` navigates to `Page2` using the `GoToAsync` method, passing in an object called `MyData`. `Page2` then receives `MyData` as a query parameter. +1. `Page2` navigates to `Page3` using the `GoToAsync` method, without passing any data. +1. `Page3` navigates backwards with the `GoToAsync` method. `Page2` then receives `MyData` again as a query parameter. + +While this is desirable in many scenarios, if it isn't desired you should clear the `IDictionary` argument with the `Clear` method after it's first been received by a page. + +::: moniker range=">=net-maui-8.0" + +### Pass single use object-based navigation data + +Single use object-based navigation data can be passed with a `GoToAsync` overload that specifies a `ShellNavigationQueryParameters` argument. A `ShellNavigationQueryParameters` object is intended for single use navigation data that's cleared after navigation has occurred. The following example shows navigating while passing single use data: + +```csharp +async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e) +{ + Animal animal = e.CurrentSelection.FirstOrDefault() as Animal; + var navigationParameter = new ShellNavigationQueryParameters + { + { "Bear", animal } + }; + await Shell.Current.GoToAsync($"beardetails", navigationParameter); +} +``` + +This example retrieves the currently selected bear in the , as an `Animal` that's added to the `ShellNavigationQueryParameters` object. Then, navigation to the `beardetails` route is performed, with the `ShellNavigationQueryParameters` object being passed as a navigation parameter. After navigation has occurred the data in the `ShellNavigationQueryParameters` object is cleared. + +::: moniker-end + +## Receive navigation data + There are two approaches to receiving navigation data: 1. The class that represents the page being navigated to, or the class for the page's `BindingContext`, can be decorated with a `QueryPropertyAttribute` for each query parameter. For more information, see [Process navigation data using query property attributes](#process-navigation-data-using-query-property-attributes). @@ -375,8 +409,18 @@ There are two approaches to receiving navigation data: ### Process navigation data using query property attributes +::: moniker range="=net-maui-7.0" + Navigation data can be received by decorating the receiving class with a `QueryPropertyAttribute` for each string-based query parameter and object-based navigation parameter: +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +Navigation data can be received by decorating the receiving class with a `QueryPropertyAttribute` for each string-based query parameter, object-based navigation parameter, or `ShellNavigationQueryParameters` object: + +::: moniker-end + ```csharp [QueryProperty(nameof(Bear), "Bear")] public partial class BearDetailPage : ContentPage diff --git a/docs/fundamentals/shell/tabs.md b/docs/fundamentals/shell/tabs.md index 984e7b1238..9deaba6490 100644 --- a/docs/fundamentals/shell/tabs.md +++ b/docs/fundamentals/shell/tabs.md @@ -174,6 +174,24 @@ The class defines the following attached pr All of these properties are backed by objects, which means that the properties can be targets of data bindings, and styled. +::: moniker range=">=net-maui-8.0" + +The three properties that most influence the color of a tab are `TabBarForegroundColor`, `TabBarTitleColor`, and `TabBarUnselectedColor`: + +- If only the `TabBarTitleColor` property is set then its value will be used to color the title and icon of the selected tab. If `TabBarTitleColor` isn't set then the title color will match the value of the `TabBarForegroundColor` property. +- If the `TabBarForegroundColor` property is set and the `TabBarUnselectedColor` property isn't set then the value of the `TabBarForegroundColor` property will be used to color the title and icon of the selected tab. +- If only the `TabBarUnselectedColor` property is set then its value will be used to color the title and icon of the unselected tab. + +For example: + +- When the `TabBarTitleColor` property is set to `Green` the title and icon for the selected tab is green, and unselected tabs match system colors. +- When the `TabBarForegroundColor` property is set to `Blue` the title and icon for the selected tab is blue, and unselected tabs match system colors. +- When the `TabBarTitleColor` property is set to `Green` and the `TabBarForegroundColor` property is set to `Blue` the title is green and the icon is blue for the selected tab, and unselected tabs match system colors. +- When the `TabBarTitleColor` property is set to `Green` and the `Shell.ForegroundColor` property is set to `Blue` the title is green and the icon is blue for the selected tab, and unselected tabs match system colors. This occurs because the `Shell.ForegroundColor` property value propagates to the `TabBarForegroundColor` property. +- When the `TabBarTitleColor` property is set to `Green`, the `TabBarForegroundColor` property is set to `Blue`, and the `TabBarUnselectedColor` property is set to `Red`, the title is green and the icon is blue for the selected tab, and unselected tab titles and icons are red. + +::: moniker-end + The following example shows a XAML style that sets different tab bar color properties: ```xaml diff --git a/docs/fundamentals/single-project.md b/docs/fundamentals/single-project.md index 6d70a87ac7..887b58b734 100644 --- a/docs/fundamentals/single-project.md +++ b/docs/fundamentals/single-project.md @@ -140,7 +140,7 @@ Raw assets can then be consumed by controls, as required: ``` -At build time, raw assets are copied to your app package. +At build time, raw assets are copied to your app package. For information about disabling asset packaging, see [Disable asset file packaging](~/troubleshooting.md#disable-asset-file-packaging). ### CSS files diff --git a/docs/fundamentals/windows.md b/docs/fundamentals/windows.md index a61281bc2f..c07ef98473 100644 --- a/docs/fundamentals/windows.md +++ b/docs/fundamentals/windows.md @@ -1,14 +1,14 @@ --- title: ".NET MAUI windows" description: "Learn how to use the .NET MAUI Window class to create, configure, show, and manage multi-window apps." -ms.date: 10/10/2022 +ms.date: 10/24/2023 --- # .NET MAUI windows -The .NET Multi-platform App UI (.NET MAUI) `Window` class provides the ability to create, configure, show, and manage multiple windows. +The .NET Multi-platform App UI (.NET MAUI) class provides the ability to create, configure, show, and manage multiple windows. -`Window` defines the following properties: + defines the following properties: - `FlowDirection`, of type `FlowDirection`, defines the direction in which the UI element of the window are laid out. - `Height`, of type `double`, specifies the height of the window on Windows. @@ -17,7 +17,7 @@ The .NET Multi-platform App UI (.NET MAUI) `Window` class provides the ability t - `MinimumHeight`, of type `double`, represents the minimum height of the window on desktop platforms. Valid values are between 0 and `double.PositiveInfinity`. - `MinimumWidth`, of type `double`, represents the minimum width of the window on desktop platforms. Valid values are between 0 and `double.PositiveInfinity`. - `Overlays`, of type `IReadOnlyCollection`, represents the collection of window overlays. -- , of type , indicates the page being displayed by the window. This property is the content property of the `Window` class, and therefore does not need to be explicitly set. +- , of type , indicates the page being displayed by the window. This property is the content property of the class, and therefore does not need to be explicitly set. - `Title`, of type `string`, represents the title of the window. - `Width`, of type `double`, specifies the width of the window on Windows. - `X`, of type `double`, specifies the X coordinate of the window on Windows. @@ -27,7 +27,7 @@ These properties, with the exception of the `Overlays` property, are backed by < -The `Window` class defines the following events: +The class defines the following events: - `Created`, which is raised when the window is created. - `Resumed`, which is raised when the window is resumed from a sleeping state. @@ -41,7 +41,7 @@ The `Window` class defines the following events: For more information about the lifecycle events, and their associated overrides, see [App lifecycle](app-lifecycle.md). -The `Window` class also defines the following modal navigation events: +The class also defines the following modal navigation events: - `ModalPopped`, with `ModalPoppedEventArgs`, which is raised when a view has been popped modally. - `ModalPopping`, with `ModalPoppingEventArgs`, which is raised when a view is modally popped. @@ -49,11 +49,11 @@ The `Window` class also defines the following modal navigation events: - `ModalPushing`, with `ModalPushingEventArgs`, which is raised when a view is modally pushed. - `PopCanceled`, which is raised when a modal pop is cancelled. -The class has a `Window` property that exposes the parent `Window` object. This property can be accessed from any page, layout, or view, to manipulate `Window` objects. +The class has a `Window` property that exposes the parent object. This property can be accessed from any page, layout, or view, to manipulate objects. ## Create a Window -By default, .NET MAUI creates a `Window` object when you set the `MainPage` property to a object in your `App` class. However, you can also override the `CreateWindow` method in your `App` class to create a `Window` object: +By default, .NET MAUI creates a object when you set the `MainPage` property to a object in your `App` class. However, you can also override the `CreateWindow` method in your `App` class to create a object: ```csharp namespace MyMauiApp @@ -79,9 +79,9 @@ namespace MyMauiApp } ``` -While the `Window` class has a default constructor and a constructor that accepts a argument, which represents the root page of the app, you can also call the base `CreateWindow` method to return the .NET MAUI created `Window` object. +While the class has a default constructor and a constructor that accepts a argument, which represents the root page of the app, you can also call the base `CreateWindow` method to return the .NET MAUI created object. -In addition, you can also create your own `Window`-derived object: +In addition, you can also create your own -derived object: ```csharp namespace MyMauiApp @@ -101,20 +101,20 @@ namespace MyMauiApp } ``` -The `Window`-derived class can then be consumed by creating a `MyWindow` object in the `CreateWindow` override in your `App` class. +The -derived class can then be consumed by creating a `MyWindow` object in the `CreateWindow` override in your `App` class. -Regardless of how your `Window` object is created, it will be the parent of the root page in your app. +Regardless of how your object is created, it will be the parent of the root page in your app. ## Multi-window support -Multiple windows can be simultaneously opened on Android, iOS on iPad (iPadOS), Mac Catalyst, and Windows. This can be achieved by creating a `Window` object and opening it using the `OpenWindow` method on the `Application` object: +Multiple windows can be simultaneously opened on Android, iOS on iPad (iPadOS), Mac Catalyst, and Windows. This can be achieved by creating a object and opening it using the `OpenWindow` method on the `Application` object: ```csharp Window secondWindow = new Window(new MyPage()); Application.Current.OpenWindow(secondWindow); ``` -The `Application.Current.Windows` collection, of type `IReadOnlyList` maintains references to all `Window` objects that are registered with the `Application` object. +The `Application.Current.Windows` collection, of type `IReadOnlyList` maintains references to all objects that are registered with the `Application` object. Windows can be closed with the `Application.Current.CloseWindow` method: @@ -173,12 +173,12 @@ Then, in the XML editor, open the **Platforms > iOS > Info.plist** file and the ## Position and size a Window -The position and size of a window can be programmatically defined for a .NET MAUI app on Windows by setting the `X`, `Y`, `Width`, and `Height` properties on a `Window` object. +The position and size of a window can be programmatically defined for a .NET MAUI app on Windows by setting the `X`, `Y`, `Width`, and `Height` properties on a object. > [!WARNING] > Mac Catalyst doesn't support resizing or repositioning windows programmatically by setting the `X`, `Y`, `Width`, and `Height` properties. -For example, to set the window position and size on launch you should override the `CreateWindow` method in your `App` class and set the `X`, `Y`, `Width`, and `Height` properties on a `Window` object: +For example, to set the window position and size on launch you should override the `CreateWindow` method in your `App` class and set the `X`, `Y`, `Width`, and `Height` properties on a object: ```csharp public partial class App : Application @@ -231,3 +231,58 @@ Dispatcher.Dispatch(() => Window.MaximumHeight = double.PositiveInfinity; }); ``` + +::: moniker range=">=net-maui-8.0" + +## Decouple window management from the App class + +Window management can be decoupled from the `App` class by creating a class that implements the `IWindowCreator` interface, and adding your window management code in the `CreateWindow` method: + +```csharp +public class WindowCreator : IWindowCreator +{ + public Window CreateWindow(Application app, IActivationState activationState) + { + var window = new Window(new ContentPage + { + Content = new Grid + { + new Label + { + Text = "Hello from IWindowCreator", + HorizontalOptions = LayoutOptions.Center, + VerticalOptions = LayoutOptions.Center + } + } + }); + + return window; + } +} +``` + +Then, in the `MauiProgram` class you should register your window management type as a dependency in the app's service container: + +```csharp +// Use a factory method to avoid reflection +builder.Services.AddSingleton(_ => new WindowCreator()); +``` + +> [!IMPORTANT] +> Ensure that your registration code specifies the `IWindowCreator` interface as well as its concrete type. + +Then, ensure that your `App` class doesn't set the `MainPage` property: + +```csharp +public partial class App : Application +{ + public App() + { + InitializeComponent(); + } +} +``` + +Provided that the `IWindowCreator` interface and its concrete type have been registered with the app's service container, and that the property of the class isn't set, your registered type will be used to create the . + +::: moniker-end diff --git a/docs/get-started/first-app.md b/docs/get-started/first-app.md index 33c240f543..3b0e62ac15 100644 --- a/docs/get-started/first-app.md +++ b/docs/get-started/first-app.md @@ -1,8 +1,9 @@ --- title: "Build your first .NET MAUI app" description: "Learn how to create and run your first .NET MAUI app in Visual Studio 2022 on Windows, or Visual Studio 2022 for Mac." -ms.date: 11/01/2022 +ms.date: 11/10/2023 zone_pivot_groups: devices-deployment +monikerRange: ">=net-maui-8.0" --- # Build your first app @@ -15,7 +16,7 @@ In this tutorial, you'll learn how to create and run your first .NET Multi-platf ## Prerequisites -- Visual Studio 2022 17.3 or greater, with the .NET Multi-platform App UI workload installed. For more information, see [Installation](installation.md?tabs=vswin). +- Visual Studio 2022 17.8 or greater, with the .NET Multi-platform App UI workload installed. For more information, see [Installation](installation.md?tabs=vswin). ## Create an app @@ -116,9 +117,9 @@ In this tutorial, you'll create your first .NET MAUI app in Visual Studio 2022 a :::image type="content" source="media/first-app/vs/android-device-manager.png" alt-text="Android Device Manager window."::: -01. In the Visual Studio toolbar, press the **Pixel 5 - API 30 (Android 11.0 - API 30)** button to build and run the app: +01. In the Visual Studio toolbar, press the **Pixel 5 - API 34 (Android 14.0 - API 33)** button to build and run the app: - :::image type="content" source="media/first-app/vs/pixel5-api30.png" alt-text="Pixel 5 API 30 emulator button."::: + :::image type="content" source="media/first-app/vs/pixel5-api-34.png" alt-text="Pixel 5 API 34 emulator button."::: Visual Studio will start the Android emulator, build the app, and deploy the app to the emulator. @@ -127,7 +128,7 @@ In this tutorial, you'll create your first .NET MAUI app in Visual Studio 2022 a 01. In the running app in the Android emulator, press the **Click me** button several times and observe that the count of the number of button clicks is incremented. - :::image type="content" source="media/first-app/vs/running-app.png" alt-text="App running in the Android emulator." lightbox="media/first-app/vs/running-app-large.png"::: + :::image type="content" source="media/first-app/vs/android-running-app.png" alt-text="App running in the Android emulator."::: ## Troubleshooting @@ -138,7 +139,7 @@ If your app fails to compile, review [Troubleshooting known issues](../troublesh :::zone pivot="devices-windows" -06. In the Visual Studio toolbar, use the **Debug Target** drop-down to select **Framework** and then the **net7.0-windows** entry: +06. In the Visual Studio toolbar, use the **Debug Target** drop-down to select **Framework** and then the **net8.0-windows** entry: :::image type="content" source="media/first-app/vs/windows-debug-target.png" alt-text="Select the Windows Machine debugging target for .NET MAUI."::: @@ -205,9 +206,14 @@ If your app fails to compile, review [Troubleshooting known issues](../troublesh # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + ## Prerequisites -- Visual Studio 2022 for Mac 17.4 or greater, with the .NET, .NET MAUI, Android, and iOS workloads installed. For more information, see [Installation](installation.md?tabs=vsmac). +- Visual Studio 2022 for Mac 17.6 with the .NET, .NET MAUI, Android, and iOS workloads installed. For more information, see [Installation](installation.md?tabs=vsmac). + +> [!IMPORTANT] +> To use Visual Studio for Mac with .NET 8, enable the **Visual Studio > Preferences > Other > Preview Features > Use the .NET 8 SDK if installed (requires restart)** checkbox. ## Create an app @@ -280,7 +286,7 @@ In this tutorial, you'll create your first .NET MAUI app in Visual Studio 2022 f :::image type="content" source="media/first-app/vsmac/android-device-manager.png" alt-text="Close the Android Device Manager window."::: -01. In the Visual Studio 2022 for Mac toolbar, change the debug target to **Pixel 5 - API 31 (API 31)**: +01. In the Visual Studio 2022 for Mac toolbar, change the debug target to **Pixel 5 - API 34 (API 34)**: :::image type="content" source="media/first-app/vsmac/android-pixel5-debug-target.png" alt-text="Set the created Android emulator as the debug target."::: @@ -320,12 +326,20 @@ In this tutorial, you'll create your first .NET MAUI app in Visual Studio 2022 f :::zone pivot="devices-maccatalyst" -06. In the Visual Studio 2022 for Mac toolbar, ensure that the debug target is set to **My Mac**: +06. In the Visual Studio 2022 for Mac toolbar, ensure that the debug target is set to **My Mac (MacCatalyst)**: :::image type="content" source="media/first-app/vsmac/mac-debug-target.png" alt-text="Ensure the debug target is set to My Mac."::: +01. In Visual Studio 2022 for Mac, right-click on the **MyMauiApp** project and select **Edit Project File**. Then, in the project file editor insert the following XML before the first ``: + + ```xml + + maccatalyst-x64;maccatalyst-arm64 + + ``` + 01. In the Visual Studio 2022 for Mac toolbar, press the **Play** button to launch the app on your Mac: :::image type="content" source="media/first-app/vsmac/mac-run.png" alt-text="Launch the app on your Mac."::: diff --git a/docs/get-started/installation.md b/docs/get-started/installation.md index e6e52d3e9f..97b094d29f 100644 --- a/docs/get-started/installation.md +++ b/docs/get-started/installation.md @@ -1,22 +1,23 @@ --- title: "Install Visual Studio 2022 to develop cross-platform apps using .NET MAUI" description: "Learn how to install Visual Studio 2022 and Visual Studio 2022 for Mac, to develop native, cross-platform apps using .NET MAUI." -ms.date: 11/01/2022 +ms.date: 11/13/2023 +monikerRange: ">=net-maui-8.0" --- # Installation -Developing native, cross-platform .NET Multi-platform App UI (.NET MAUI) apps requires Visual Studio 2022 17.3 or greater, or Visual Studio 2022 for Mac 17.4 or greater. +Developing native, cross-platform .NET Multi-platform App UI (.NET MAUI) apps requires Visual Studio 2022 17.8 or greater, or Visual Studio 2022 for Mac 17.6. # [Visual Studio](#tab/vswin) -To start developing native, cross-platform .NET MAUI apps on Windows, install Visual Studio 2022 17.3 or greater by following the [installation](#installation) steps. +To start developing native, cross-platform .NET MAUI apps on Windows, install Visual Studio 2022 17.8 or greater by following the [installation](#installation) steps. ## Prerequisites -- Visual Studio 2022 17.3 or greater. For information about supported operating systems, hardware, supported languages, and additional requirements and guidance, see [Visual Studio 2022 System Requirements](/visualstudio/releases/2022/system-requirements). +- Visual Studio 2022 17.8 or greater. For information about supported operating systems, hardware, supported languages, and additional requirements and guidance, see [Visual Studio 2022 System Requirements](/visualstudio/releases/2022/system-requirements). To build, sign, and deploy .NET MAUI apps for iOS, you'll also need: @@ -46,11 +47,13 @@ Alternatively, to deploy debug builds of your app directly from Windows to your # [Visual Studio for Mac](#tab/vsmac) -To start developing native, cross-platform .NET MAUI apps on macOS, install Visual Studio 2022 for Mac 17.4 or greater by following the [installation](#installation) steps. +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + +To start developing native, cross-platform .NET MAUI apps on macOS, install Visual Studio 2022 for Mac 17.6 by following the [installation](#installation) steps. ## Prerequisites -- Visual Studio 2022 for Mac 17.4 or greater. For information about supported operating systems, hardware, supported languages, and additional requirements and guidance, see [Visual Studio 2022 for Mac System Requirements](/visualstudio/releases/2022/mac-system-requirements). +- Visual Studio 2022 for Mac 17.6. For information about supported operating systems, hardware, supported languages, and additional requirements and guidance, see [Visual Studio 2022 for Mac System Requirements](/visualstudio/releases/2022/mac-system-requirements). To build, sign, and deploy .NET MAUI apps for iOS or macOS, you'll also need: @@ -80,6 +83,9 @@ To build, sign, and deploy .NET MAUI apps for iOS or macOS, you'll also need: +1. Install .NET 8 through the [standalone installer](https://dotnet.microsoft.com/en-us/download/dotnet/8.0). +1. After .NET 8 has finished installing, run `dotnet workload install maui` in a terminal. + If you have network trouble while installing in a corporate environment, review the [installing behind a firewall or proxy](#installation-behind-a-firewall-or-proxy-server) instructions. ## Installation behind a firewall or proxy server @@ -119,12 +125,12 @@ The recommended approach to setup your Windows machine for .NET MAUI development If you don't want to install Visual Studio, you can still get set up for .NET MAUI development by following these steps: -1. Install [.NET 7 or greater](/dotnet/core/install/windows?tabs=net70). +1. Install [.NET 8](/dotnet/core/install/windows). 1. After .NET has finished installing, run `dotnet workload install maui` in a terminal. 1. If you'd like to debug Android in Visual Studio Code, you also have to: 1. Install [Microsoft OpenJDK 11](/java/openjdk/download#openjdk-11). 1. Install the Android SDK. You can acquire the correct versions of the Android SDK and build tools by creating a new .NET MAUI project (`dotnet new maui`) and running the following command in your terminal: - `dotnet build -t:InstallAndroidDependencies -f:net7.0-android -p:AndroidSdkDirectory="" -p:AcceptAndroidSDKLicenses=True` + `dotnet build -t:InstallAndroidDependencies -f:net8.0-android -p:AndroidSdkDirectory="" -p:AcceptAndroidSDKLicenses=True` On Windows, the suggested Android SDK directory value is `%LOCALAPPDATA%/Android/Sdk`. > [!NOTE] @@ -132,19 +138,19 @@ If you don't want to install Visual Studio, you can still get set up for .NET MA ### macOS -1. Install [.NET 7 or greater](/dotnet/core/install/macOS). +1. Install [.NET 8](/dotnet/core/install/macOS). 1. Install the [latest stable Xcode](https://apps.apple.com/us/app/xcode/id497799835?mt=12). 1. After Xcode has finished installing, run `xcode-select --install` in a terminal to acquire the Xcode command line tools. 1. Run `dotnet workload install maui` in a terminal. 1. If you'd like to debug to Android in Visual Studio Code, you also have to: 1. Install [Microsoft OpenJDK 11](/java/openjdk/download#openjdk-11). 1. Install the Android SDK. You can acquire the correct versions of the Android SDK and build tools by creating a new .NET MAUI project (`dotnet new maui`) and running the following command in your terminal: - `dotnet build -t:InstallAndroidDependencies -f:net7.0-android -p:AndroidSdkDirectory="" -p:AcceptAndroidSDKLicenses=True` + `dotnet build -t:InstallAndroidDependencies -f:net8.0-android -p:AndroidSdkDirectory="" -p:AcceptAndroidSDKLicenses=True` On macOS, the suggested Android SDK directory value is `$HOME/Library/Android/sdk`. ### Linux -1. Install [.NET 7 or greater](/dotnet/core/install/linux). +1. Install [.NET 8](/dotnet/core/install/linux). 1. After .NET has installed, run `dotnet workload install maui-android` in a terminal. 1. If you'd like to debug to Android in Visual Studio Code, you also have to: 1. Install [Microsoft OpenJDK 11](/java/openjdk/download#openjdk-11). @@ -171,7 +177,7 @@ No matter which way you install Android, you can develop .NET MAUI apps in Visua #### Using "InstallAndroidDependencies" -* .NET 7 and above has a build target that helps set up your Android environment for you. You can add or remove the following properties to `dotnet build -t:InstallAndroidDependencies -f:net7.0-android` to configure your machine: +* .NET 8 has a build target that helps set up your Android environment for you. You can add or remove the following properties to `dotnet build -t:InstallAndroidDependencies -f:net8.0-android` to configure your machine: * `-p:AndroidSdkDirectory ""` installs or updates Android dependencies to the specified path (Note: You must use an absolute path without a tilde "~"). * `-p:JavaSdkDirectory ""` installs Java to the specified path (Note: You must use an absolute path without a tilde "~"). * `-p:AcceptAndroidSDKLicenses=True` accepts the necessary Android licenses for development. @@ -208,7 +214,7 @@ This is a known issue if you install to `%APPDATA%` on Windows and will be fixed ### Debugging issues * Debugging can fail to start for multiple reasons. If there isn't a clear error in the Output window, first double check that you are using the ".NET MAUI" run configuration in Visual Studio Code. -* You can try a command line build from the terminal to see if the error is with your code or the .NET MAUI extension. For example, you could run `dotnet build -f:net7.0-android` to see if your Android build succeeds outside of Visual Studio Code. If this build succeeds, please [Report an Issue](https://github.com/microsoft/vscode-dotnettools/issues) +* You can try a command line build from the terminal to see if the error is with your code or the .NET MAUI extension. For example, you could run `dotnet build -f:net8.0-android` to see if your Android build succeeds outside of Visual Studio Code. If this build succeeds, please [Report an Issue](https://github.com/microsoft/vscode-dotnettools/issues) ## Known Limitations diff --git a/docs/get-started/media/first-app/vs/additional-information.png b/docs/get-started/media/first-app/vs/additional-information.png index fbafff3c14..48a9e6380b 100644 Binary files a/docs/get-started/media/first-app/vs/additional-information.png and b/docs/get-started/media/first-app/vs/additional-information.png differ diff --git a/docs/get-started/media/first-app/vs/android-debug-target.png b/docs/get-started/media/first-app/vs/android-debug-target.png index c126a8a121..de5b82246e 100644 Binary files a/docs/get-started/media/first-app/vs/android-debug-target.png and b/docs/get-started/media/first-app/vs/android-debug-target.png differ diff --git a/docs/get-started/media/first-app/vs/android-device-manager.png b/docs/get-started/media/first-app/vs/android-device-manager.png index 2e84970f24..9f8fc082e2 100644 Binary files a/docs/get-started/media/first-app/vs/android-device-manager.png and b/docs/get-started/media/first-app/vs/android-device-manager.png differ diff --git a/docs/get-started/media/first-app/vs/android-running-app.png b/docs/get-started/media/first-app/vs/android-running-app.png new file mode 100644 index 0000000000..0e0a01f226 Binary files /dev/null and b/docs/get-started/media/first-app/vs/android-running-app.png differ diff --git a/docs/get-started/media/first-app/vs/ios-chosen-debug-target.png b/docs/get-started/media/first-app/vs/ios-chosen-debug-target.png index 8c5a8be724..446136aa0a 100644 Binary files a/docs/get-started/media/first-app/vs/ios-chosen-debug-target.png and b/docs/get-started/media/first-app/vs/ios-chosen-debug-target.png differ diff --git a/docs/get-started/media/first-app/vs/ios-debug-target.png b/docs/get-started/media/first-app/vs/ios-debug-target.png index 848848d603..dcf28a24a0 100644 Binary files a/docs/get-started/media/first-app/vs/ios-debug-target.png and b/docs/get-started/media/first-app/vs/ios-debug-target.png differ diff --git a/docs/get-started/media/first-app/vs/ios-running-app.png b/docs/get-started/media/first-app/vs/ios-running-app.png index f25ecf84b8..0ce8f42da1 100644 Binary files a/docs/get-started/media/first-app/vs/ios-running-app.png and b/docs/get-started/media/first-app/vs/ios-running-app.png differ diff --git a/docs/get-started/media/first-app/vs/new-android-device.png b/docs/get-started/media/first-app/vs/new-android-device.png index 867d4a3546..9f662e7101 100644 Binary files a/docs/get-started/media/first-app/vs/new-android-device.png and b/docs/get-started/media/first-app/vs/new-android-device.png differ diff --git a/docs/get-started/media/first-app/vs/pixel5-api-34.png b/docs/get-started/media/first-app/vs/pixel5-api-34.png new file mode 100644 index 0000000000..19c7af5bcf Binary files /dev/null and b/docs/get-started/media/first-app/vs/pixel5-api-34.png differ diff --git a/docs/get-started/media/first-app/vs/pixel5-api30.png b/docs/get-started/media/first-app/vs/pixel5-api30.png deleted file mode 100644 index 94f6616d17..0000000000 Binary files a/docs/get-started/media/first-app/vs/pixel5-api30.png and /dev/null differ diff --git a/docs/get-started/media/first-app/vs/restored-dependencies.png b/docs/get-started/media/first-app/vs/restored-dependencies.png index d894c2a5ed..9d0e0e3759 100644 Binary files a/docs/get-started/media/first-app/vs/restored-dependencies.png and b/docs/get-started/media/first-app/vs/restored-dependencies.png differ diff --git a/docs/get-started/media/first-app/vs/running-app-large.png b/docs/get-started/media/first-app/vs/running-app-large.png deleted file mode 100644 index b179d0e8b7..0000000000 Binary files a/docs/get-started/media/first-app/vs/running-app-large.png and /dev/null differ diff --git a/docs/get-started/media/first-app/vs/running-app.png b/docs/get-started/media/first-app/vs/running-app.png deleted file mode 100644 index 5a7af6ec1f..0000000000 Binary files a/docs/get-started/media/first-app/vs/running-app.png and /dev/null differ diff --git a/docs/get-started/media/first-app/vs/windows-debug-target.png b/docs/get-started/media/first-app/vs/windows-debug-target.png index 02643c208f..3563a606b1 100644 Binary files a/docs/get-started/media/first-app/vs/windows-debug-target.png and b/docs/get-started/media/first-app/vs/windows-debug-target.png differ diff --git a/docs/get-started/media/first-app/vs/windows-run-button.png b/docs/get-started/media/first-app/vs/windows-run-button.png index fd45885ace..fb643c427e 100644 Binary files a/docs/get-started/media/first-app/vs/windows-run-button.png and b/docs/get-started/media/first-app/vs/windows-run-button.png differ diff --git a/docs/get-started/media/first-app/vs/windows-running-app.png b/docs/get-started/media/first-app/vs/windows-running-app.png index 7cb368e9f6..10a9d6762e 100644 Binary files a/docs/get-started/media/first-app/vs/windows-running-app.png and b/docs/get-started/media/first-app/vs/windows-running-app.png differ diff --git a/docs/get-started/media/first-app/vsmac/android-create-emulator.png b/docs/get-started/media/first-app/vsmac/android-create-emulator.png index 5ea1a25d5a..e7506a94bd 100644 Binary files a/docs/get-started/media/first-app/vsmac/android-create-emulator.png and b/docs/get-started/media/first-app/vsmac/android-create-emulator.png differ diff --git a/docs/get-started/media/first-app/vsmac/android-device-manager.png b/docs/get-started/media/first-app/vsmac/android-device-manager.png index 53c836d1cc..5792f2c47c 100644 Binary files a/docs/get-started/media/first-app/vsmac/android-device-manager.png and b/docs/get-started/media/first-app/vsmac/android-device-manager.png differ diff --git a/docs/get-started/media/first-app/vsmac/android-pixel5-debug-target.png b/docs/get-started/media/first-app/vsmac/android-pixel5-debug-target.png index 3adea375b4..8b6bdf55a6 100644 Binary files a/docs/get-started/media/first-app/vsmac/android-pixel5-debug-target.png and b/docs/get-started/media/first-app/vsmac/android-pixel5-debug-target.png differ diff --git a/docs/get-started/media/first-app/vsmac/android-pixel5-run.png b/docs/get-started/media/first-app/vsmac/android-pixel5-run.png index 61d804c22c..f85f0ba6e0 100644 Binary files a/docs/get-started/media/first-app/vsmac/android-pixel5-run.png and b/docs/get-started/media/first-app/vsmac/android-pixel5-run.png differ diff --git a/docs/get-started/media/first-app/vsmac/ios-debug-target.png b/docs/get-started/media/first-app/vsmac/ios-debug-target.png index 27508dc165..07a057c2a0 100644 Binary files a/docs/get-started/media/first-app/vsmac/ios-debug-target.png and b/docs/get-started/media/first-app/vsmac/ios-debug-target.png differ diff --git a/docs/get-started/media/first-app/vsmac/ios-run.png b/docs/get-started/media/first-app/vsmac/ios-run.png index 4120c03ccc..f3498fb351 100644 Binary files a/docs/get-started/media/first-app/vsmac/ios-run.png and b/docs/get-started/media/first-app/vsmac/ios-run.png differ diff --git a/docs/get-started/media/first-app/vsmac/mac-debug-target.png b/docs/get-started/media/first-app/vsmac/mac-debug-target.png index 1b08c87514..040d0323c4 100644 Binary files a/docs/get-started/media/first-app/vsmac/mac-debug-target.png and b/docs/get-started/media/first-app/vsmac/mac-debug-target.png differ diff --git a/docs/get-started/media/first-app/vsmac/mac-run.png b/docs/get-started/media/first-app/vsmac/mac-run.png index f5d9c4aa39..75385d68ad 100644 Binary files a/docs/get-started/media/first-app/vsmac/mac-run.png and b/docs/get-started/media/first-app/vsmac/mac-run.png differ diff --git a/docs/get-started/media/first-app/vsmac/project-dependencies-restored.png b/docs/get-started/media/first-app/vsmac/project-dependencies-restored.png index e7390114a3..a4fbab5435 100644 Binary files a/docs/get-started/media/first-app/vsmac/project-dependencies-restored.png and b/docs/get-started/media/first-app/vsmac/project-dependencies-restored.png differ diff --git a/docs/get-started/media/first-app/vsmac/select-target-framework.png b/docs/get-started/media/first-app/vsmac/select-target-framework.png index e852da3a0a..f9eac4d774 100644 Binary files a/docs/get-started/media/first-app/vsmac/select-target-framework.png and b/docs/get-started/media/first-app/vsmac/select-target-framework.png differ diff --git a/docs/includes/dotnet-publish-net8-ios.md b/docs/includes/dotnet-publish-net8-ios.md new file mode 100644 index 0000000000..b2c6e5e45a --- /dev/null +++ b/docs/includes/dotnet-publish-net8-ios.md @@ -0,0 +1,7 @@ +--- +ms.topic: include +ms.date: 11/13/2023 +--- + +> [!NOTE] +> In .NET 8, the `dotnet publish` command defaults to the `Release` configuration. Therefore, the build configuration can be omitted from the command line. In addition, the `dotnet publish` command also defaults to the `ios-arm64` `RuntimeIdentifier`. Therefore, the `RuntimeIdentifier` can also be omitted from the command line. diff --git a/docs/includes/dotnet-publish-net8.md b/docs/includes/dotnet-publish-net8.md new file mode 100644 index 0000000000..0d275140dd --- /dev/null +++ b/docs/includes/dotnet-publish-net8.md @@ -0,0 +1,7 @@ +--- +ms.topic: include +ms.date: 11/13/2023 +--- + +> [!NOTE] +> In .NET 8, the `dotnet publish` command defaults to the `Release` configuration. Therefore, the build configuration can be omitted from the command line. diff --git a/docs/includes/vsmac-eol.md b/docs/includes/vsmac-eol.md new file mode 100644 index 0000000000..d89ce8dc98 --- /dev/null +++ b/docs/includes/vsmac-eol.md @@ -0,0 +1,7 @@ +--- +ms.topic: include +ms.date: 11/08/2023 +--- + +> [!NOTE] +> Visual Studio for Mac is scheduled for retirement by August 31 2024 in accordance with [Microsoft's Modern Lifecycle Policy](/lifecycle/policies/modern). Visual Studio for Mac 17.6 will continue to be supported until August 31 2024, with servicing updates for security issues and updated platforms from Apple. For more information, including alternative options for developing on a Mac, see [What's happening to Visual Studio for Mac?](/visualstudio/mac/what-happened-to-vs-for-mac). diff --git a/docs/index.yml b/docs/index.yml index deaf3cb1bf..141c51904b 100644 --- a/docs/index.yml +++ b/docs/index.yml @@ -84,6 +84,8 @@ landingContent: url: xaml/fundamentals/get-started.md - text: Compilation url: xaml/xamlc.md + - text: Class modifiers + url: xaml/class-modifiers.md - text: Field modifiers url: xaml/field-modifiers.md - text: Generics diff --git a/docs/ios/apple-account-management.md b/docs/ios/apple-account-management.md index a84478d7b1..f56553b310 100644 --- a/docs/ios/apple-account-management.md +++ b/docs/ios/apple-account-management.md @@ -48,6 +48,8 @@ If you have an individual Apple Developer account, as opposed to an enterprise a # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + 1. In Visual Studio for Mac, go to **Visual Studio > Preferences > Publishing > Apple Developer Account**, click on the **Add** button and select **Individual Account...** or **Enterprise Account...**: :::image type="content" source="media/apple-account-management/vsmac/add-account.png" alt-text="Add an Apple Developer Account to Visual Studio for Mac."::: diff --git a/docs/ios/capabilities.md b/docs/ios/capabilities.md index dada49d5cc..9b2aede18c 100644 --- a/docs/ios/capabilities.md +++ b/docs/ios/capabilities.md @@ -49,6 +49,8 @@ In Visual Studio, all capabilities are added to your app's *Entitlements.plist* # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + 1. In Visual Studio for Mac, enable automatic provisioning for your project. For more information, see [Enable automatic provisioning](~/ios/device-provisioning/automatic-provisioning.md#enable-automatic-provisioning). 1. In the **Solution Window**, double-click the *Entitlements.plist* file from the *Platforms > iOS* folder of your .NET MAUI app project to open it in the entitlements editor. Then, change from the **Source** view to the **Entitlements** view: diff --git a/docs/ios/cli.md b/docs/ios/cli.md index 58994f0315..08e84eb1db 100644 --- a/docs/ios/cli.md +++ b/docs/ios/cli.md @@ -16,7 +16,7 @@ In this tutorial, you'll learn how to create and run a .NET Multi-platform App U ```zsh cd MyMauiApp - dotnet build -t:Run -f net7.0-ios + dotnet build -t:Run -f net8.0-ios ``` The `dotnet build` command will restore the project the dependencies, build the app, and launch it in the default simulator. @@ -49,13 +49,13 @@ A .NET MAUI iOS app can be launched on a specific iOS simulator from a Mac by pr 3. In **Terminal**, build the app and run it on your chosen simulator by specifying the `_DeviceName` MSBuild property using the `-p` [MSBuild option](/dotnet/core/tools/dotnet-build#msbuild): ```zsh - dotnet build -t:Run -f net7.0-ios -p:_DeviceName=:v2:udid=MY_SPECIFIC_UDID + dotnet build -t:Run -f net8.0-ios -p:_DeviceName=:v2:udid=MY_SPECIFIC_UDID ``` For example, use the following command to build the app and run it on the iPhone 13 Pro simulator: ```zsh - dotnet build -t:Run -f net7.0-ios -p:_DeviceName=:v2:udid=E25BBE37-69BA-4720-B6FD-D54C97791E79 + dotnet build -t:Run -f net8.0-ios -p:_DeviceName=:v2:udid=E25BBE37-69BA-4720-B6FD-D54C97791E79 ``` 4. In your chosen simulator, press the **Click me** button several times and observe that the count of the number of button clicks is incremented. @@ -81,7 +81,7 @@ A device must be provisioned before you can deploy an iOS app to it. For more in 5. In **Terminal**, build the app and run it on your chosen simulator by specifying the `_DeviceName` MSBuild property using the `-p` [MSBuild option](/dotnet/core/tools/dotnet-build#msbuild): ```zsh - dotnet build -t:Run -f net7.0-ios -p:RuntimeIdentifier=ios-arm64 -p:_DeviceName=MY_SPECIFIC_UDID + dotnet build -t:Run -f net8.0-ios -p:RuntimeIdentifier=ios-arm64 -p:_DeviceName=MY_SPECIFIC_UDID ``` Replace "MY_SPECIFIC_UDID" with the device identifier you copied to the clipboard. diff --git a/docs/ios/deployment/index.md b/docs/ios/deployment/index.md index e83b1e811f..fc3a526b63 100644 --- a/docs/ios/deployment/index.md +++ b/docs/ios/deployment/index.md @@ -8,10 +8,10 @@ ms.date: 02/24/2023 > [!div class="op_single_selector"] > -> - [Publish for Android](../../android/deployment/index.md) -> - [Publish for iOS](index.md) -> - [Publish for macOS](../../mac-catalyst/deployment/index.md) -> - [Publish for Windows](../../windows/deployment/overview.md) +> - [Publish for app store distribution](publish-app-store.md) +> - [Publish for in-house distribution](publish-in-house.md) +> - [Publish for ad-hoc distribution](publish-ad-hoc.md) +> - [Publish using the command line](publish-cli.md) Once a .NET Multi-platform App UI (.NET MAUI) iOS app has been developed and tested, it can be packaged for distribution as an *.ipa* file. An *.ipa* file is an iOS app archive file that stores an iOS app. The following diagram shows the steps required to produce the app package for distribution: diff --git a/docs/ios/deployment/publish-ad-hoc.md b/docs/ios/deployment/publish-ad-hoc.md index 4ff2f984d4..3cfead7095 100644 --- a/docs/ios/deployment/publish-ad-hoc.md +++ b/docs/ios/deployment/publish-ad-hoc.md @@ -6,6 +6,12 @@ ms.date: 02/24/2023 # Publish an iOS app for ad-hoc distribution +> [!div class="op_single_selector"] +> +> - [Publish for app store distribution](publish-app-store.md) +> - [Publish for in-house distribution](publish-in-house.md) +> - [Publish using the command line](publish-cli.md) + Ad-hoc distribution is primarily used for testing apps within a wide group of people, and is available for the Apple Developer Program and the Apple Developer Enterprise Program. Another use case for ad-hoc distribution is distribution within a company when App Store Connect isn't an option. Ad-hoc distribution has the advantage of not requiring App Store approval, with apps being installed with [Apple Configurator](https://apps.apple.com/app/id1037126344). However, it's limited to 100 devices per membership year, for both development and distribution, and the devices must be added to your Apple Developer Account. @@ -98,6 +104,8 @@ Visual Studio can publish a .NET MAUI iOS app for ad-hoc distribution. For infor # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + [!INCLUDE [Publish](../includes/publish-vsmac.md)] diff --git a/docs/ios/deployment/publish-app-store.md b/docs/ios/deployment/publish-app-store.md index 4dbbecd627..5477853942 100644 --- a/docs/ios/deployment/publish-app-store.md +++ b/docs/ios/deployment/publish-app-store.md @@ -6,6 +6,12 @@ ms.date: 02/24/2023 # Publish an iOS app for App Store distribution +> [!div class="op_single_selector"] +> +> - [Publish for in-house distribution](publish-in-house.md) +> - [Publish for ad-hoc distribution](publish-ad-hoc.md) +> - [Publish using the command line](publish-cli.md) + The most common approach to distributing iOS apps to users is through the App Store. Apps are submitted to the App Store through an online tool called *App Store Connect*. Only developers who belong to the Apple Developer Program have access to this tool. Members of the Apple Developer Enterprise Program do not have access. All apps submitted to the App Store require approval from Apple. Distributing an iOS app requires that the app is provisioned using a *provisioning profile*. Provisioning profiles are files that contain code signing information, as well as the identity of the app and its intended distribution mechanism. @@ -100,6 +106,8 @@ For information about publishing an iOS app using the Command Line Interface (CL # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + [!INCLUDE [Publish](../includes/publish-vsmac.md)] diff --git a/docs/ios/deployment/publish-cli.md b/docs/ios/deployment/publish-cli.md index 5276f8273d..a0322f338c 100644 --- a/docs/ios/deployment/publish-cli.md +++ b/docs/ios/deployment/publish-cli.md @@ -6,11 +6,17 @@ ms.date: 02/24/2023 # Publish an iOS app using the command line +> [!div class="op_single_selector"] +> +> - [Publish for app store distribution](publish-app-store.md) +> - [Publish for in-house distribution](publish-in-house.md) +> - [Publish for ad-hoc distribution](publish-ad-hoc.md) + To publish your app from the command line on a Mac, open a terminal and navigate to the folder for your .NET Multi-platform App UI (.NET MAUI) app project. Run the `dotnet publish` command, providing the following parameters: | Parameter | Value | |------------------------------|-------------------------------------------------------------------------------------------------| -| `-f` or `--framework` | The target framework, which is `net7.0-ios`. | +| `-f` or `--framework` | The target framework, which is `net8.0-ios`. | | `-c` or `--configuration` | The build configuration, which is `Release`. | > [!WARNING] @@ -38,15 +44,19 @@ For a full list of build properties, see [Project file properties](https://githu For example, use the following command to build and sign an *.ipa* on a Mac: ```dotnetcli -dotnet publish -f net7.0-ios -c Release -p:ArchiveOnBuild=true -p:RuntimeIdentifier=ios-arm64 -p:CodesignKey="Apple Distribution: John Smith (AY2GDE9QM7)" -p:CodesignProvision="MyMauiApp" +dotnet publish -f net8.0-ios -c Release -p:ArchiveOnBuild=true -p:RuntimeIdentifier=ios-arm64 -p:CodesignKey="Apple Distribution: John Smith (AY2GDE9QM7)" -p:CodesignProvision="MyMauiApp" ``` -Publishing builds and signs the app, and then copies the *.ipa* to the *bin/Release/net7.0-ios/ios-arm64/publish/* folder. The distribution channel for the app is specified in the distribution certificate contained within the provisioning profile. For information about creating provisioning profiles for the different distribution channels, see [Publish an iOS app for App Store distribution](publish-app-store.md), [Publish an iOS app for ad-hoc distribution](publish-ad-hoc.md), and [Publish an iOS app for in-house distribution](publish-in-house.md). +[!INCLUDE [dotnet publish in .NET 8 on iOS](~/includes/dotnet-publish-net8-ios.md)] + +Publishing builds and signs the app, and then copies the *.ipa* to the *bin/Release/net8.0-ios/ios-arm64/publish/* folder. The distribution channel for the app is specified in the distribution certificate contained within the provisioning profile. For information about creating provisioning profiles for the different distribution channels, see [Publish an iOS app for App Store distribution](publish-app-store.md), [Publish an iOS app for ad-hoc distribution](publish-ad-hoc.md), and [Publish an iOS app for in-house distribution](publish-in-house.md). For more information about the `dotnet publish` command, see [dotnet publish](/dotnet/core/tools/dotnet-publish). +::: moniker range="=net-maui-7.0" + ## Runtime identifiers If the `RuntimeIdentifier` parameter isn't specified on the command line, or in the project file, the build process will default to a simulator runtime identifier. In addition, passing the runtime identifier on the command line can result in the build failing to restore if there are multiple target frameworks in the project file. For more information, see [Specifying both -f and -r to dotnet build fails to restore if multiple frameworks are present in the project file](https://github.com/dotnet/sdk/issues/21877). @@ -79,6 +89,8 @@ Then, use the following command to publish your app: dotnet publish -f net7.0-ios -c Release ... ``` +::: moniker-end + ## Define build properties in your project file An alternative to specifying build parameters on the command line is to specify them in your project file in a ``. The following table lists some of the common build properties: @@ -89,7 +101,7 @@ An alternative to specifying build parameters on the command line is to specify | `` | The unique identifier for the app, such as `com.companyname.mymauiapp`. | | `` | The version of the build that identifies an iteration of the app. | | `` | The version number of the app. | -| `` | The runtime identifier (RID) for the project. Set to `ios-arm64`. | +| `` | The runtime identifier (RID) for the project. Use `ios-arm64`. | | `` | A boolean value that indicates whether to produce the app archive. Use `true` to produce the *.ipa*. | | `` | The name of the code signing key. | | `` | The provisioning profile to use when signing the app bundle. | @@ -104,7 +116,7 @@ The following example shows a typical property group for building and signing yo ```xml - ios-arm64 + ios-arm64 Apple Distribution: John Smith (AY2GDE9QM7) MyMauiApp true @@ -141,18 +153,36 @@ To publish your app from the command line on Windows, open a terminal and naviga For example, use the following command to build and sign an *.ipa* from Windows: ```dotnetcli -dotnet publish -f net7.0-ios -c Release -p:ArchiveOnBuild=true -p:RuntimeIdentifier=ios-arm64 -p:CodesignKey="Apple Distribution: John Smith (AY2GDE9QM7)" -p:CodesignProvision="MyMauiApp" -p:ServerAddress={macOS build host IP address} -p:ServerUser={macOS username} -p:ServerPassword={macOS password} -p:TcpPort=58181 -p:_DotNetRootRemoteDirectory=/Users/{macOS username}/Library/Caches/Xamarin/XMA/SDKs/dotnet/ +dotnet publish -f net8.0-ios -c Release -p:ArchiveOnBuild=true -p:RuntimeIdentifier=ios-arm64 -p:CodesignKey="Apple Distribution: John Smith (AY2GDE9QM7)" -p:CodesignProvision="MyMauiApp" -p:ServerAddress={macOS build host IP address} -p:ServerUser={macOS username} -p:ServerPassword={macOS password} -p:TcpPort=58181 -p:_DotNetRootRemoteDirectory=/Users/{macOS username}/Library/Caches/Xamarin/XMA/SDKs/dotnet/ ``` +[!INCLUDE [dotnet publish in .NET 8 on iOS](~/includes/dotnet-publish-net8-ios.md)] + > [!NOTE] > If the `ServerPassword` parameter is omitted from a command line build invocation, Pair to Mac attempts to log in to the Mac build host using its saved SSH keys. -Publishing builds and signs the app, and then copies the *.ipa* to the *bin\\Release\\net7.0-ios\\ios-arm64\\publish* folder on your Windows machine. The distribution channel for the app is specified in the distribution certificate contained within the provisioning profile. For information about creating distribution provisioning profiles for the different distribution channels, see [Publish an iOS app for App Store distribution](publish-app-store.md), [Publish an iOS app for ad-hoc distribution](publish-ad-hoc.md), and [Publish an iOS app for in-house distribution](publish-in-house.md) +Publishing builds and signs the app, and then copies the *.ipa* to the *bin\\Release\\net8.0-ios\\ios-arm64\\publish* folder on your Windows machine. The distribution channel for the app is specified in the distribution certificate contained within the provisioning profile. For information about creating distribution provisioning profiles for the different distribution channels, see [Publish an iOS app for App Store distribution](publish-app-store.md), [Publish an iOS app for ad-hoc distribution](publish-ad-hoc.md), and [Publish an iOS app for in-house distribution](publish-in-house.md) During the publishing process it maybe necessary to allow `codesign` to run on your paired Mac: :::image type="content" source="media/publish/codesign.png" alt-text="Allow codesign to sign your app on your paired Mac."::: +::: moniker range=">=net-maui-8.0" + +### Troubleshoot a remote build + +If a `RuntimeIdentifier` isn't specified when building remotely from the command line on Windows, the architecture of the Windows machine will be used. This occurs because the `RuntimeIdentifier` has to be set early in the build process, before the build can connect to the Mac to derive its architecture. + +If a `RuntimeIdentifier` isn't specified when building remotely using Visual Studio on Windows, the IDE will detect the architecture of the remote Mac and set it accordingly. Overriding the default can be achieved by setting the `$(ForceSimulatorX64ArchitectureInIDE)` build property: + +```xml + + true + +``` + +::: moniker-end + ## Distribute the app The *.ipa* file can be distributed with one of the following approaches: diff --git a/docs/ios/deployment/publish-in-house.md b/docs/ios/deployment/publish-in-house.md index 6b06ca950a..5926615b8f 100644 --- a/docs/ios/deployment/publish-in-house.md +++ b/docs/ios/deployment/publish-in-house.md @@ -6,6 +6,12 @@ ms.date: 02/24/2023 # Publish an iOS app for in-house distribution +> [!div class="op_single_selector"] +> +> - [Publish for app store distribution](publish-app-store.md) +> - [Publish for ad-hoc distribution](publish-ad-hoc.md) +> - [Publish using the command line](publish-cli.md) + In-house distribution enables members of the Apple Developer Enterprise Program to distribute apps internally to other members of the same organization. This has the advantage of not requiring an App Store review, and having no limit on the number of devices on which an app can be installed. However, members of the Apple Developer Enterprise Program don't have access to App Store Connect, and therefore the licensee is responsible for distributing the app. Distributing an iOS app requires that the app is provisioned using a *provisioning profile*. Provisioning profiles are files that contain code signing information, as well as the identity of the app and its intended distribution mechanism. @@ -129,6 +135,8 @@ Visual Studio can publish a .NET MAUI iOS app for in-house distribution. For inf # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + [!INCLUDE [Publish](../includes/publish-vsmac.md)] diff --git a/docs/ios/device-provisioning/automatic-provisioning.md b/docs/ios/device-provisioning/automatic-provisioning.md index 8c527d3e41..891bbb0bcc 100644 --- a/docs/ios/device-provisioning/automatic-provisioning.md +++ b/docs/ios/device-provisioning/automatic-provisioning.md @@ -39,6 +39,8 @@ Once you've added your Apple Developer Account to Visual Studio, you need to ena # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + 1. In the **Solution Window**, double-click the **Info.plist** file from the **Platforms > iOS** folder of your .NET MAUI app project to open it in the editor. 1. In the **Info.plist** editor, change from the **Source** view to the **Application** view: diff --git a/docs/ios/device-provisioning/manual-provisioning.md b/docs/ios/device-provisioning/manual-provisioning.md index 65c11d2fde..fff8f5165e 100644 --- a/docs/ios/device-provisioning/manual-provisioning.md +++ b/docs/ios/device-provisioning/manual-provisioning.md @@ -36,6 +36,8 @@ Once you've added your Apple Developer Account to Visual Studio, you need to gen # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + 1. In Visual Studio for Mac, go to **Visual Studio > Preferences > Publishing > Apple Developer Account**. 1. In the **Apple Developer Accounts** window, select a team and then select **View Details**. 1. In the **Details** window, select **Create Certificate** and then select **Apple Development** or **iOS Development**. A new signing identity will be created and will sync with Apple if you have the correct permissions. @@ -134,6 +136,8 @@ The provisioning profiles will be downloaded on Windows, and exported to your Ma # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + 1. In Visual Studio for Mac, go to **Visual Studio > Preferences > Publishing > Apple Developer Account**. 1. In the **Apple Developer Accounts** window, select a team and click the **View Details...** button. 1. In the **Details** window, verify that the new profile appears in the **Provisioning Profiles** list. You may need to restart Visual Studio for Mac to refresh the list. @@ -162,6 +166,8 @@ After manually creating the development provisioning profile, and installing it # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + 1. In the **Solution Window**, right-click on your .NET MAUI app project and select **Properties**. 1. In the **Project Properties** window, select the **Build > App Info** tab and ensure that the value of the **Application ID** field corresponds to the format of the App ID you created earlier. 1. In the **Solution Window**, double-click the **Info.plist** file from the **Platforms > iOS** folder of your .NET MAUI app project to open it in the editor. diff --git a/docs/ios/entitlements.md b/docs/ios/entitlements.md index d5bce18beb..f600e3e73c 100644 --- a/docs/ios/entitlements.md +++ b/docs/ios/entitlements.md @@ -47,6 +47,8 @@ Entitlements can be configured in Visual Studio by double-clicking the *Entitlem # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + 1. In the **Solution Window**, double-click the *Entitlements.plist* file from the *Platforms > iOS* folder of your .NET MAUI app project to open it in the entitlements editor. Then, change from the **Source** view to the **Entitlements** view: :::image type="content" source="media/entitlements/editor-source-vsmac.png" alt-text="Visual Studio for Mac iOS entitlements editor source view."::: @@ -85,6 +87,8 @@ A .NET MAUI iOS app must be configured to consume the entitlements defined in th # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + 1. In the **Solution Window**, right-click on your .NET MAUI app project and select **Properties**. 1. In the **Project Properties** window, select the **Build > iOS > Bundle Signing** tab and click the **...** button next to the **Custom Entitlements** field: diff --git a/docs/ios/includes/deploy.md b/docs/ios/includes/deploy.md index 47a0bcbde4..f7d2b0ea44 100644 --- a/docs/ios/includes/deploy.md +++ b/docs/ios/includes/deploy.md @@ -28,6 +28,8 @@ After configuring provisioning in your .NET MAUI app project, the app can be dep # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + 1. In the **Solution Window**, double-click the **Info.plist** file from the **Platforms > iOS** folder of your .NET MAUI app project to open it in the editor. 1. In the **Info.plist** editor, change from the **Source** view to the **Application** view: diff --git a/docs/ios/includes/distribution-certificate.md b/docs/ios/includes/distribution-certificate.md index 9af7d51dbf..3493af5b5a 100644 --- a/docs/ios/includes/distribution-certificate.md +++ b/docs/ios/includes/distribution-certificate.md @@ -26,6 +26,8 @@ To create a distribution certificate: # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + 1. In Visual Studio for Mac, go to **Visual Studio > Preferences > Publishing > Apple Developer Account**. 1. In the **Apple Developer Accounts** window, select a team and click the **View Details...** button. 1. In the **Details** window, click **Create Certificate** and select **Apple Distribution** or **iOS Distribution**. A new signing identity will be created and will sync with Apple provided that you have the correct permissions. diff --git a/docs/ios/includes/download-profiles.md b/docs/ios/includes/download-profiles.md index 3b580d9cdc..82e5d1606c 100644 --- a/docs/ios/includes/download-profiles.md +++ b/docs/ios/includes/download-profiles.md @@ -22,6 +22,8 @@ The provisioning profiles are downloaded on Windows, and exported to your Mac bu # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + 1. In Visual Studio for Mac, go to **Visual Studio > Preferences > Publishing > Apple Developer Account**. 1. In the **Apple Developer Accounts** window, select your team and click **View Details**. 1. In the **Details** window, verify that the new profile appears in the **Provisioning Profiles** list. You may need to restart Visual Studio for Mac to refresh the list. diff --git a/docs/ios/linking.md b/docs/ios/linking.md index d1b09a18bc..9fa2366f1d 100644 --- a/docs/ios/linking.md +++ b/docs/ios/linking.md @@ -21,6 +21,8 @@ no-loc: [ ILLink ] # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + 1. In the **Solution Window**, right-click on your .NET MAUI app project and select **Properties**. 1. In the **Project Properties** window, select the **Build > iOS > Build** tab. 1. In the **Project Properties** window, ensure the **Configuration** drop-down is set to **Release** and set the **Linker behavior** drop-down to your desired linker behavior: diff --git a/docs/ios/pair-to-mac.md b/docs/ios/pair-to-mac.md index b94d402657..4d36e303d0 100644 --- a/docs/ios/pair-to-mac.md +++ b/docs/ios/pair-to-mac.md @@ -154,7 +154,7 @@ If you encounter any trouble using automatic Mac provisioning, take a look at th Pair to Mac supports building .NET MAUI apps from the command line. Navigate to the folder that holds the source of your .NET MAUI iOS app and execute the following command: ```dotnet -dotnet build -f net7.0-ios -p:ServerAddress={macOS build host IP address} -p:ServerUser={macOS username} -p:ServerPassword={macOS password} -p:TcpPort=58181 -p:_DotNetRootRemoteDirectory=/Users/{macOS username}/Library/Caches/Xamarin/XMA/SDKs/dotnet/ +dotnet build -f net8.0-ios -p:ServerAddress={macOS build host IP address} -p:ServerUser={macOS username} -p:ServerPassword={macOS password} -p:TcpPort=58181 -p:_DotNetRootRemoteDirectory=/Users/{macOS username}/Library/Caches/Xamarin/XMA/SDKs/dotnet/ ``` The parameters passed to `dotnet` in the above example are: @@ -167,3 +167,5 @@ The parameters passed to `dotnet` in the above example are: The first time Pair to Mac logs in to a Mac build host from either Visual Studio 2022 or the command-line, it sets up SSH keys. With these keys, future logins won't require a username or password. Newly created keys are stored in **%LOCALAPPDATA%\Xamarin\MonoTouch**. If the `ServerPassword` parameter is omitted from a command-line build invocation, Pair to Mac attempts to log in to the Mac build host using the saved SSH keys. + +For more information about building iOS apps from the Windows command-line, see [Publish an iOS app using the command line](~/ios/deployment/publish-cli.md). diff --git a/docs/ios/wireless-deployment.md b/docs/ios/wireless-deployment.md index 81444707db..2a0f6e40b2 100644 --- a/docs/ios/wireless-deployment.md +++ b/docs/ios/wireless-deployment.md @@ -71,6 +71,8 @@ After wirelessly pairing your device to Xcode, provisioned .NET MAUI iOS apps ca # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + 1. Ensure that your iOS device is wirelessly paired to your Mac build host. For more information, see [Pair an iOS device](#pair-an-ios-device). 1. In the Visual Studio for Mac toolbar, ensure that the debug target is set to your connected iOS device: diff --git a/docs/mac-catalyst/capabilities.md b/docs/mac-catalyst/capabilities.md index 8ea5c4ff06..1c81a8ddea 100644 --- a/docs/mac-catalyst/capabilities.md +++ b/docs/mac-catalyst/capabilities.md @@ -38,6 +38,8 @@ Once you've created an App ID you must create a provisioning profile for the App ## Download provisioning profiles +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + Once you've created a provisioning profile it must be downloaded by Visual Studio for Mac: 1. In Visual Studio for Mac, go to *Visual Studio > Preferences > Publishing > Apple Developer Account*. @@ -64,7 +66,7 @@ The project file for your app should be updated to use the signing certificate, The following example shows a typical property group for building and signing your Mac Catalyst app for Mac App Store distribution: ```xml - + True Apple Distribution: John Smith (AY2GDE9QM7) MyMauiApp diff --git a/docs/mac-catalyst/cli.md b/docs/mac-catalyst/cli.md index cdf095885b..bcd2e44398 100644 --- a/docs/mac-catalyst/cli.md +++ b/docs/mac-catalyst/cli.md @@ -16,7 +16,7 @@ In this tutorial, you'll learn how to create and run a .NET Multi-platform App U ```zsh cd MyMauiApp - dotnet build -t:Run -f net7.0-maccatalyst + dotnet build -t:Run -f net8.0-maccatalyst ``` The `dotnet build` command will restore the project dependencies, build the app, and launch it. diff --git a/docs/mac-catalyst/deployment/index.md b/docs/mac-catalyst/deployment/index.md index a5285fe2bf..3543bd5e38 100644 --- a/docs/mac-catalyst/deployment/index.md +++ b/docs/mac-catalyst/deployment/index.md @@ -8,10 +8,10 @@ ms.date: 03/23/2023 > [!div class="op_single_selector"] > -> - [Publish for Android](../../android/deployment/index.md) -> - [Publish for iOS](../../ios/deployment/index.md -> - [Publish for macOS](index.md) -> - [Publish for Windows](../../windows/deployment/overview.md) +> - [Publish an unsigned app](publish-unsigned.md) +> - [Publish for app store distribution](publish-app-store.md) +> - [Publish outside the app store](publish-outside-app-store.md) +> - [Publish for ad-hoc distribution](publish-ad-hoc.md) Once a .NET Multi-platform App UI (.NET MAUI) Mac Catalyst app has been developed and tested, it can be packaged for distribution as an *.app* or a *.pkg* file. An *.app* file is a self-contained app that can be run without installation, whereas a *.pkg* is an app packaged in an installer. The following diagram shows the steps required to produce an app package for distribution: diff --git a/docs/mac-catalyst/deployment/publish-ad-hoc.md b/docs/mac-catalyst/deployment/publish-ad-hoc.md index e415b54d3a..bd7056b273 100644 --- a/docs/mac-catalyst/deployment/publish-ad-hoc.md +++ b/docs/mac-catalyst/deployment/publish-ad-hoc.md @@ -6,6 +6,12 @@ ms.date: 03/20/2023 # Publish a Mac Catalyst app for ad-hoc distribution +> [!div class="op_single_selector"] +> +> - [Publish an unsigned app](publish-unsigned.md) +> - [Publish for app store distribution](publish-app-store.md) +> - [Publish outside the app store](publish-outside-app-store.md) + When distributing Mac Catalyst apps outside the Mac App Store, you can also choose to distribute your app to a limited number of users on registered devices. This is known as *ad-hoc* distribution, and is primarily used for testing apps within a group of people. However, it's limited to 100 devices per membership year, and the devices must be added to your Apple Developer Account. Members of the Apple Developer Program and the Apple Developer Enterprise Program can use this distribution approach. Distributing a Mac Catalyst app requires that the app is provisioned using a *provisioning profile*. Provisioning profiles are files that contain code signing information, as well as the identity of the app and its intended distribution mechanism. @@ -153,7 +159,7 @@ To publish your Mac Catalyst app from the command line on a Mac, open a terminal | Parameter | Value | |------------------------------|-------------------------------------------------------------------------------------------------| -| `-f` or `--framework` | The target framework, which is `net7.0-maccatalyst`. | +| `-f` or `--framework` | The target framework, which is `net8.0-maccatalyst`. | | `-c` or `--configuration` | The build configuration, which is `Release`. | | `-p:MtouchLink` | The link mode for the project, which can be `None`, `SdkOnly`, or `Full`. | | `-p:CreatePackage` | Set to `true` so that a package (*.pkg*) is created for the app at the end of the build. | @@ -161,6 +167,7 @@ To publish your Mac Catalyst app from the command line on a Mac, open a terminal | `-p:CodesignKey` | The name of the code signing key. Set to the name of your distribution certificate, as displayed in Keychain Access. | | `-p:CodesignProvision` | The provisioning profile to use when signing the app bundle. | | `-p:CodesignEntitlements` | The path to the entitlements file that specifies the entitlements the app requires. Set to `Platforms\MacCatalyst\Entitlements.plist`. | +| `-p:RuntimeIdentifier` | The runtime identifier (RID) for the project. Release builds of .NET MAUI Mac Catalyst apps default to using `maccatalyst-x64` and `maccatalyst-arm64` as runtime identifiers, to support universal apps. To support only a single architecture, specify `maccatalyst-x64` or `maccatalyst-arm64`. | | `-p:UseHardenedRuntime` | Set to `true` to enable the hardened runtime, which is required for Mac Catalyst apps that are distributed outside of the Mac App Store. | [!INCLUDE [Additional build parameters](../includes/additional-build-parameters.md)] @@ -168,10 +175,12 @@ To publish your Mac Catalyst app from the command line on a Mac, open a terminal For example, use the following command to build and sign a *.pkg* on a Mac, for ad-hoc distribution to users on registered devices: ```dotnetcli -dotnet publish -f net7.0-maccatalyst -c Release -p:MtouchLink=SdkOnly -p:CreatePackage=true -p:EnableCodeSigning=true -p:CodesignKey="Apple Development: John Smith (AY2GDE9QM7)" -p:CodesignProvision="MyMauiApp (Ad-hoc)" -p:CodesignEntitlements="Platforms\MacCatalyst\Entitlements.plist" -p:UseHardenedRuntime=true +dotnet publish -f net8.0-maccatalyst -c Release -p:MtouchLink=SdkOnly -p:CreatePackage=true -p:EnableCodeSigning=true -p:CodesignKey="Apple Development: John Smith (AY2GDE9QM7)" -p:CodesignProvision="MyMauiApp (Ad-hoc)" -p:CodesignEntitlements="Platforms\MacCatalyst\Entitlements.plist" -p:UseHardenedRuntime=true ``` -Publishing builds, signs, and packages the app, and then copies the *.pkg* to the *bin/Release/net7.0-maccatalyst/publish/* folder. If you publish the app using only a single architecture, it will be published to the *bin/Release/net7.0-maccatalyst/{architecture}/publish/* folder. +[!INCLUDE [dotnet publish in .NET 8](~/includes/dotnet-publish-net8.md)] + +Publishing builds, signs, and packages the app, and then copies the *.pkg* to the *bin/Release/net8.0-maccatalyst/publish/* folder. If you publish the app using only a single architecture, it will be published to the *bin/Release/net8.0-maccatalyst/{architecture}/publish/* folder. During the signing process it maybe necessary to enter your login password and allow `codesign` to run: @@ -208,7 +217,7 @@ For a full list of build properties, see [Project file properties](https://githu The following example shows a typical property group for building and signing your Mac Catalyst app for ad-hoc distribution to users on registered devices: ```xml - + SdkOnly True true @@ -222,7 +231,7 @@ The following example shows a typical property group for building and signing yo This example `` adds a condition check, preventing the settings from being processed unless the condition check passes. The condition check looks for two items: 1. The build configuration is set to `Release`. -1. The target framework is set to something containing the text `net7.0-maccatalyst`. +1. The target framework is set to something containing the text `net8.0-maccatalyst`. 1. The platform is set to `AnyCPU`. If any of these conditions fail, the settings aren't processed. More importantly, the `` and `` settings aren't set, preventing the app from being signed. @@ -230,10 +239,10 @@ If any of these conditions fail, the settings aren't processed. More importantly After adding the above property group, the app can be published from the command line on a Mac by opening a terminal and navigating to the folder for your .NET MAUI app project. Then, run the following command: ```dotnetcli -dotnet build -f net7.0-maccatalyst -c Release +dotnet build -f net8.0-maccatalyst -c Release ``` -Publishing builds, signs, and packages the app, and then copies the *.pkg* to the *bin/Release/net7.0-maccatalyst/publish/* folder. +Publishing builds, signs, and packages the app, and then copies the *.pkg* to the *bin/Release/net8.0-maccatalyst/publish/* folder. ## Distribute your app for testing diff --git a/docs/mac-catalyst/deployment/publish-app-store.md b/docs/mac-catalyst/deployment/publish-app-store.md index 6cb87ce64c..118c3534d2 100644 --- a/docs/mac-catalyst/deployment/publish-app-store.md +++ b/docs/mac-catalyst/deployment/publish-app-store.md @@ -6,6 +6,12 @@ ms.date: 03/23/2023 # Publish a Mac Catalyst app for Mac App Store distribution +> [!div class="op_single_selector"] +> +> - [Publish an unsigned app](publish-unsigned.md) +> - [Publish outside the app store](publish-outside-app-store.md) +> - [Publish for ad-hoc distribution](publish-ad-hoc.md) + The most common approach to distributing Mac Catalyst apps to users is through the Mac App Store. Apps are submitted to the Mac App Store through an online tool called *App Store Connect*. Only developers who belong to the Apple Developer Program have access to this tool. Members of the Apple Developer Enterprise Program do not have access. All apps submitted to the Mac App Store require approval from Apple. Distributing a Mac Catalyst app requires that the app is provisioned using a *provisioning profile*. Provisioning profiles are files that contain code signing information, as well as the identity of the app and its intended distribution mechanism. @@ -172,7 +178,7 @@ To publish your Mac Catalyst app from the command line on a Mac, open a terminal | Parameter | Value | |------------------------------|-------------------------------------------------------------------------------------------------| -| `-f` or `--framework` | The target framework, which is `net7.0-maccatalyst`. | +| `-f` or `--framework` | The target framework, which is `net8.0-maccatalyst`. | | `-c` or `--configuration` | The build configuration, which is `Release`. | | `-p:MtouchLink` | The link mode for the project, which can be `None`, `SdkOnly`, or `Full`. | | `-p:CreatePackage` | Set to `true` so that a package (*.pkg*) is created for the app at the end of the build. | @@ -203,9 +209,11 @@ For a full list of build properties, see [Project file properties](https://githu For example, use the following command to build and sign a *.pkg* on a Mac, for distribution through the Mac App Store: ```dotnetcli -dotnet publish -f net7.0-maccatalyst -c Release -p:MtouchLink=SdkOnly -p:CreatePackage=true -p:EnableCodeSigning=true -p:EnablePackageSigning=true -p:CodesignKey="Apple Distribution: John Smith (AY2GDE9QM7)" -p:CodesignProvision="MyMauiApp" -p:CodesignEntitlements="Platforms\MacCatalyst\Entitlements.plist" -p:PackageSigningKey="3rd Party Mac Developer Installer: John Smith (AY2GDE9QM7)" +dotnet publish -f net8.0-maccatalyst -c Release -p:MtouchLink=SdkOnly -p:CreatePackage=true -p:EnableCodeSigning=true -p:EnablePackageSigning=true -p:CodesignKey="Apple Distribution: John Smith (AY2GDE9QM7)" -p:CodesignProvision="MyMauiApp" -p:CodesignEntitlements="Platforms\MacCatalyst\Entitlements.plist" -p:PackageSigningKey="3rd Party Mac Developer Installer: John Smith (AY2GDE9QM7)" ``` +[!INCLUDE [dotnet publish in .NET 8](~/includes/dotnet-publish-net8.md)] + [!INCLUDE [Publishing output](../includes/publishing-output.md)] ## Define build properties in your project file @@ -235,7 +243,7 @@ For a full list of build properties, see [Project file properties](https://githu The following example shows a typical property group for building and signing your Mac Catalyst app for Mac App Store distribution: ```xml - + SdkOnly True true diff --git a/docs/mac-catalyst/deployment/publish-outside-app-store.md b/docs/mac-catalyst/deployment/publish-outside-app-store.md index 6cf2c73878..147ae0529d 100644 --- a/docs/mac-catalyst/deployment/publish-outside-app-store.md +++ b/docs/mac-catalyst/deployment/publish-outside-app-store.md @@ -6,6 +6,12 @@ ms.date: 03/23/2023 # Publish a Mac Catalyst app for distribution outside the Mac App Store +> [!div class="op_single_selector"] +> +> - [Publish an unsigned app](publish-unsigned.md) +> - [Publish for app store distribution](publish-app-store.md) +> - [Publish for ad-hoc distribution](publish-ad-hoc.md) + An alternative to distributing Mac Catalyst apps through the Mac App Store is to distribute them outside the Mac App Store. With this approach, your Mac Catalyst app can be hosted at a location of your choosing for download. Members of the Apple Developer Program and the Apple Developer Enterprise Program can use this distribution approach. Distributing a Mac Catalyst app requires that the app is provisioned using a *provisioning profile*. Provisioning profiles are files that contain code signing information, as well as the identity of the app and its intended distribution mechanism. @@ -168,7 +174,7 @@ If your app uses encryption, and you plan to distribute it outside the United St Currently, when you attempt to publish a .NET MAUI Mac Catalyst app for distribution outside the Mac App Store, provided you've met the provisioning requirements, you'll receive an error about `codesign` exiting with code 3: ``` -/usr/local/share/dotnet/packs/Microsoft.MacCatalyst.Sdk/16.2.1040/tools/msbuild/iOS/Xamarin.Shared.targets(1930,3): error MSB6006: "codesign" exited with code 3. [/Users/davidbritch/Projects/MyMauiApp/MyMauiApp/MyMauiApp.csproj::TargetFramework=net7.0-maccatalyst] +/usr/local/share/dotnet/packs/Microsoft.MacCatalyst.Sdk/16.2.1040/tools/msbuild/iOS/Xamarin.Shared.targets(1930,3): error MSB6006: "codesign" exited with code 3. [/Users/davidbritch/Projects/MyMauiApp/MyMauiApp/MyMauiApp.csproj::TargetFramework=net8.0-maccatalyst] ``` While `codesign` succeeds in signing your app, the `_CodesignVerify` target fails to verify the code signature: @@ -198,7 +204,7 @@ To publish your Mac Catalyst app from the command line on a Mac, open a terminal | Parameter | Value | |------------------------------|-------------------------------------------------------------------------------------------------| -| `-f` or `--framework` | The target framework, which is `net7.0-maccatalyst`. | +| `-f` or `--framework` | The target framework, which is `net8.0-maccatalyst`. | | `-c` or `--configuration` | The build configuration, which is `Release`. | | `-p:MtouchLink` | The link mode for the project, which can be `None`, `SdkOnly`, or `Full`. | | `-p:CreatePackage` | Set to `true` so that a package (*.pkg*) is created for the app at the end of the build. | @@ -208,6 +214,7 @@ To publish your Mac Catalyst app from the command line on a Mac, open a terminal | `-p:CodesignProvision` | The provisioning profile to use when signing the app bundle. | | `-p:CodesignEntitlements` | The path to the entitlements file that specifies the entitlements the app requires. Set to `Platforms\MacCatalyst\Entitlements.plist`. | | `-p:PackageSigningKey` | The package signing key to use when signing the package. Set to the name of your installer certificate, as displayed in Keychain Access. | +| `-p:RuntimeIdentifier` | The runtime identifier (RID) for the project. Release builds of .NET MAUI Mac Catalyst apps default to using `maccatalyst-x64` and `maccatalyst-arm64` as runtime identifiers, to support universal apps. To support only a single architecture, specify `maccatalyst-x64` or `maccatalyst-arm64`. | | `-p:UseHardenedRuntime` | Set to `true` to enable the hardened runtime, which is required for Mac Catalyst apps that are distributed outside of the Mac App Store. | [!INCLUDE [Additional build parameters](../includes/additional-build-parameters.md)] @@ -215,9 +222,11 @@ To publish your Mac Catalyst app from the command line on a Mac, open a terminal For example, use the following command to build and sign a *.pkg* on a Mac, for distribution outside the Mac App Store: ```dotnetcli -dotnet publish -f net7.0-maccatalyst -c Release -p:MtouchLink=SdkOnly -p:CreatePackage=true -p:EnableCodeSigning=true -p:EnablePackageSigning=true -p:CodesignKey="Developer ID Application: John Smith (AY2GDE9QM7)" -p:CodesignProvision="MyMauiApp (Non-App Store)" -p:CodesignEntitlements="Platforms\MacCatalyst\Entitlements.plist" -p:PackageSigningKey="Developer ID Installer: John Smith (AY2GDE9QM7)" -p:UseHardenedRuntime=true +dotnet publish -f net8.0-maccatalyst -c Release -p:MtouchLink=SdkOnly -p:CreatePackage=true -p:EnableCodeSigning=true -p:EnablePackageSigning=true -p:CodesignKey="Developer ID Application: John Smith (AY2GDE9QM7)" -p:CodesignProvision="MyMauiApp (Non-App Store)" -p:CodesignEntitlements="Platforms\MacCatalyst\Entitlements.plist" -p:PackageSigningKey="Developer ID Installer: John Smith (AY2GDE9QM7)" -p:UseHardenedRuntime=true ``` +[!INCLUDE [dotnet publish in .NET 8](~/includes/dotnet-publish-net8.md)] + [!INCLUDE [Publishing output](../includes/publishing-output.md)] ## Define build properties in your project file @@ -249,7 +258,7 @@ For a full list of build properties, see [Project file properties](https://githu The following example shows a typical property group for building and signing your Mac Catalyst app for distribution outside the Mac App Store: ```xml - + SdkOnly True true diff --git a/docs/mac-catalyst/deployment/publish-unsigned.md b/docs/mac-catalyst/deployment/publish-unsigned.md index 3a515c2c80..a78be89e77 100644 --- a/docs/mac-catalyst/deployment/publish-unsigned.md +++ b/docs/mac-catalyst/deployment/publish-unsigned.md @@ -6,11 +6,17 @@ ms.date: 03/23/2023 # Publish an unsigned .NET MAUI Mac Catalyst app +> [!div class="op_single_selector"] +> +> - [Publish for app store distribution](publish-app-store.md) +> - [Publish outside the app store](publish-outside-app-store.md) +> - [Publish for ad-hoc distribution](publish-ad-hoc.md) + To publish an unsigned .NET Multi-platform App UI (.NET MAUI) Mac Catalyst app, open a terminal and navigate to the folder for your app project. Run the `dotnet publish` command, providing the following parameters: | Parameter | Value | |------------------------------|-----------------------------------------------------------------------------------------------------| -| `-f` or `--framework` | The target framework, which is `net7.0-maccatalyst`. | +| `-f` or `--framework` | The target framework, which is `net8.0-maccatalyst`. | | `-c` or `--configuration` | The build configuration, which is `Release`. | | `-p:MtouchLink` | The link mode for the project, which can be `None`, `SdkOnly`, or `Full`. | | `-p:CreatePackage` | An optional parameter that controls whether to create an .app or a .pkg. Use `false` for an *.app*. | @@ -31,16 +37,18 @@ Additional build parameters can be specified on the command line. The following For example, use the following command to create an *.app*: ```dotnetcli -dotnet publish -f net7.0-maccatalyst -c Release -p:CreatePackage=false +dotnet publish -f net8.0-maccatalyst -c Release -p:CreatePackage=false ``` +[!INCLUDE [dotnet publish in .NET 8](~/includes/dotnet-publish-net8.md)] + Use the following command to create a *.pkg*: ```dotnetcli -dotnet publish -f net7.0-maccatalyst -c Release +dotnet publish -f net8.0-maccatalyst -c Release ``` -Publishing builds the app, and then copies the *.app* to the *bin/Release/net7.0-maccatalyst/* folder or the *.pkg* to the *bin/Release/net7.0-maccatalyst/publish/* folder. If you publish the app using only a single architecture, the *.app* will be published to the *bin/Release/net7.0-maccatalyst/{architecture}/* folder while the *.pkg* will be published to the *bin/Release/net7.0-maccatalyst/{architecture}/publish/* folder. +Publishing builds the app, and then copies the *.app* to the *bin/Release/net8.0-maccatalyst/* folder or the *.pkg* to the *bin/Release/net8.0-maccatalyst/publish/* folder. If you publish the app using only a single architecture, the *.app* will be published to the *bin/Release/net8.0-maccatalyst/{architecture}/* folder while the *.pkg* will be published to the *bin/Release/net8.0-maccatalyst/{architecture}/publish/* folder. For more information about the `dotnet publish` command, see [dotnet publish](/dotnet/core/tools/dotnet-publish). diff --git a/docs/mac-catalyst/entitlements.md b/docs/mac-catalyst/entitlements.md index 8c15b6b6ab..0f896b0544 100644 --- a/docs/mac-catalyst/entitlements.md +++ b/docs/mac-catalyst/entitlements.md @@ -30,6 +30,8 @@ To add a new entitlements file to your .NET MAUI app project, add a new XML file ## Set entitlements +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + Entitlements can be configured in Visual Studio for Mac by double-clicking the *Entitlements.plist* file to open it in the entitlements editor: 1. In Visual Studio for Mac's **Solution Window**, double-click the *Entitlements.plist* file from the *Platforms > MacCatalyst* folder of your .NET MAUI app project to open it in the entitlements editor. Then, change from the **Source** view to the **Entitlements** view: @@ -46,6 +48,8 @@ It may also be necessary to set privacy keys in *Info.plist*, for certain entitl ## Consume entitlements +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + A .NET MAUI Mac Catalyst app must be configured to consume the entitlements defined in the *Entitlements.plist* file: 1. In Visual Studio for Mac's **Solution Window**, right-click on your .NET MAUI app project and select **Properties**. diff --git a/docs/mac-catalyst/includes/publishing-output.md b/docs/mac-catalyst/includes/publishing-output.md index 8517d31e5b..6f98366d11 100644 --- a/docs/mac-catalyst/includes/publishing-output.md +++ b/docs/mac-catalyst/includes/publishing-output.md @@ -3,7 +3,7 @@ ms.topic: include ms.date: 03/23/2023 --- -Publishing builds, signs, and packages the app, and then copies the *.pkg* to the *bin/Release/net7.0-maccatalyst/publish/* folder. If you publish the app using only a single architecture, it will be published to the *bin/Release/net7.0-maccatalyst/{architecture}/publish/* folder. +Publishing builds, signs, and packages the app, and then copies the *.pkg* to the *bin/Release/net8.0-maccatalyst/publish/* folder. If you publish the app using only a single architecture, it will be published to the *bin/Release/net8.0-maccatalyst/{architecture}/publish/* folder. During the signing process it maybe necessary to enter your login password and allow `codesign` and `productbuild` to run: diff --git a/docs/mac-catalyst/includes/publishing-property-group.md b/docs/mac-catalyst/includes/publishing-property-group.md index b616321395..55b74969da 100644 --- a/docs/mac-catalyst/includes/publishing-property-group.md +++ b/docs/mac-catalyst/includes/publishing-property-group.md @@ -6,7 +6,7 @@ ms.date: 03/23/2023 This example `` adds a condition check, preventing the settings from being processed unless the condition check passes. The condition check looks for two items: 1. The build configuration is set to `Release`. -1. The target framework is set to something containing the text `net7.0-maccatalyst`. +1. The target framework is set to something containing the text `net8.0-maccatalyst`. 1. The platform is set to `AnyCPU`. If any of these conditions fail, the settings aren't processed. More importantly, the ``, ``, and `` settings aren't set, preventing the app from being signed. @@ -14,7 +14,9 @@ If any of these conditions fail, the settings aren't processed. More importantly After adding the above property group, the app can be published from the command line on a Mac by opening a terminal and navigating to the folder for your .NET MAUI app project. Then, run the following command: ```dotnetcli -dotnet build -f net7.0-maccatalyst -c Release +dotnet build -f net8.0-maccatalyst -c Release ``` -Publishing builds, signs, and packages the app, and then copies the *.pkg* to the *bin/Release/net7.0-maccatalyst/publish/* folder. +[!INCLUDE [dotnet publish in .NET 8](~/includes/dotnet-publish-net8.md)] + +Publishing builds, signs, and packages the app, and then copies the *.pkg* to the *bin/Release/net8.0-maccatalyst/publish/* folder. diff --git a/docs/mac-catalyst/linking.md b/docs/mac-catalyst/linking.md index 6177bf3e20..0c15ab556f 100644 --- a/docs/mac-catalyst/linking.md +++ b/docs/mac-catalyst/linking.md @@ -9,6 +9,8 @@ no-loc: [ ILLink ] [!INCLUDE [Linker introduction and behavior](../macios/includes/linker-behavior.md)] +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + To configure linker behavior in Visual Studio for Mac: 1. In the **Solution Window**, right-click on your .NET MAUI app project and select **Properties**. diff --git a/docs/macios/info-plist.md b/docs/macios/info-plist.md index 88aa28e228..2ffba8c3da 100644 --- a/docs/macios/info-plist.md +++ b/docs/macios/info-plist.md @@ -37,6 +37,8 @@ Visual Studio's *Info.plist* editor contains two views of the data: # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + Visual Studio for Mac's *Info.plist* editor contains three views of the data: - Source, which enables you to edit keys and values manually: @@ -86,6 +88,8 @@ In **Solution Explorer**, right-click on your .NET MAUI app project and select * # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + In the **Solution Window**, right-click on your .NET MAUI app project and select **Properties**. Then, in the **Project Properties** window, select the **Build > App Info** tab. The **Application Title** field lists the application name. --- @@ -106,6 +110,8 @@ In **Solution Explorer**, right-click on your .NET MAUI app project and select * # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + In the **Solution Window**, right-click on your .NET MAUI app project and select **Properties**. Then, in the **Project Properties** window, select the **Build > App Info** tab. The **Application ID** field lists the bundle identifier. --- @@ -126,6 +132,8 @@ In **Solution Explorer**, right-click on your .NET MAUI app project and select * # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + In the **Solution Window**, right-click on your .NET MAUI app project and select **Properties**. Then, in the **Project Properties** window, select the **Build > App Info** tab. The **Application Display Version** field lists the application display version. --- @@ -146,6 +154,8 @@ In **Solution Explorer**, right-click on your .NET MAUI app project and select * # [Visual Studio for Mac](#tab/vsmac) +[!INCLUDE [Visual Studio for Mac end of life](~/includes/vsmac-eol.md)] + In the **Solution Window**, right-click on your .NET MAUI app project and select **Properties**. Then, in the **Project Properties** window, select the **Build > App Info** tab. The **Application Version** field lists the application version. --- diff --git a/docs/migration/android-binding-projects.md b/docs/migration/android-binding-projects.md index 5c87d8d75c..9846ec193c 100644 --- a/docs/migration/android-binding-projects.md +++ b/docs/migration/android-binding-projects.md @@ -19,7 +19,7 @@ To migrate a Xamarin.Android binding library to a .NET Android class library: ```xml - net7.0-android + net8.0-android 21 enable enable diff --git a/docs/migration/android-projects.md b/docs/migration/android-projects.md index c1eccd5022..92ef1cc08d 100644 --- a/docs/migration/android-projects.md +++ b/docs/migration/android-projects.md @@ -6,12 +6,12 @@ ms.date: 02/15/2023 # Xamarin.Android project migration -A .NET 7 project for a .NET Android app is similar to the following example: +A .NET 8 project for a .NET Android app is similar to the following example: ```xml - net7.0-android + net8.0-android Exe @@ -80,20 +80,20 @@ In Xamarin.Android, Java, and Kotlin Android projects, the `` element For more information about the `` element, see the [Android documentation](https://developer.android.com/guide/topics/manifest/uses-sdk-element). -In .NET 7+ Android apps, there are MSBuild properties to set these values. Using the MSBuild properties has other benefits. In most cases the `` element should be removed in favor of values in your project's `.csproj` file: +In .NET 8 Android apps, there are MSBuild properties to set these values. Using the MSBuild properties has other benefits. In most cases the `` element should be removed in favor of values in your project's `.csproj` file: ```xml - net7.0-android + net8.0-android 21 ``` -In this example, `net7.0-android` is shorthand for `net7.0-android33.0`. Future versions of .NET will track the latest Android version available at the time of the .NET release. +In this example, `net8.0-android` is shorthand for `net8.0-android34.0`. Future versions of .NET will track the latest Android version available at the time of the .NET release. -`TargetFramework` maps to `android:targetSdkVersion`. At build time, this value will automatically be included in the `` element for you. The benefit of using `TargetFramework` in this way is that you're given the matching C# binding for Android API 33 for `net7.0-android33.0`. Android releases independently of the .NET release cycle, so we have the flexibility to opt into `net7.0-android34.0` when a binding is available sometime after .NET 7's release. +`TargetFramework` maps to `android:targetSdkVersion`. At build time, this value will automatically be included in the `` element for you. The benefit of using `TargetFramework` in this way is that you're given the matching C# binding for Android API 34 for `net8.0-android34.0`. Android releases independently of the .NET release cycle, so we have the flexibility to opt into `net8.0-android35.0` when a binding is available for the next Android release. Similarly, `SupportedOSPlatformVersion` maps to `android:minSdkVersion`. At build time, this value will automatically be included in the `` element for you. Android APIs are decorated with the so that you get build warnings for calling APIs that are only available for some of the Android versions your app can run on: @@ -144,7 +144,7 @@ With `AndroidLinkMode=SdkOnly`, only BCL and SDK assemblies marked with `%(Trimm `$(RunAOTCompilation)` is the new MSBuild property for enabling Ahead-of-Time (AoT) compilation. This is the same property used for [Blazor WASM](/aspnet/core/blazor/host-and-deploy/webassembly/#ahead-of-time-aot-compilation). The `$(AotAssemblies)` property also enables AOT, in order to help with migration from Xamarin.Android projects to .NET Android projects. > [!TIP] -> You should migrate to the new `$(RunAOTCompilation)` property, because `$(AotAssemblies)` is deprecated in .NET 7. +> You should migrate to the new `$(RunAOTCompilation)` property, because `$(AotAssemblies)` is deprecated from .NET 7. Release builds default to the following AOT property values: diff --git a/docs/migration/apple-projects.md b/docs/migration/apple-projects.md index 2157ec1435..786daa2d87 100644 --- a/docs/migration/apple-projects.md +++ b/docs/migration/apple-projects.md @@ -6,12 +6,12 @@ ms.date: 02/15/2023 # Xamarin Apple project migration -A .NET 7 project for a .NET iOS app is similar to the following example: +A .NET 8 project for a .NET iOS app is similar to the following example: ```xml - net7.0-ios + net8.0-ios Exe enable true @@ -81,7 +81,7 @@ For more information about the `RuntimeIdentifier` property, see [RuntimeIdentif ### Convert to UseNativeHttpHandler -The following table shows how to convert the `HttpClientHandler` and `MtouchHttpClientHandler` properties to the `UseNativeHttpHandler` property when migrating a Xamarin Apple project to .NET 7+: +The following table shows how to convert the `HttpClientHandler` and `MtouchHttpClientHandler` properties to the `UseNativeHttpHandler` property when migrating a Xamarin Apple project to .NET 8: | Value | UseNativeHttpHandler | | ------------------ | ------------------ | @@ -103,7 +103,7 @@ Some values have moved from *Info.plist* to the project file. ### MinimumOSVersion and LSMinimumSystemVersion -The `MinimumOSVersion` and `LSMinimumSystemVersion` properties should be converted to the `SupportedOSPlatformVersion` property in .NET 7+ projects. For more information, see [Ensure MinimumOSVersion is consistent with SupportedOSPlatformVersion](https://github.com/xamarin/xamarin-macios/issues/12336). +The `MinimumOSVersion` and `LSMinimumSystemVersion` properties should be converted to the `SupportedOSPlatformVersion` property in .NET 8 projects. For more information, see [Ensure MinimumOSVersion is consistent with SupportedOSPlatformVersion](https://github.com/xamarin/xamarin-macios/issues/12336). ## See also diff --git a/docs/migration/includes/api-changes.md b/docs/migration/includes/api-changes.md index 7a71b4d8d9..e9217e1fb1 100644 --- a/docs/migration/includes/api-changes.md +++ b/docs/migration/includes/api-changes.md @@ -37,6 +37,8 @@ In addition, all of the numeric values in a [!div class="mx-tdBreakAll"] > | Xamarin.Forms API | .NET MAUI API | Comments | > | ----------------- | ------------- | -------- | @@ -46,6 +48,20 @@ The following table lists the layout APIs that have been removed in the move fro > | | | No .NET MAUI equivalent. | > | | | In .NET MAUI, `RelativeLayout` only exists as a compatibility control for users migrating from Xamarin.Forms. Use instead, or add the `xmlns` for the compatibility namespace. | +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +> [!div class="mx-tdBreakAll"] +> | Xamarin.Forms API | .NET MAUI API | Comments | +> | ----------------- | ------------- | -------- | +> | | | The `Add` overload that accepts 3 arguments isn't present in .NET MAUI. | +> | | | No .NET MAUI equivalent. | +> | | | No .NET MAUI equivalent. | +> | | | In .NET MAUI, `RelativeLayout` only exists as a compatibility control for users migrating from Xamarin.Forms. Use instead, or add the `xmlns` for the compatibility namespace. | + +::: moniker-end + In addition, adding children to a layout in code in Xamarin.Forms is accomplished by adding the children to the layout's `Children` collection: ```csharp diff --git a/docs/migration/includes/update-app-dependencies.md b/docs/migration/includes/update-app-dependencies.md index 0156fb5c14..677aff4d4c 100644 --- a/docs/migration/includes/update-app-dependencies.md +++ b/docs/migration/includes/update-app-dependencies.md @@ -5,25 +5,25 @@ ms.date: 08/30/2023 ## Update app dependencies -Generally, Xamarin.Forms NuGet packages are not compatible with .NET 7+ unless they have been recompiled using .NET target framework monikers (TFMs). However, Android apps can use NuGet packages targeting the `monoandroid` and `monoandroidXX.X` frameworks. +Generally, Xamarin.Forms NuGet packages are not compatible with .NET 8 unless they have been recompiled using .NET target framework monikers (TFMs). However, Android apps can use NuGet packages targeting the `monoandroid` and `monoandroidXX.X` frameworks. -You can confirm a package is .NET 7+ compatible by looking at the **Frameworks** tab on [NuGet](https://nuget.org) for the package you're using, and checking that it lists one of the compatible frameworks shown in the following table: +You can confirm a package is .NET 8 compatible by looking at the **Frameworks** tab on [NuGet](https://nuget.org) for the package you're using, and checking that it lists one of the compatible frameworks shown in the following table: | Compatible frameworks | Incompatible frameworks | | --- | --- | -| net7.0-android, monoandroid, monoandroidXX.X | | -| net7.0-ios | monotouch, xamarinios, xamarinios10 | -| net7.0-macos | monomac, xamarinmac, xamarinmac20 | -| net7.0-tvos | xamarintvos | +| net8.0-android, monoandroid, monoandroidXX.X | | +| net8.0-ios | monotouch, xamarinios, xamarinios10 | +| net8.0-macos | monomac, xamarinmac, xamarinmac20 | +| net8.0-tvos | xamarintvos | | | xamarinwatchos | > [!NOTE] -> .NET Standard libraries that have no dependencies on the incompatible frameworks listed above are still compatible with .NET 7+. +> .NET Standard libraries that have no dependencies on the incompatible frameworks listed above are still compatible with .NET 8. If a package on [NuGet](https://nuget.org) indicates compatibility with any of the compatible frameworks above, regardless of also including incompatible frameworks, then the package is compatible. Compatible NuGet packages can be added to your .NET MAUI library project using the NuGet package manager in Visual Studio. -If you can't find a .NET 7+ compatible version of a NuGet package you should: +If you can't find a .NET 8 compatible version of a NuGet package you should: - Recompile the package with .NET TFMs, if you own the code. -- Look for a preview release of a .NET 7+ version of the package. -- Replace the dependency with a .NET 7+ compatible alternative. +- Look for a preview release of a .NET 8 version of the package. +- Replace the dependency with a .NET 8 compatible alternative. diff --git a/docs/migration/index.md b/docs/migration/index.md index 7d26c4ef86..4cda8e2773 100644 --- a/docs/migration/index.md +++ b/docs/migration/index.md @@ -1,6 +1,6 @@ --- title: "Upgrade from Xamarin to .NET" -description: "Learn how to upgrade Xamarin apps to .NET starting with .NET 7" +description: "Learn how to upgrade Xamarin apps to .NET." ms.date: 08/30/2023 --- @@ -33,7 +33,7 @@ Xamarin projects can run on .NET after completing an upgrade process. The follow > - Multi-project solutions **don't** need to become a multi-targeted single project. -To upgrade your Xamarin native projects to .NET, you'll first have to update the projects to be SDK-style projects and then update your dependencies to .NET 7+. For more information, see [Upgrade Xamarin.Android, Xamarin.iOS, and Xamarin.Mac apps to .NET](native-projects.md). +To upgrade your Xamarin native projects to .NET, you'll first have to update the projects to be SDK-style projects and then update your dependencies to .NET 8. For more information, see [Upgrade Xamarin.Android, Xamarin.iOS, and Xamarin.Mac apps to .NET](native-projects.md). The .NET Upgrade Assistant is a command-line tool that can help you upgrade multi-project Xamarin.Forms apps to multi-project .NET Multi-platform App UI (.NET MAUI) apps. After running the tool, in most cases the app will require additional effort to complete the upgrade. For more information, see [Upgrade a Xamarin.Forms app to a .NET MAUI app with the .NET Upgrade Assistant](upgrade-assistant.md). diff --git a/docs/migration/ios-binding-projects.md b/docs/migration/ios-binding-projects.md index 6e2a9b22dc..a719156a0f 100644 --- a/docs/migration/ios-binding-projects.md +++ b/docs/migration/ios-binding-projects.md @@ -17,7 +17,7 @@ To migrate a Xamarin.iOS binding library to a .NET iOS binding library: ```xml - net7.0-ios + net8.0-ios enable true true diff --git a/docs/migration/multi-project-to-multi-project.md b/docs/migration/multi-project-to-multi-project.md index 33b68512cb..edf1bcd62b 100644 --- a/docs/migration/multi-project-to-multi-project.md +++ b/docs/migration/multi-project-to-multi-project.md @@ -2,7 +2,7 @@ title: "Manually upgrade a Xamarin.Forms app to a multi-project .NET MAUI app" description: "Learn how to manually upgrade a Xamarin.Forms app to a multi-project .NET MAUI app." ms.date: 3/02/2023 -no-loc: [ "Xamarin.Forms", "Xamarin.Essentials", "Xamarin.CommunityToolkit", ".NET MAUI Community Toolkit", "SkiaSharp", "Xamarin.Forms.Maps", "Microsoft.Maui", "Microsoft.Maui.Controls", "net7.0-android", "net7.0-ios" ] +no-loc: [ "Xamarin.Forms", "Xamarin.Essentials", "Xamarin.CommunityToolkit", ".NET MAUI Community Toolkit", "SkiaSharp", "Xamarin.Forms.Maps", "Microsoft.Maui", "Microsoft.Maui.Controls", "net8.0-android", "net8.0-ios" ] --- # Manually upgrade a Xamarin.Forms app to a multi-project .NET MAUI app @@ -22,7 +22,7 @@ To migrate a Xamarin.Forms library project to a .NET MAUI library project, you m > - Update namespaces. > - Address any API changes. > - Configure .NET MAUI. -> - Upgrade or replace incompatible dependencies with .NET 7+ versions. +> - Upgrade or replace incompatible dependencies with .NET 8 versions. > - Compile and test your app. To simplify the upgrade process, you should create a new .NET MAUI library project of the same name as your Xamarin.Forms library project, and then copy in your code. This is the approach outlined below. @@ -41,10 +41,10 @@ In Visual Studio, create a new .NET MAUI class library project of the same name - net7.0;net7.0-android;net7.0-ios;net7.0-maccatalyst - $(TargetFrameworks);net7.0-windows10.0.19041.0 + net8.0;net8.0-android;net8.0-ios;net8.0-maccatalyst + $(TargetFrameworks);net8.0-windows10.0.19041.0 - + true true enable diff --git a/docs/migration/multi-project-to-single-project.md b/docs/migration/multi-project-to-single-project.md index 367d4dc393..22ca141c30 100644 --- a/docs/migration/multi-project-to-single-project.md +++ b/docs/migration/multi-project-to-single-project.md @@ -2,7 +2,7 @@ title: "Manually upgrade a Xamarin.Forms app to a single project .NET MAUI app" description: "Learn how to manually upgrade a Xamarin.Forms app to a single project .NET MAUI app." ms.date: 08/29/2023 -no-loc: [ "Xamarin.Forms", "Xamarin.Essentials", "Xamarin.CommunityToolkit", ".NET MAUI Community Toolkit", "SkiaSharp", "Xamarin.Forms.Maps", "Microsoft.Maui", "Microsoft.Maui.Controls", "net7.0-android", "net7.0-ios" ] +no-loc: [ "Xamarin.Forms", "Xamarin.Essentials", "Xamarin.CommunityToolkit", ".NET MAUI Community Toolkit", "SkiaSharp", "Xamarin.Forms.Maps", "Microsoft.Maui", "Microsoft.Maui.Controls", "net8.0-android", "net8.0-ios" ] --- # Manually upgrade a Xamarin.Forms app to a single project .NET MAUI app @@ -19,7 +19,7 @@ To migrate a Xamarin.Forms app to a single project .NET Multi-platform App UI (. > - Copy resources from your Xamarin.Forms app to the .NET MAUI app. > - Update namespaces. > - Address any API changes. -> - Upgrade or replace incompatible dependencies with .NET 7+ versions. +> - Upgrade or replace incompatible dependencies with .NET 8 versions. > - Compile and test your app. To simplify the upgrade process, you should create a new .NET MAUI app of the same name as your Xamarin.Forms app, and then copy in your code, configuration, and resources. This is the approach outlined below. diff --git a/docs/migration/native-essentials.md b/docs/migration/native-essentials.md index 0c25500f06..76647f770a 100644 --- a/docs/migration/native-essentials.md +++ b/docs/migration/native-essentials.md @@ -28,7 +28,7 @@ To use .NET MAUIs native device functionality in a .NET Android or .NET iOS app, ```xml - net7.0-android + net8.0-android ... true @@ -42,7 +42,7 @@ To use .NET MAUIs native device functionality in a .NET Android or .NET iOS app, ```xml - net7.0-ios + net8.0-ios ... true diff --git a/docs/migration/native-projects.md b/docs/migration/native-projects.md index f50856ba5f..0dd64bc146 100644 --- a/docs/migration/native-projects.md +++ b/docs/migration/native-projects.md @@ -11,7 +11,7 @@ To upgrade your Xamarin native projects to .NET, you must: > [!div class="checklist"] > > - Update your project file to be SDK-style. -> - Update or replace incompatible dependencies with .NET 7+ versions. +> - Update or replace incompatible dependencies with .NET 8 versions. > - Compile and test your app. For most apps, you won't need to change namespaces or undertake other rewrites. @@ -29,7 +29,7 @@ The new project should be given the same project and package name as your existi ```xml - net7.0-android + net8.0-android 21 Exe enable @@ -42,7 +42,7 @@ The new project should be given the same project and package name as your existi ``` > [!IMPORTANT] -> The target framework moniker (TFM) is what denotes the project as using .NET, in this case .NET 7. Valid TFMs for equivalent Xamarin native projects are net7.0-android, net7.0-ios, net7.0-macos, net7.0-tvos. +> The target framework moniker (TFM) is what denotes the project as using .NET, in this case .NET 8. Valid TFMs for equivalent Xamarin native projects are net8.0-android, net8.0-ios, net8.0-macos, net8.0-tvos. Launch the app to confirm that your development environment can build the app. @@ -56,28 +56,28 @@ You'll also need to copy some project properties from your Xamarin native projec ## Update dependencies -Generally, Xamarin native NuGet packages are not compatible with .NET 7+ unless they have been recompiled using .NET TFMs. However, .NET Android apps can use NuGet packages targeting the `monoandroid` and `monoandroidXX.X` frameworks. +Generally, Xamarin native NuGet packages are not compatible with .NET 8 unless they have been recompiled using .NET TFMs. However, .NET Android apps can use NuGet packages targeting the `monoandroid` and `monoandroidXX.X` frameworks. -You can confirm a package is .NET 7+ compatible by looking at the **Frameworks** tab on [NuGet](https://nuget.org) for the package you're using, and checking that it lists one of the compatible frameworks shown in the following table: +You can confirm a package is .NET 8 compatible by looking at the **Frameworks** tab on [NuGet](https://nuget.org) for the package you're using, and checking that it lists one of the compatible frameworks shown in the following table: | Compatible frameworks | Incompatible frameworks | | --- | --- | -| net7.0-android, monoandroid, monoandroidXX.X | | -| net7.0-ios | monotouch, xamarinios, xamarinios10 | -| net7.0-macos | monomac, xamarinmac, xamarinmac20 | -| net7.0-tvos | xamarintvos | +| net8.0-android, monoandroid, monoandroidXX.X | | +| net8.0-ios | monotouch, xamarinios, xamarinios10 | +| net8.0-macos | monomac, xamarinmac, xamarinmac20 | +| net8.0-tvos | xamarintvos | | | xamarinwatchos | > [!NOTE] -> .NET Standard libraries that have no dependencies on the incompatible frameworks listed above are still compatible with .NET 7+. +> .NET Standard libraries that have no dependencies on the incompatible frameworks listed above are still compatible with .NET 8. If a package on [NuGet](https://nuget.org) indicates compatibility with any of the compatible frameworks above, regardless of also including incompatible frameworks, then the package is compatible. Compatible NuGet packages can be added to your .NET native project using the NuGet package manager in Visual Studio. -If you can't find a .NET 7+ compatible version of a NuGet package you should: +If you can't find a .NET 8 compatible version of a NuGet package you should: - Recompile the package with .NET TFMs, if you own the code. -- Look for a preview release of a .NET 7+ version of the package. -- Replace the dependency with a .NET 7+ compatible alternative. +- Look for a preview release of a .NET 8 version of the package. +- Replace the dependency with a .NET 8 compatible alternative. For information about migrating Xamarin.Essentials code in a .NET Android or .NET iOS app, see [Migrate Xamarin.Essentials code in .NET Android and .NET iOS apps](native-essentials.md). diff --git a/docs/migration/renderer-to-handler.md b/docs/migration/renderer-to-handler.md index 6681674bb1..184ec1985e 100644 --- a/docs/migration/renderer-to-handler.md +++ b/docs/migration/renderer-to-handler.md @@ -126,13 +126,13 @@ Filename-based multi-targeting is configured by adding the following XML to the ```xml - + - + diff --git a/docs/migration/upgrade-assistant.md b/docs/migration/upgrade-assistant.md index a0a7d74b79..74c50204d9 100644 --- a/docs/migration/upgrade-assistant.md +++ b/docs/migration/upgrade-assistant.md @@ -2,7 +2,7 @@ title: "Upgrade a Xamarin.Forms app to a .NET MAUI app with the .NET Upgrade Assistant" description: "Learn how to use .NET Upgrade Assistant to migrate a Xamarin.Forms app to a multi-project .NET MAUI app." ms.date: 08/21/2023 -no-loc: [ "Xamarin.Forms", "Xamarin.Essentials", "Xamarin.CommunityToolkit", ".NET MAUI Community Toolkit", "SkiaSharp", "Xamarin.Forms.Maps", "Microsoft.Maui", "Microsoft.Maui.Controls", "net7.0-android", "net7.0-ios" ] +no-loc: [ "Xamarin.Forms", "Xamarin.Essentials", "Xamarin.CommunityToolkit", ".NET MAUI Community Toolkit", "SkiaSharp", "Xamarin.Forms.Maps", "Microsoft.Maui", "Microsoft.Maui.Controls", "net8.0-android", "net8.0-ios" ] --- # Upgrade a Xamarin.Forms app to a .NET MAUI app with the .NET Upgrade Assistant @@ -10,7 +10,7 @@ no-loc: [ "Xamarin.Forms", "Xamarin.Essentials", "Xamarin.CommunityToolkit", ".N The .NET Upgrade Assistant helps you upgrade Xamarin.Forms projects to .NET Multi-platform App UI (.NET MAUI) by converting the solution's project file and by performing common code updates. Specifically, the tool will: - Convert the Xamarin.Forms class library project, Xamarin.iOS project, and Xamarin.Android project to SDK-style projects. -- Update the target framework in project files to net7.0-android and net7.0-ios, as required. +- Update the target framework in project files to net8.0-android and net8.0-ios, as required. - Set `true` in project files. - Add additional project properties, and remove project properties that aren't required. - Add and remove specific NuGet packages: diff --git a/docs/platform-integration/appmodel/permissions.md b/docs/platform-integration/appmodel/permissions.md index f2ca85cd81..8dd751fe32 100644 --- a/docs/platform-integration/appmodel/permissions.md +++ b/docs/platform-integration/appmodel/permissions.md @@ -1,7 +1,7 @@ --- title: "Permissions" description: "Learn how to use the .NET MAUI Permissions class, to check and request permissions. This class is in the Microsoft.Maui.ApplicationModel namespace." -ms.date: 02/02/2023 +ms.date: 10/19/2023 no-loc: ["Microsoft.Maui", "Microsoft.Maui.ApplicationModel"] --- @@ -15,8 +15,41 @@ This article describes how you can use the .NET Multi-platform App UI (.NET MAUI The following table uses ✔️ to indicate that the permission is supported and ❌ to indicate the permission isn't supported or isn't required: +::: moniker range="=net-maui-7.0" + +| Permission | Android | iOS | Windows | tvOS | +|------------------------------------------------------------------------------------------|:-------:|:---:|:-------:|:----:| +| [Battery](xref:Microsoft.Maui.ApplicationModel.Permissions.Battery) | ✔️ | ❌ | ❌ | ❌ | +| [CalendarRead](xref:Microsoft.Maui.ApplicationModel.Permissions.CalendarRead) | ✔️ | ✔️ | ❌ | ❌ | +| [CalendarWrite](xref:Microsoft.Maui.ApplicationModel.Permissions.CalendarWrite) | ✔️ | ✔️ | ❌ | ❌ | +| [Camera](xref:Microsoft.Maui.ApplicationModel.Permissions.Camera) | ✔️ | ✔️ | ❌ | ❌ | +| [ContactsRead](xref:Microsoft.Maui.ApplicationModel.Permissions.ContactsRead) | ✔️ | ✔️ | ❌ | ❌ | +| [ContactsWrite](xref:Microsoft.Maui.ApplicationModel.Permissions.ContactsWrite) | ✔️ | ✔️ | ❌ | ❌ | +| [Flashlight](xref:Microsoft.Maui.ApplicationModel.Permissions.Flashlight) | ✔️ | ❌ | ❌ | ❌ | +| [LocationWhenInUse](xref:Microsoft.Maui.ApplicationModel.Permissions.LocationWhenInUse) | ✔️ | ✔️ | ❌ | ✔️ | +| [LocationAlways](xref:Microsoft.Maui.ApplicationModel.Permissions.LocationAlways) | ✔️ | ✔️ | ❌ | ❌ | +| [Media](xref:Microsoft.Maui.ApplicationModel.Permissions.Media) | ❌ | ✔️ | ❌ | ❌ | +| [Microphone](xref:Microsoft.Maui.ApplicationModel.Permissions.Microphone) | ✔️ | ✔️ | ❌ | ❌ | +| [NetworkState](xref:Microsoft.Maui.ApplicationModel.Permissions.NetworkState) | ✔️ | ❌ | ❌ | ❌ | +| [Phone](xref:Microsoft.Maui.ApplicationModel.Permissions.Phone) | ✔️ | ✔️ | ❌ | ❌ | +| [Photos](xref:Microsoft.Maui.ApplicationModel.Permissions.Photos) | ❌ | ✔️ | ❌ | ✔️ | +| [PhotosAddOnly](xref:Microsoft.Maui.ApplicationModel.Permissions.PhotosAddOnly) | ❌ | ✔️ | ❌ | ✔️ | +| [Reminders](xref:Microsoft.Maui.ApplicationModel.Permissions.Reminders) | ❌ | ✔️ | ❌ | ❌ | +| [Sensors](xref:Microsoft.Maui.ApplicationModel.Permissions.Sensors) | ✔️ | ✔️ | ❌ | ❌ | +| [Sms](xref:Microsoft.Maui.ApplicationModel.Permissions.Sms) | ✔️ | ✔️ | ❌ | ❌ | +| [Speech](xref:Microsoft.Maui.ApplicationModel.Permissions.Speech) | ✔️ | ✔️ | ❌ | ❌ | +| [StorageRead](xref:Microsoft.Maui.ApplicationModel.Permissions.StorageRead) | ✔️ | ❌ | ❌ | ❌ | +| [StorageWrite](xref:Microsoft.Maui.ApplicationModel.Permissions.StorageWrite) | ✔️ | ❌ | ❌ | ❌ | +| [Vibrate](xref:Microsoft.Maui.ApplicationModel.Permissions.Vibrate) | ✔️ | ❌ | ❌ | ❌ | + +::: moniker-end + +::: moniker range=">=net-maui-8.0" + | Permission | Android | iOS | Windows | tvOS | |------------------------------------------------------------------------------------------|:-------:|:---:|:-------:|:----:| +| [Battery](xref:Microsoft.Maui.ApplicationModel.Permissions.Battery) | ✔️ | ❌ | ❌ | ❌ | +| Bluetooth | ✔️ | ❌ | ❌ | ❌ | | [CalendarRead](xref:Microsoft.Maui.ApplicationModel.Permissions.CalendarRead) | ✔️ | ✔️ | ❌ | ❌ | | [CalendarWrite](xref:Microsoft.Maui.ApplicationModel.Permissions.CalendarWrite) | ✔️ | ✔️ | ❌ | ❌ | | [Camera](xref:Microsoft.Maui.ApplicationModel.Permissions.Camera) | ✔️ | ✔️ | ❌ | ❌ | @@ -27,14 +60,20 @@ The following table uses ✔️ to indicate that the permission is supported and | [LocationAlways](xref:Microsoft.Maui.ApplicationModel.Permissions.LocationAlways) | ✔️ | ✔️ | ❌ | ❌ | | [Media](xref:Microsoft.Maui.ApplicationModel.Permissions.Media) | ❌ | ✔️ | ❌ | ❌ | | [Microphone](xref:Microsoft.Maui.ApplicationModel.Permissions.Microphone) | ✔️ | ✔️ | ❌ | ❌ | +| NearbyWifiDevices | ✔️ | ❌ | ❌ | ❌ | +| [NetworkState](xref:Microsoft.Maui.ApplicationModel.Permissions.NetworkState) | ✔️ | ❌ | ❌ | ❌ | | [Phone](xref:Microsoft.Maui.ApplicationModel.Permissions.Phone) | ✔️ | ✔️ | ❌ | ❌ | -| [Photos](xref:Microsoft.Maui.ApplicationModel.Permissions.Photos) | ❌ | ✔️ | ❌ | ✔️ | +| [Photos](xref:Microsoft.Maui.ApplicationModel.Permissions.Photos) | ❌ | ✔️ | ❌ | ✔️ | +| [PhotosAddOnly](xref:Microsoft.Maui.ApplicationModel.Permissions.PhotosAddOnly) | ❌ | ✔️ | ❌ | ✔️ | | [Reminders](xref:Microsoft.Maui.ApplicationModel.Permissions.Reminders) | ❌ | ✔️ | ❌ | ❌ | | [Sensors](xref:Microsoft.Maui.ApplicationModel.Permissions.Sensors) | ✔️ | ✔️ | ❌ | ❌ | | [Sms](xref:Microsoft.Maui.ApplicationModel.Permissions.Sms) | ✔️ | ✔️ | ❌ | ❌ | | [Speech](xref:Microsoft.Maui.ApplicationModel.Permissions.Speech) | ✔️ | ✔️ | ❌ | ❌ | | [StorageRead](xref:Microsoft.Maui.ApplicationModel.Permissions.StorageRead) | ✔️ | ❌ | ❌ | ❌ | | [StorageWrite](xref:Microsoft.Maui.ApplicationModel.Permissions.StorageWrite) | ✔️ | ❌ | ❌ | ❌ | +| [Vibrate](xref:Microsoft.Maui.ApplicationModel.Permissions.Vibrate) | ✔️ | ❌ | ❌ | ❌ | + +::: moniker-end If a permission is marked as ❌, it will always return when checked or requested. diff --git a/docs/platform-integration/configure-multi-targeting.md b/docs/platform-integration/configure-multi-targeting.md index 20d9e76556..888fd27fad 100644 --- a/docs/platform-integration/configure-multi-targeting.md +++ b/docs/platform-integration/configure-multi-targeting.md @@ -22,25 +22,25 @@ A standard multi-targeting pattern is to include the platform as an extension in ```xml - + - + - + - + @@ -69,25 +69,25 @@ Another standard multi-targeting pattern is to include the platform as a folder ```xml - + - + - + - + @@ -116,7 +116,7 @@ Filename-based multi-targeting can be combined with folder-based multi-targeting ```xml - + @@ -124,7 +124,7 @@ Filename-based multi-targeting can be combined with folder-based multi-targeting - + @@ -132,7 +132,7 @@ Filename-based multi-targeting can be combined with folder-based multi-targeting - + @@ -140,7 +140,7 @@ Filename-based multi-targeting can be combined with folder-based multi-targeting - + diff --git a/docs/platform-integration/customize-ui-appearance.md b/docs/platform-integration/customize-ui-appearance.md index a5fc04eec6..927d83c249 100644 --- a/docs/platform-integration/customize-ui-appearance.md +++ b/docs/platform-integration/customize-ui-appearance.md @@ -25,14 +25,14 @@ The [`OnPlatform`](xref:Microsoft.Maui.Controls.Xaml.OnPlatformExtension) markup The [`OnPlatform`](xref:Microsoft.Maui.Controls.Xaml.OnPlatformExtension) markup extension is supported by the class, which defines the following properties: -- `Default` (of type `object`) that you set to a default value to be applied to the properties that represent platforms. -- `Android` (of type `object`) that you set to a value to be applied on Android. -- `iOS` (of type `object`) that you set to a value to be applied on iOS. -- `MacCatalyst` (of type `object`) that you set to a value to be applied on Mac Catalyst. -- `Tizen` (of type `object`) that you set to a value to be applied on the Tizen platform. -- `WinUI` (of type `object`) that you set to a value to be applied on WinUI. -- `Converter` of type , that can be set to an implementation. -- `ConverterParameter` (of type `object`) that can be set to a value to pass to the implementation. +- `Default`, of type `object`, that you set to a default value to be applied to the properties that represent platforms. +- `Android`, of type `object`, that you set to a value to be applied on Android. +- `iOS`, of type `object`, that you set to a value to be applied on iOS. +- `MacCatalyst`, of type `object`, that you set to a value to be applied on Mac Catalyst. +- `Tizen`, of type `object`, that you set to a value to be applied on the Tizen platform. +- `WinUI`, of type `object`, that you set to a value to be applied on WinUI. +- `Converter`, of type , that can be set to an implementation. +- `ConverterParameter`, of type `object`, that can be set to a value to pass to the implementation. > [!NOTE] > The XAML parser allows the class to be abbreviated as `OnPlatform`. @@ -57,14 +57,14 @@ In this example, all three [`OnPlatform`](xref:Microsoft.Maui.Controls.Xaml.OnPl The [`OnIdiom`](xref:Microsoft.Maui.Controls.Xaml.OnIdiomExtension) markup extension enables you to customize UI appearance based on the idiom of the device the app is running on. It's supported by the class, which defines the following properties: -- `Default` (of type `object`) that you set to a default value to be applied to the properties that represent device idioms. -- `Phone` (of type `object`) that you set to a value to be applied on phones. -- `Tablet` (of type `object`) that you set to a value to be applied on tablets. -- `Desktop` (of type `object`) that you set to a value to be applied on desktop platforms. -- `TV` (of type `object`) that you set to a value to be applied on TV platforms. -- `Watch` (of type `object`) that you set to a value to be applied on Watch platforms. -- `Converter` (of type ) that can be set to an implementation. -- `ConverterParameter` (of type `object`) that can be set to a value to pass to the implementation. +- `Default`, of type `object`, that you set to a default value to be applied to the properties that represent device idioms. +- `Phone`, of type `object`, that you set to a value to be applied on phones. +- `Tablet`, of type `object`, that you set to a value to be applied on tablets. +- `Desktop`, of type `object`, that you set to a value to be applied on desktop platforms. +- `TV`, of type `object`, that you set to a value to be applied on TV platforms. +- `Watch`, of type `object`, that you set to a value to be applied on Watch platforms. +- `Converter`, of type , that can be set to an implementation. +- `ConverterParameter`, of type `object`, that can be set to a value to pass to the implementation. > [!NOTE] > The XAML parser allows the class to be abbreviated as `OnIdiom`. diff --git a/docs/platform-integration/device/flashlight.md b/docs/platform-integration/device/flashlight.md index e13c7eb71e..2500dad1ab 100644 --- a/docs/platform-integration/device/flashlight.md +++ b/docs/platform-integration/device/flashlight.md @@ -1,7 +1,7 @@ --- title: "Flashlight" description: "Learn how to use the .NET MAUI IFlashlight interface in the Microsoft.Maui.Devices namespace. This interface provides the ability to turn on or off the device's camera flash, to emulate a flashlight." -ms.date: 02/02/2023 +ms.date: 10/03/2023 no-loc: ["Microsoft.Maui", "Microsoft.Maui.Devices"] --- @@ -74,6 +74,12 @@ The flashlight can be turned on and off through the method. + +::: moniker-end + ## Platform differences This section describes the platform-specific differences with the flashlight. diff --git a/docs/platform-integration/device/geolocation.md b/docs/platform-integration/device/geolocation.md index 891e281665..ab099fad67 100644 --- a/docs/platform-integration/device/geolocation.md +++ b/docs/platform-integration/device/geolocation.md @@ -138,6 +138,69 @@ Not all location values may be available, depending on the device. For example, > [!WARNING] > can return `null` in some scenarios. This indicates that the underlying platform is unable to obtain the current location. +::: moniker range=">=net-maui-8.0" + +## Listen for location changes + +In addition to querying the device for the current location, you can listen for location changes while an app is in the foreground. + +To check to see if the app is currently listening for location changes, there's a `IsListeningForeground` property you can query. Once you're ready to start listening for location changes you should call the `StartListeningForegroundAsync` method. This method starts listening for location updates and raises the `LocationChanged` event when the location changes, provided that the app is in the foreground. The `GeolocationLocationChangedEventArgs` object that accompanies this event has a `Location` property, of type , that represents the new location that's been detected. + +> [!NOTE] +> When necessary, the Geolocation API prompts the user for permissions. + +The following code example demonstrates how to listen for a location change, and how to process the changed location: + +```csharp +async void OnStartListening() +{ + try + { + Geolocation.LocationChanged += Geolocation_LocationChanged; + var request = new GeolocationListeningRequest((GeolocationAccuracy)Accuracy); + var success = await Geolocation.StartListeningForegroundAsync(request); + + string status = success + ? "Started listening for foreground location updates" + : "Couldn't start listening"; + } + catch (Exception ex) + { + // Unable to start listening for location changes + } +} + +void Geolocation_LocationChanged(object sender, GeolocationLocationChangedEventArgs e) +{ + // Process e.Location to get the new location +} +``` + +Error handling can be implemented by registering an event handler for the `ListeningFailed` event. The `GeolocationListeningFailedEventArgs` object that accompanies this event has an `Error` property, of type `GeolocationError`, that indicates why listening failed. When the `ListeningFailed` event is raised, listening for further location changes stops and no further `LocationChanged` events are raised. + +To stop listening for location changes, call the `StopListeningForeground` method: + +```csharp +void OnStopListening() +{ + try + { + Geolocation.LocationChanged -= Geolocation_LocationChanged; + Geolocation.StopListeningForeground(); + string status = "Stopped listening for foreground location updates"; + } + catch (Exception ex) + { + // Unable to stop listening for location changes + } +} +``` + +> [!NOTE] +> The `StopListeningForeground` method has no effect when the app isn't listening for location changes. + +::: moniker-end + ## Accuracy The following sections outline the location accuracy distance, per platform: diff --git a/docs/platform-integration/device/sensors.md b/docs/platform-integration/device/sensors.md index 6098827e70..09198f0cb8 100644 --- a/docs/platform-integration/device/sensors.md +++ b/docs/platform-integration/device/sensors.md @@ -1,5 +1,5 @@ --- -title: Accessing device sensors overview +title: Accessing device sensors description: "Learn how to use and monitor sensors provided by your device, with .NET MAUI. You can monitor the following sensors: accelerometer, barometer, compass, shake, gyroscope, magnetometer, orientation." ms.topic: overview ms.date: 02/02/2023 @@ -16,7 +16,7 @@ Device sensor-related types are available in the `Microsoft.Maui.Devices.Sensors ## Sensor speed -Sensor speed sets the speed in which a sensor will return data to your app. When you start a sensor, you provide the desired sensor speed with the enumeration. +Sensor speed sets the speed in which a sensor will return data to your app. When you start a sensor, you provide the desired sensor speed with the enumeration: - \ Get the sensor data as fast as possible (not guaranteed to return on UI thread). @@ -24,15 +24,26 @@ Get the sensor data as fast as possible (not guaranteed to return on UI thread). - \ Rate suitable for games (not guaranteed to return on UI thread). -- \ -Default rate suitable for screen orientation changes. - - \ Rate suitable for general user interface. +- \ +Default rate suitable for screen orientation changes. + > [!WARNING] > Monitoring too many sensors at once may affect the rate sensor data is returned to your app. +::: moniker range=">=net-maui-8.0" + +In .NET 8, intervals are identical across all platforms: + +- uses an interval of 200ms. +- uses an interval of 60ms. +- uses an interval of 20ms. +- uses an interval of 5ms. + +::: moniker-end + ### Sensor event handlers Event handlers added to sensors with either the or speeds **aren't** guaranteed to run on the UI thread. If the event handler needs to access user-interface elements, use the [`MainThread.BeginInvokeOnMainThread`](../appmodel/main-thread.md) method to run that code on the UI thread. @@ -43,6 +54,14 @@ The accelerometer sensor measures the acceleration of the device along its three The interface provides access to the sensor, and is available through the property. Both the `IAccelerometer` interface and `Accelerometer` class are contained in the `Microsoft.Maui.Devices.Sensors` namespace. +### Get started + +To access the accelerometer functionality the following platform-specific setup maybe required: + +[!INCLUDE [Android sensor high sampling rate](../includes/android-sensors.md)] + +### Monitor the accelerometer sensor + To start monitoring the accelerometer sensor, call the method. .NET MAUI sends accelerometer data changes to your app by raising the event. Use the method to stop monitoring the sensor. You can detect the monitoring state of the accelerometer with the property, which will be `true` if the accelerometer was started and is currently being monitored. The following code example demonstrates monitoring the accelerometer for changes: @@ -159,6 +178,9 @@ Even though this article is listing **shake** as a sensor, it isn't. The [accele The interface provides access to the sensor, and is available through the property. Both the `IAccelerometer` interface and `Accelerometer` class are contained in the `Microsoft.Maui.Devices.Sensors` namespace. +> [!NOTE] +> If your app needs to gather accelerometer sensor data using the sensor speed, you must declare the `HIGH_SAMPLING_RATE_SENSORS` permission. For more information, see [Accelerometer](#accelerometer). + The detect shake API uses raw readings from the accelerometer to calculate acceleration. It uses a simple queue mechanism to detect if 3/4ths of the recent accelerometer events occurred in the last half second. Acceleration is calculated by adding the square of the X, Y, and Z ($x^2+y^2+z^2$) readings from the accelerometer and comparing it to a specific threshold. To start monitoring the accelerometer sensor, call the method. When a shake is detected, the event is raised. Use the method to stop monitoring the sensor. You can detect the monitoring state of the accelerometer with the `IAccelerometer.IsMonitoring` property, which will be `true` if the accelerometer was started and is currently being monitored. @@ -179,6 +201,14 @@ The gyroscope sensor measures the angular rotation speed around the device's thr The interface provides access to the sensor, and is available through the property. Both the `IGyroscope` interface and `Gyroscope` class are contained in the `Microsoft.Maui.Devices.Sensors` namespace. +### Get started + +To access the gyroscope functionality the following platform-specific setup maybe required: + +[!INCLUDE [Android sensor high sampling rate](../includes/android-sensors.md)] + +### Monitor the gyroscope sensor + To start monitoring the gyroscope sensor, call the method. .NET MAUI sends gyroscope data changes to your app by raising the event. The data provided by this event is measured in rad/s (radian per second). Use the method to stop monitoring the sensor. You can detect the monitoring state of the gyroscope with the property, which will be `true` if the gyroscope was started and is currently being monitored. The following code example demonstrates monitoring the gyroscope: @@ -195,6 +225,14 @@ The magnetometer sensor indicates the device's orientation relative to Earth's m The interface provides access to the sensor, and is available through the property. Both the `IMagnetometer` interface and `Magnetometer` class are contained in the `Microsoft.Maui.Devices.Sensors` namespace. +### Get started + +To access the magnetometer functionality the following platform-specific setup maybe required: + +[!INCLUDE [Android sensor high sampling rate](../includes/android-sensors.md)] + +### Monitor the magnetometer sensor + To start monitoring the magnetometer sensor, call the method. .NET MAUI sends magnetometer data changes to your app by raising the event. The data provided by this event is measured in $µT$ (microteslas). Use the method to stop monitoring the sensor. You can detect the monitoring state of the magnetometer with the property, which will be `true` if the magnetometer was started and is currently being monitored. The following code example demonstrates monitoring the magnetometer: diff --git a/docs/platform-integration/includes/android-sensors.md b/docs/platform-integration/includes/android-sensors.md new file mode 100644 index 0000000000..4795ad9d11 --- /dev/null +++ b/docs/platform-integration/includes/android-sensors.md @@ -0,0 +1,49 @@ +--- +ms.topic: include +ms.date: 11/08/2023 +--- + + +# [Android](#tab/android) + +If your app targets Android 12+ (API 31+), the system places a 200 Hz limit on the refresh rate of data from this sensor. If your app needs to gather sensor data using the sensor speed, you must declare the `HIGH_SAMPLING_RATE_SENSORS` permission. You can configure the permission in the following ways: + +- Add the assembly-based permission: + + Open the _Platforms/Android/MainApplication.cs_ file and add the following assembly attribute after `using` directives: + + ```csharp + [assembly: UsesPermission(Android.Manifest.Permission.HighSamplingRateSensors)] + ``` + + \- or - + +- Update the Android Manifest: + + Open the _Platforms/Android/AndroidManifest.xml_ file and add the following line in the `manifest` node: + + ```xml + + ``` + + + +> [!NOTE] +> If a user turns off microphone access using the [device toggles](https://developer.android.com/training/permissions/explaining-access#toggles), motion and position sensors are always rate-limited, regardless of whether you declare the `HIGH_SAMPLING_RATE_SENSORS` permission. + +# [iOS/Mac Catalyst](#tab/macios) + +No setup is required. + +# [Windows](#tab/windows) + +No setup is required. + +----- + diff --git a/docs/platform-integration/native-embedding.md b/docs/platform-integration/native-embedding.md index 5a67864ed3..510b9aee82 100644 --- a/docs/platform-integration/native-embedding.md +++ b/docs/platform-integration/native-embedding.md @@ -88,6 +88,9 @@ public class MainActivity : AppCompatActivity } ``` +> [!NOTE] +> The call to the method can specify your own derived class, such as `MyApp`. For example, `builder.UseMauiEmbedding();`. + ### iOS and Mac Catalyst On iOS and Mac Catalyst, the `FinishedLaunching` override in the `AppDelegate` class is typically the place to perform app startup related tasks. It's called after the app has launched, and is usually overridden to configure the main window and view controller. The following code example shows .NET MAUI being initialized in the `AppDelegate` class: @@ -127,6 +130,9 @@ public class AppDelegate : UIApplicationDelegate } ``` +> [!NOTE] +> The call to the method can specify your own derived class, such as `MyApp`. For example, `builder.UseMauiEmbedding();`. + ### Windows On Windows apps built using WinUI, .NET MAUI can typically be initialized in the native `App` class, `Window` class, or a class. The following code example shows .NET MAUI being initialized in a class: @@ -155,6 +161,9 @@ public sealed partial class MainPage : Page } ``` +> [!NOTE] +> The call to the method can specify your own derived class, such as `MyApp`. For example, `builder.UseMauiEmbedding();`. + ## Consume .NET MAUI controls To consume .NET MAUI types that derive from in native apps, create an instance of the control and convert it to the appropriate native type with the `ToPlatform` extension method. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 19e5fd9d1d..5bfe384907 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -1,7 +1,7 @@ --- title: "Troubleshoot known issues" description: "Learn about .NET MAUI known issues and troubleshooting you can do to resolve these issues." -ms.date: 03/08/2023 +ms.date: 10/02/2023 --- # Troubleshooting known issues @@ -136,22 +136,10 @@ Use a `global.json` config file in the folder where you'll create the project. T Visual Studio may not be resolving the required workloads if you try to compile a project and receive an error similar to the following text: -> Platform version is not present for one or more target frameworks, even though they have specified a platform: net7.0-android, net7.0-ios, net7.0-maccatalyst +> Platform version is not present for one or more target frameworks, even though they have specified a platform: net8.0-android, net8.0-ios, net8.0-maccatalyst This problem typically results from having an x86 and x64 SDK installed, and the x86 version is being used. Visual Studio and .NET MAUI require the x64 .NET SDK. If your operating system has a system-wide `PATH` variable that is resolving the x86 SDK first, you need to fix that by either removing the x86 .NET SDK from the `PATH` variable, or promoting the x64 .NET SDK so that it resolves first. For more information on troubleshooting x86 vs x64 SDK resolution, see [Install .NET on Windows - Troubleshooting](/dotnet/core/install/windows#it-was-not-possible-to-find-any-installed-net-core-sdks). - - ## Type or namespace 'Default' doesn't exist When using the [`Contacts` API](platform-integration/communication/contacts.md), you may see the following error related to iOS and macOS: @@ -182,3 +170,82 @@ If you receive the error "Could not find a valid Xcode app bundle at '/Library/D ```zsh sudo xcode-select --reset ``` + +::: moniker range=">=net-maui-8.0" + +## Diagnose issues in Blazor Hybrid apps + + has built-in logging that can help you diagnose problems in your Blazor Hybrid app. There are two steps to enable this logging: + +1. Enable and related components to log diagnostic information. +1. Configure a logger to write the log output to where you can view it. + +For more information, see [Diagnosing issues in Blazor Hybrid apps](~/user-interface/controls/blazorwebview.md#diagnosing-issues). + +## Disable image packaging + +For troubleshooting purposes, image resource packaging can be disabled by setting the `$(EnableMauiImageProcessing)` build property to `false` in the first `` node in your project file: + +```xml +false +``` + +## Disable splash screen packaging + +For troubleshooting purposes, splash screen resource generation can be disabled by setting the `$(EnableSplashScreenProcessing)` build property to `false` in the first `` node in your project file: + +```xml +false +``` + +## Disable font packaging + +For troubleshooting purposes, font resource packaging can be disabled by setting the `$(EnableMauiFontProcessing)` build property to `false` in the first `` node in your project file: + +```xml +false +``` + +## Disable asset file packaging + +For troubleshooting purposes, asset file resource packaging can be disabled by setting the `$(EnableMauiAssetProcessing)` build property to `false` in the first `` node in your project file: + +```xml +false +``` + +## Generate a blank splash screen + +For troubleshooting purposes, a blank splash screen can be generated if you don't have a `` item and you don't have a custom splash screen. This can be achieved by setting the `$(EnableBlankMauiSplashScreen)` build property to `true` in the first `` node in your project file: + +```xml +true +``` + +Generating a blank splash screen will override any custom splash screen and will cause app store rejection. However, it can be a useful approach in testing to ensure that your app UI is correct. + +## Duplicate image filename errors + +You may encounter build errors about duplicate image filenames: + +> One or more duplicate file names were detected. All image output filenames must be unique. + +This can occur for `MauiIcon` and `MauiImage` items. For example, the following `MauiImage` items in an `` node in your project file will result in this error: + +```xml + + +``` + +This occurs because from .NET 8, .NET MAUI checks to ensure that there are no duplicate image resource filenames. + +If you receive this build error it can be fixed by ensuring that your project file doesn't include duplicate images. To do this, change any `MauiIcon` or `MauiImage` that references a specific file to use the `Update` attribute instead of the `Include` attribute: + +```xml + + +``` + +For information about MSBuild item element attributes, see [Item element (MSBuild): Attributes and elements](/visualstudio/msbuild/item-element-msbuild#attributes-and-elements). + +::: moniker-end diff --git a/docs/user-interface/animation/basic.md b/docs/user-interface/animation/basic.md index 304d3a608a..13bd30b67a 100644 --- a/docs/user-interface/animation/basic.md +++ b/docs/user-interface/animation/basic.md @@ -31,6 +31,8 @@ The animation extension methods in the class implements a single animation operation that progressively changes a property from one value to another value over a period of time. diff --git a/docs/user-interface/animation/custom.md b/docs/user-interface/animation/custom.md index acc06feb5c..6fff1d7132 100644 --- a/docs/user-interface/animation/custom.md +++ b/docs/user-interface/animation/custom.md @@ -15,6 +15,8 @@ Running an animation created with the c > [!NOTE] > The class has an property that can be examined to determine if animations have been disabled by the operating system, such as when power saving mode is activated. +[!INCLUDE [Android animation system settings](../includes/animation-android.md)] + ## Create an animation When creating an object, typically, a minimum of three parameters are required, as demonstrated in the following code example: diff --git a/docs/user-interface/brushes/gradient.md b/docs/user-interface/brushes/gradient.md index c13a06bbe7..b4098e455c 100644 --- a/docs/user-interface/brushes/gradient.md +++ b/docs/user-interface/brushes/gradient.md @@ -18,7 +18,7 @@ Classes that derive from describe d The class defines the property, of type , which represents the brush's gradient stops, each of which specifies a color and an offset along the brush's gradient axis. A is an `ObservableCollection` of objects. The property is backed by a object, which means that it can be the target of data bindings, and styled. > [!NOTE] -> The property is the `ContentProperty` of the class, and so does not need to be explicitly set from XAML. +> The property is the [`ContentProperty`](xref:Microsoft.Maui.Controls.ContentPropertyAttribute) of the class, and so does not need to be explicitly set from XAML. ## Gradient stops diff --git a/docs/user-interface/brushes/solidcolor.md b/docs/user-interface/brushes/solidcolor.md index 270129758d..8d00eb01f8 100644 --- a/docs/user-interface/brushes/solidcolor.md +++ b/docs/user-interface/brushes/solidcolor.md @@ -10,8 +10,18 @@ ms.date: 01/11/2022 The .NET Multi-platform App UI (.NET MAUI) class derives from the class, and is used to paint an area with a solid color. There are a variety of approaches to specifying the color of a . For example, you can specify its color with a value or by using one of the predefined objects provided by the class. +::: moniker range="=net-maui-7.0" + The class defines the `Color` property, of type , which represents the color of the brush. This property is backed by a object, which means that it can be the target of data bindings, and styled. +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +The class defines the `Color` property, of type , which represents the color of the brush. This property is the [`ContentProperty`](xref:Microsoft.Maui.Controls.ContentPropertyAttribute) of the class, and therefore does not need to be explicitly set from XAML. In addition, this property is backed by a object, which means that it can be the target of data bindings, and styled. + +::: moniker-end + The class also has an `IsEmpty` method that returns a `bool` that represents whether the brush has been assigned a color. ## Create a SolidColorBrush diff --git a/docs/user-interface/context-menu.md b/docs/user-interface/context-menu.md index 5669fb2d61..3ca8c2434d 100644 --- a/docs/user-interface/context-menu.md +++ b/docs/user-interface/context-menu.md @@ -63,6 +63,12 @@ The `OnWebViewGoToRepoClicked` event handler retrieves the `CommandParameter` pr > [!WARNING] > It's not currently possible to add items to, or remove items from, the `MenuFlyout` at runtime. +::: moniker range=">=net-maui-8.0" + +Keyboard accelerators can be added to context menu items, so that a context menu item can be invoked through a keyboard shortcut. For more information, see [Keyboard accelerators](~/user-interface/keyboard-accelerators.md). + +::: moniker-end + ### Create sub-menu items Sub-menu items can be added to a context menu by adding one or more `MenuFlyoutSubItem` objects to the `MenuFlyout`: diff --git a/docs/user-interface/controls/blazorwebview.md b/docs/user-interface/controls/blazorwebview.md index b182e31d64..31943b3c67 100644 --- a/docs/user-interface/controls/blazorwebview.md +++ b/docs/user-interface/controls/blazorwebview.md @@ -1,7 +1,7 @@ --- title: "Host a Blazor web app in a .NET MAUI app using BlazorWebView" description: "The .NET MAUI BlazorWebView control enables you to host a Blazor web app in your .NET MAUI app, and integrate the app with device features." -ms.date: 01/18/2023 +ms.date: 10/02/2023 --- # Host a Blazor web app in a .NET MAUI app using BlazorWebView @@ -10,9 +10,21 @@ The .NET Multi-platform App UI (.NET MAUI) defines the following properties: +::: moniker range="=net-maui-7.0" + - `HostPage`, of type `string?`, which defines the root page of the Blazor web app. - `RootComponents`, of type `RootComponentsCollection`, which specifies the collection of root components that can be added to the control. +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +- `HostPage`, of type `string?`, which defines the root page of the Blazor web app. +- `RootComponents`, of type `RootComponentsCollection`, which specifies the collection of root components that can be added to the control. +- `StartPath`, of type `string`, which defines the path for initial navigation within the Blazor navigation context when the Blazor component is finished loading. + +::: moniker-end + The `RootComponent` class defines the following properties: - `Selector`, of type `string?`, which defines the CSS selector string that specifies where in the document the component should be placed. @@ -121,3 +133,74 @@ The process to add a has a `TryDispatchAsync` method that can call a specified `Action` asynchronously and pass in the scoped services available in Razor components. This enables code from the native UI to access scoped services such as enables code from the native UI to access scoped services such as : + +```csharp +private async void OnMyMauiButtonClicked(object sender, EventArgs e) +{ + var wasDispatchCalled = await blazorWebView.TryDispatchAsync(sp => + { + var navMan = sp.GetRequiredService(); + navMan.CallSomeNavigationApi(...); + }); + + if (!wasDispatchCalled) + { + // Consider what to do if it the dispatch fails - that's up to your app to decide. + } +} +``` + +## Diagnosing issues + + has built-in logging that can help you diagnose issues in your Blazor Hybrid app. There are two steps to enable this logging: + +1. Enable and related components to log diagnostic information. +1. Configure a logger to write the log output to where you can view it. + +For more information about logging, see [Logging in C# and .NET](/dotnet/core/extensions/logging). + +### Enable BlazorWebView logging + +All logging configuration can be performed as part of service registration in the dependency injection system. To enable maximum logging for and related components under the namespace, add the following code to where your app's services are registered: + +```csharp +services.AddLogging(logging => +{ + logging.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace); +}); +``` + +Alternatively, to enable maximum logging for every component that uses , you could use the following code: + +```csharp +services.AddLogging(logging => +{ + logging.SetMinimumLevel(LogLevel.Trace); +}); +``` + +### Configure logging output and viewing the output + +After configuring components to write log information you need to configure where the loggers should write the logs to, and then view the log output. + +The **Debug** logging providers write the output using `Debug` statements, and the output can be viewed from Visual Studio. + +To configure the **Debug** logging provider, first add a reference in your project to the [`Microsoft.Extensions.Logging.Debug`](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Debug) NuGet package. Then, register the provider inside the call to that you added in the previous step by calling the extension method: + +```csharp +services.AddLogging(logging => +{ + logging.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace); + logging.AddDebug(); +}); +``` + +When you run the app from Visual Studio (with debugging enabled), you can view the debug output in Visual Studio's **Output** window. + +::: moniker-end diff --git a/docs/user-interface/controls/border.md b/docs/user-interface/controls/border.md index 8b55640b2c..7f1ad0fb03 100644 --- a/docs/user-interface/controls/border.md +++ b/docs/user-interface/controls/border.md @@ -12,7 +12,7 @@ The .NET Multi-platform App UI (.NET MAUI) defines the following properties: -- `Content`, of type `IView`, represents the content to display in the border. This property is the `ContentProperty` of the class, and therefore does not need to be explicitly set from XAML. +- `Content`, of type `IView`, represents the content to display in the border. This property is the [`ContentProperty`](xref:Microsoft.Maui.Controls.ContentPropertyAttribute) of the class, and therefore does not need to be explicitly set from XAML. - `Padding`, of type `Thickness`, represents the distance between the border and its child element. - `StrokeShape`, of type `IShape`, describes the shape of the border. This property has a type converter applied to it that can convert a string to its equivalent `IShape`. It's default value is . Therefore, a will be rectangular by default. - `Stroke`, of type , indicates the brush used to paint the border. diff --git a/docs/user-interface/controls/editor.md b/docs/user-interface/controls/editor.md index 3e1bcd0789..befdd066b0 100644 --- a/docs/user-interface/controls/editor.md +++ b/docs/user-interface/controls/editor.md @@ -1,7 +1,7 @@ --- title: "Editor" description: "The .NET MAUI Editor allows you to enter and edit multiple lines of text." -ms.date: 03/03/2022 +ms.date: 10/19/2023 --- # Editor @@ -10,8 +10,9 @@ The .NET Multi-platform App UI (.NET MAUI) defines the following properties: +::: moniker range="=net-maui-7.0" + - `AutoSize`, of type `EditorAutoSizeOption`, defines whether the editor will change size to accommodate user input. By default, the editor doesn't auto size. -- `CharacterSpacing`, of type `double`, sets the spacing between characters in the entered text. - `CursorPosition`, of type `int`, defines the position of the cursor within the editor. - `FontAttributes`, of type `FontAttributes`, determines text style. - `FontAutoScalingEnabled`, of type `bool`, defines whether the text will reflect scaling preferences set in the operating system. The default value of this property is `true`. @@ -19,25 +20,62 @@ The .NET Multi-platform App UI (.NET MAUI) - `FontSize`, of type `double`, defines the font size. - `HorizontalTextAlignment`, of type `TextAlignment`, defines the horizontal alignment of the text. - `IsTextPredictionEnabled`, of type `bool`, controls whether text prediction and automatic text correction is enabled. -- `Placeholder`, of type `string`, defines the text that's displayed when the control is empty. -- `PlaceholderColor`, of type , defines the color of the placeholder text. - `SelectionLength`, of type `int`, represents the length of selected text within the editor. -- `Text`, of type `string`, defines the text entered into the editor. -- `TextColor`, of type , defines the color of the entered text. - `VerticalTextAlignment`, of type `TextAlignment`, defines the vertical alignment of the text. +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +- `AutoSize`, of type `EditorAutoSizeOption`, defines whether the editor will change size to accommodate user input. By default, the editor doesn't auto size. +- `HorizontalTextAlignment`, of type `TextAlignment`, defines the horizontal alignment of the text. +- `VerticalTextAlignment`, of type `TextAlignment`, defines the vertical alignment of the text. + +::: moniker-end + These properties are backed by objects, which means that they can be targets of data bindings, and styled. In addition, defines a `Completed` event, which is raised when the user finalizes text in the with the return key. derives from the `InputView` class, from which it inherits the following properties: +::: moniker range="=net-maui-7.0" + +- `CharacterSpacing`, of type `double`, sets the spacing between characters in the entered text. - `IsReadOnly`, of type `bool`, defines whether the user should be prevented from modifying text. The default value of this property is `false`. - `IsSpellCheckEnabled`, of type `bool`, controls whether spell checking is enabled. -- `Keyboard`, of type `Keyboard`, specifies the virtual keyboard that's displayed when entering text. +- `Keyboard`, of type `Keyboard`, specifies the soft input keyboard that's displayed when entering text. - `MaxLength`, of type `int`, defines the maximum input length. +- `Placeholder`, of type `string`, defines the text that's displayed when the control is empty. +- `PlaceholderColor`, of type , defines the color of the placeholder text. +- `Text`, of type `string`, defines the text entered into the control. +- `TextColor`, of type , defines the color of the entered text. - `TextTransform`, of type `TextTransform`, specifies the casing of the entered text. +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +- `CharacterSpacing`, of type `double`, sets the spacing between characters in the entered text. +- `CursorPosition`, of type `int`, defines the position of the cursor within the editor. +- `FontAttributes`, of type `FontAttributes`, determines text style. +- `FontAutoScalingEnabled`, of type `bool`, defines whether the text will reflect scaling preferences set in the operating system. The default value of this property is `true`. +- `FontFamily`, of type `string`, defines the font family. +- `FontSize`, of type `double`, defines the font size. +- `IsReadOnly`, of type `bool`, defines whether the user should be prevented from modifying text. The default value of this property is `false`. +- `IsSpellCheckEnabled`, of type `bool`, controls whether spell checking is enabled. +- `IsTextPredictionEnabled`, of type `bool`, controls whether text prediction and automatic text correction is enabled. +- `Keyboard`, of type `Keyboard`, specifies the soft input keyboard that's displayed when entering text. +- `MaxLength`, of type `int`, defines the maximum input length. +- `Placeholder`, of type `string`, defines the text that's displayed when the control is empty. +- `PlaceholderColor`, of type , defines the color of the placeholder text. +- `SelectionLength`, of type `int`, represents the length of selected text within the control. +- `Text`, of type `string`, defines the text entered into the control. +- `TextColor`, of type , defines the color of the entered text. +- `TextTransform`, of type `TextTransform`, specifies the casing of the entered text. + +::: moniker-end + These properties are backed by objects, which means that they can be targets of data bindings, and styled. In addition, `InputView` defines a `TextChanged` event, which is raised when the text in the changes. The `TextChangedEventArgs` object that accompanies the `TextChanged` event has `NewTextValue` and `OldTextValue` properties, which specify the new and old text, respectively. @@ -68,6 +106,8 @@ The following screenshot shows the resulting changes, and the `TextChangedEventArgs` provide the text before and after the change via the `OldTextValue` and `NewTextValue` properties: @@ -200,6 +240,19 @@ Editor editor = new Editor(); editor.Keyboard = Keyboard.Create(KeyboardFlags.Suggestions | KeyboardFlags.CapitalizeCharacter); ``` +::: moniker range=">=net-maui-8.0" + +[!INCLUDE [Hide and show the soft input keyboard](includes/soft-input-extensions.md)] + +The following example shows how to hide the soft input keyboard on an named `editor`, if it's currently showing: + +```csharp +if (editor.IsSoftInputShowing()) + await editor.HideSoftInputAsync(System.Threading.CancellationToken.None); +``` + +::: moniker-end + ## Enable and disable spell checking The `IsSpellCheckEnabled` property controls whether spell checking is enabled. By default, the property is set to `true`. As the user enters text, misspellings are indicated. diff --git a/docs/user-interface/controls/entry.md b/docs/user-interface/controls/entry.md index 2d9d2c2e05..fcafa63b72 100644 --- a/docs/user-interface/controls/entry.md +++ b/docs/user-interface/controls/entry.md @@ -1,7 +1,7 @@ --- title: "Entry" description: "The .NET MAUI Entry allows you to enter and edit a single line of text." -ms.date: 03/03/2022 +ms.date: 10/19/2023 --- # Entry @@ -10,6 +10,8 @@ The .NET Multi-platform App UI (.NET MAUI) defines the following properties: +::: moniker range="=net-maui-7.0" + - `CharacterSpacing`, of type `double`, sets the spacing between characters in the entered text. - `ClearButtonVisibility`, of type `ClearButtonVisibility`, controls whether a clear button is displayed, which enables the user to clear the text. The default value of this property ensures that a clear button isn't displayed. - `CursorPosition`, of type `int`, defines the position of the cursor within the entry. @@ -17,31 +19,72 @@ The .NET Multi-platform App UI (.NET MAUI) - `FontAutoScalingEnabled`, of type `bool`, defines whether the text will reflect scaling preferences set in the operating system. The default value of this property is `true`. - `FontFamily`, of type `string`, defines the font family. - `FontSize`, of type `double`, defines the font size. -- `Keyboard`, of type `Keyboard`, specifies the virtual keyboard that's displayed when entering text. - `HorizontalTextAlignment`, of type `TextAlignment`, defines the horizontal alignment of the text. - `IsPassword`, of type `bool`, specifies whether the entry should visually obscure typed text. - `IsTextPredictionEnabled`, of type `bool`, controls whether text prediction and automatic text correction is enabled. -- `Placeholder`, of type `string`, defines the text that's displayed when the control is empty. -- `PlaceholderColor`, of type , defines the color of the placeholder text. - `ReturnCommand`, of type `ICommand`, defines the command to be executed when the return key is pressed. - `ReturnCommandParameter`, of type `object`, specifies the parameter for the `ReturnCommand`. - `ReturnType`, of type `ReturnType`, specifies the appearance of the return button. - `SelectionLength`, of type `int`, represents the length of selected text within the entry. -- `Text`, of type `string`, defines the text entered into the entry. -- `TextColor`, of type , defines the color of the entered text. - `VerticalTextAlignment`, of type `TextAlignment`, defines the vertical alignment of the text. +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +- `ClearButtonVisibility`, of type `ClearButtonVisibility`, controls whether a clear button is displayed, which enables the user to clear the text. The default value of this property ensures that a clear button isn't displayed. +- `HorizontalTextAlignment`, of type `TextAlignment`, defines the horizontal alignment of the text. +- `IsPassword`, of type `bool`, specifies whether the entry should visually obscure typed text. +- `ReturnCommand`, of type `ICommand`, defines the command to be executed when the return key is pressed. +- `ReturnCommandParameter`, of type `object`, specifies the parameter for the `ReturnCommand`. +- `ReturnType`, of type `ReturnType`, specifies the appearance of the return button. +- `VerticalTextAlignment`, of type `TextAlignment`, defines the vertical alignment of the text. + +::: moniker-end + These properties are backed by objects, which means that they can be targets of data bindings, and styled. In addition, defines a `Completed` event, which is raised when the user finalizes text in the with the return key. derives from the `InputView` class, from which it inherits the following properties: +::: moniker range="=net-maui-7.0" + +- `CharacterSpacing`, of type `double`, sets the spacing between characters in the entered text. - `IsReadOnly`, of type `bool`, defines whether the user should be prevented from modifying text. The default value of this property is `false`. - `IsSpellCheckEnabled`, of type `bool`, controls whether spell checking is enabled. +- `Keyboard`, of type `Keyboard`, specifies the soft input keyboard that's displayed when entering text. - `MaxLength`, of type `int`, defines the maximum input length. +- `Placeholder`, of type `string`, defines the text that's displayed when the control is empty. +- `PlaceholderColor`, of type , defines the color of the placeholder text. +- `Text`, of type `string`, defines the text entered into the control. +- `TextColor`, of type , defines the color of the entered text. - `TextTransform`, of type `TextTransform`, specifies the casing of the entered text. +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +- `CharacterSpacing`, of type `double`, sets the spacing between characters in the entered text. +- `CursorPosition`, of type `int`, defines the position of the cursor within the editor. +- `FontAttributes`, of type `FontAttributes`, determines text style. +- `FontAutoScalingEnabled`, of type `bool`, defines whether the text will reflect scaling preferences set in the operating system. The default value of this property is `true`. +- `FontFamily`, of type `string`, defines the font family. +- `FontSize`, of type `double`, defines the font size. +- `IsReadOnly`, of type `bool`, defines whether the user should be prevented from modifying text. The default value of this property is `false`. +- `IsSpellCheckEnabled`, of type `bool`, controls whether spell checking is enabled. +- `IsTextPredictionEnabled`, of type `bool`, controls whether text prediction and automatic text correction is enabled. +- `Keyboard`, of type `Keyboard`, specifies the soft input keyboard that's displayed when entering text. +- `MaxLength`, of type `int`, defines the maximum input length. +- `Placeholder`, of type `string`, defines the text that's displayed when the control is empty. +- `PlaceholderColor`, of type , defines the color of the placeholder text. +- `SelectionLength`, of type `int`, represents the length of selected text within the control. +- `Text`, of type `string`, defines the text entered into the control. +- `TextColor`, of type , defines the color of the entered text. +- `TextTransform`, of type `TextTransform`, specifies the casing of the entered text. + +::: moniker-end + These properties are backed by objects, which means that they can be targets of data bindings, and styled. In addition, `InputView` defines a `TextChanged` event, which is raised when the text in the changes. The `TextChangedEventArgs` object that accompanies the `TextChanged` event has `NewTextValue` and `OldTextValue` properties, which specify the new and old text, respectively. @@ -71,6 +114,8 @@ The following screenshot shows the resulting changes, and the `TextChangedEventArgs` provide the text before and after the change via the `OldTextValue` and `NewTextValue` properties: @@ -192,7 +237,7 @@ The following screenshot shows an whose inp ## Customize the keyboard -The virtual keyboard that's presented when users interact with an can be set programmatically via the `Keyboard` property, to one of the following properties from the `Keyboard` class: +The soft input keyboard that's presented when users interact with an can be set programmatically via the `Keyboard` property, to one of the following properties from the `Keyboard` class: - `Chat` – used for texting and places where emoji are useful. - `Default` – the default keyboard. @@ -243,7 +288,7 @@ entry.Keyboard = Keyboard.Create(KeyboardFlags.Suggestions | KeyboardFlags.Capit ### Customize the return key -The appearance of the return key on the virtual keyboard, which is displayed when an has focus, can be customized by setting the `ReturnType` property to a value of the `ReturnType` enumeration: +The appearance of the return key on the soft input keyboard, which is displayed when an has focus, can be customized by setting the `ReturnType` property to a value of the `ReturnType` enumeration: - `Default` – indicates that no specific return key is required and that the platform default will be used. - `Done` – indicates a "Done" return key. @@ -263,6 +308,19 @@ The following XAML example shows how to set the return key: When the return key is pressed, the `Completed` event fires and any `ICommand` specified by the `ReturnCommand` property is executed. In addition, any `object` specified by the `ReturnCommandParameter` property will be passed to the `ICommand` as a parameter. For more information about commands, see [Commanding](~/fundamentals/data-binding/commanding.md). +::: moniker range=">=net-maui-8.0" + +[!INCLUDE [Hide and show the soft input keyboard](includes/soft-input-extensions.md)] + +The following example shows how to hide the soft input keyboard on an named `entry`, if it's currently showing: + +```csharp +if (entry.IsSoftInputShowing()) + await entry.HideSoftInputAsync(System.Threading.CancellationToken.None); +``` + +::: moniker-end + ## Enable and disable spell checking The `IsSpellCheckEnabled` property controls whether spell checking is enabled. By default, the property is set to `true`. As the user enters text, misspellings are indicated. diff --git a/docs/user-interface/controls/frame.md b/docs/user-interface/controls/frame.md index 98441cb75c..72b6d20dde 100644 --- a/docs/user-interface/controls/frame.md +++ b/docs/user-interface/controls/frame.md @@ -16,7 +16,7 @@ The class defines the following properties: These properties are backed by objects, which means that they can be targets of data bindings, and styled. -The class inherits from , which provides a `Content` bindable property. The `Content` property is the `ContentProperty` of the class, and therefore does not need to be explicitly set from XAML. +The class inherits from , which provides a `Content` bindable property. The `Content` property is the [`ContentProperty`](xref:Microsoft.Maui.Controls.ContentPropertyAttribute) of the class, and therefore does not need to be explicitly set from XAML. > [!NOTE] > The class existed in Xamarin.Forms and is present in .NET MAUI for users who are migrating their apps from Xamarin.Forms to .NET MAUI. If you're building a new .NET MAUI app it's recommended to use instead, and to set shadows using the `Shadow` bindable property on . For more information, see [Border](border.md) and [Shadow](../shadow.md). diff --git a/docs/user-interface/controls/image.md b/docs/user-interface/controls/image.md index abf59ba371..649b5e1c76 100644 --- a/docs/user-interface/controls/image.md +++ b/docs/user-interface/controls/image.md @@ -214,6 +214,13 @@ Image image = new Image }; ``` +::: moniker range=">=net-maui-8.0" + +> [!IMPORTANT] +> Image caching is disabled on Android when loading an image from a stream with the [`ImageSource.FromStream`](xref:Microsoft.Maui.Controls.ImageSource.FromStream%2A) method. This is due to the lack of data from which to create a reasonable cache key. + +::: moniker-end + ## Load a font icon The [`FontImage`](xref:Microsoft.Maui.Controls.Xaml.FontImageExtension) markup extension enables you to display a font icon in any view that can display an . It provides the same functionality as the class, but with a more concise representation. diff --git a/docs/user-interface/controls/includes/keyboardautomanagerscroll.md b/docs/user-interface/controls/includes/keyboardautomanagerscroll.md new file mode 100644 index 0000000000..602e455c5c --- /dev/null +++ b/docs/user-interface/controls/includes/keyboardautomanagerscroll.md @@ -0,0 +1,11 @@ +--- +ms.topic: include +ms.date: 10/21/2023 +--- + +::: moniker range=">=net-maui-8.0" + +> [!NOTE] +> On iOS, the soft input keyboard can cover a text input field when the field is near the bottom of the screen, making it difficult to enter text. However, in a .NET MAUI iOS app, pages automatically scroll when the soft input keyboard would cover a text entry field, so that the field is above the soft input keyboard. The `KeyboardAutoManagerScroll.Disconnect` method, in the `Microsoft.Maui.Platform` namespace, can be called to disable this default behavior. The `KeyboardAutoManagerScroll.Connect` method can be called to re-enable the behavior after it's been disabled. + +::: moniker-end diff --git a/docs/user-interface/controls/includes/soft-input-extensions.md b/docs/user-interface/controls/includes/soft-input-extensions.md new file mode 100644 index 0000000000..7c9a5c1982 --- /dev/null +++ b/docs/user-interface/controls/includes/soft-input-extensions.md @@ -0,0 +1,12 @@ +--- +ms.topic: include +ms.date: 10/19/2023 +--- + +## Hide and show the soft input keyboard + +The `SoftInputExtensions` class, in the `Microsoft.Maui` namespace, provides a series of extension methods that support interacting with the soft input keyboard on controls that support text input. The class defines the following methods: + +- `IsSoftInputShowing`, which checks to see if the device is currently showing the soft input keyboard. +- `HideSoftInputAsync`, which will attempt to hide the soft input keyboard if it's currently showing. +- `ShowSoftInputAsync`, which will attempt to show the soft input keyboard if it's currently hidden. diff --git a/docs/user-interface/controls/label.md b/docs/user-interface/controls/label.md index e448a12cba..ae4e35fa1a 100644 --- a/docs/user-interface/controls/label.md +++ b/docs/user-interface/controls/label.md @@ -186,7 +186,7 @@ Alternatively, for greater readability the HTML can be inlined in a `CDATA` sect ``` -In this example, the `Text` property is set to the HTML string that's inlined in the `CDATA` section. This works because the `Text` property is the `ContentProperty` for the class. +In this example, the `Text` property is set to the HTML string that's inlined in the `CDATA` section. This works because the `Text` property is the [`ContentProperty`](xref:Microsoft.Maui.Controls.ContentPropertyAttribute) for the class. > [!IMPORTANT] > Displaying HTML in a is limited to the HTML tags that are supported by the underlying platform. diff --git a/docs/user-interface/controls/map.md b/docs/user-interface/controls/map.md index dad1273513..2e8e6786bc 100644 --- a/docs/user-interface/controls/map.md +++ b/docs/user-interface/controls/map.md @@ -173,6 +173,8 @@ For information about the `ItemsSource`, `ItemTemplate`, and `ItemTemplateSelect A can be displayed by adding it to a layout or page: +::: moniker range="=net-maui-7.0" + ```xaml @@ -183,6 +185,19 @@ A can be displayed by adding it to a lay > [!NOTE] > In XAML, an `xmlns` namespace definition should be added for the control. While this isn't required, it prevents a collision between the `Polygon` and `Polyline` types, which exist in both the and namespaces. +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +```xaml + + + +``` + +::: moniker-end + The equivalent C# code is: ```csharp @@ -237,6 +252,8 @@ Map map = new Map The region of a map to display when a map is loaded can be set by passing a `MapSpan` argument to the constructor: +::: moniker range="=net-maui-7.0" + ```xaml ``` +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +```xaml + + + + + + + + 36.9628066 + -122.0194722 + + + 0.01 + 0.01 + + + + + +``` + +::: moniker-end + The equivalent C# code is: ```csharp @@ -512,6 +558,8 @@ In addition, the `Pin` class defines `MarkerClicked` and `InfoWindowClicked` eve A `Pin` can be added to a in XAML: +::: moniker range="=net-maui-7.0" + ```xaml in XAML: ``` +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +```xaml + + + + + + + + 36.9628066 + -122.0194722 + + + 0.01 + 0.01 + + + + + + + + + 36.9628066 + -122.0194722 + + + + + + + +``` + +::: moniker-end + This XAML creates a object that shows the region that is specified by the `MapSpan` object. The `MapSpan` object is centered on the latitude and longitude represented by a `Location` object, which extends 0.01 latitude and longitude degrees. A `Pin` object is added to the `Map.Pins` collection, and drawn on the at the location specified by its `Location` property. For information about the `Location` class, see [Location and distance](#location-and-distance). For information about passing arguments in XAML to objects that lack default constructors, see [Pass arguments in XAML](~/xaml/pass-arguments.md). The equivalent C# code is: @@ -652,6 +743,8 @@ The class defines the following bindable A can be populated with pins by using data binding to bind its `ItemsSource` property to an `IEnumerable` collection: +::: moniker range="=net-maui-7.0" + ```xaml @@ -672,6 +765,32 @@ A can be populated with pins by using da ``` +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +```xaml + + + ... + + + + + + + + ... + + +``` + +::: moniker-end + The `ItemsSource` property data binds to the `Positions` property of the connected viewmodel, which returns an `ObservableCollection` of `Position` objects, which is a custom type. Each `Position` object defines `Address` and `Description` properties, of type `string`, and a `Location` property, of type `Location`. The appearance of each item in the `IEnumerable` collection is defined by setting the `ItemTemplate` property to a that contains a `Pin` object that data binds to appropriate properties. @@ -684,6 +803,8 @@ The following screenshot shows a display The appearance of each item in the `IEnumerable` collection can be chosen at runtime, based on the item value, by setting the `ItemTemplateSelector` property to a : +::: moniker range="=net-maui-7.0" + ```xaml ``` +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +```xaml + + + + + + + + + + + + + + + + + + ... + + ... + + +``` + +::: moniker-end + The following example shows the `MapItemTemplateSelector` class: ```csharp @@ -770,6 +930,8 @@ The `Circle` class defines the following bindable properties: A `Polygon` object can be added to a map by instantiating it and adding it to the map's `MapElements` collection: +::: moniker range="=net-maui-7.0" + ```xaml ``` +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +```xaml + + + + + + + + 47.6458676 + -122.1356007 + + + + + 47.6458097 + -122.142789 + + + ... + + + + + +``` + +::: moniker-end + The equivalent C# code is: ```csharp @@ -837,6 +1035,8 @@ The `StrokeColor` and `StrokeWidth` properties are specified to set the polygon' A `Polyline` object can be added to a map by instantiating it and adding it to the map's `MapElements` collection: +::: moniker range="=net-maui-7.0" + ```xaml ``` +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +```xaml + + + + + + + + 47.6381401 + -122.1317367 + + + + + 47.6381473 + -122.1350841 + + + ... + + + + + +``` + +::: moniker-end + +The equivalent C# code is: + ```csharp using Microsoft.Maui.Controls.Maps; using Microsoft.Maui.Maps; @@ -897,6 +1134,8 @@ The `StrokeColor` and `StrokeWidth` properties are specified to set the line app A `Circle` object can be added to a map by instantiating it and adding it to the map's `MapElements` collection: +::: moniker range="=net-maui-7.0" + ```xaml ``` +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +```xaml + + + + + + + + 37.79752 + -122.40183 + + + + + + + 250 + + + + + + + +``` + +::: moniker-end + The equivalent C# code is: ```csharp diff --git a/docs/user-interface/controls/scrollview.md b/docs/user-interface/controls/scrollview.md index 3e4ed44d5e..5ab1b62183 100644 --- a/docs/user-interface/controls/scrollview.md +++ b/docs/user-interface/controls/scrollview.md @@ -22,7 +22,7 @@ The .NET Multi-platform App UI (.NET MAUI) objects, with the exception of the `Content` property, which means that they can be targets of data bindings and styled. -The `Content` property is the `ContentProperty` of the class, and therefore does not need to be explicitly set from XAML. +The `Content` property is the [`ContentProperty`](xref:Microsoft.Maui.Controls.ContentPropertyAttribute) of the class, and therefore does not need to be explicitly set from XAML. > [!WARNING] > objects should not be nested. In addition, objects should not be nested with other controls that provide scrolling, such as , , and . diff --git a/docs/user-interface/controls/searchbar.md b/docs/user-interface/controls/searchbar.md index 0c23fffb0b..7565cf3b07 100644 --- a/docs/user-interface/controls/searchbar.md +++ b/docs/user-interface/controls/searchbar.md @@ -1,7 +1,7 @@ --- title: "SearchBar" description: "The .NET MAUI SearchBar is a user input control that is used for initiating a search. The SearchBar control supports placeholder text, query input, execution, and cancellation." -ms.date: 02/15/2022 +ms.date: 10/19/2023 --- # SearchBar @@ -12,8 +12,9 @@ The .NET Multi-platform App UI (.NET MAUI) defines the following properties: +::: moniker range="=net-maui-7.0" + - `CancelButtonColor` is a that defines the color of the cancel button. -- `CharacterSpacing`, is a `double` that's the spacing between characters of the text. - `CursorPosition` is an `int` that determines the position at which the next character will be inserted into the string stored in the `Text` property. - `FontAttributes` is a `FontAttributes` enum value that determines whether the font is bold, italic, or neither. - `FontAutoScalingEnabled` is a `bool` which defines whether an app's UI reflects text scaling preferences set in the operating system. @@ -21,21 +22,69 @@ The .NET Multi-platform App UI (.NET MAUI) that defines the color of the placeholder text. - `SearchCommand` is an `ICommand` that allows binding user actions, such as finger taps or clicks, to commands defined on a viewmodel. - `SearchCommandParameter` is an `object` that specifies the parameter that should be passed to the `SearchCommand`. - `SelectionLength` is an `int` that can be used to return or set the length of text selection within the . -- `Text` is a `string` containing the query text in the . -- `TextColor` is a that defines the query text color. - `VerticalTextAlignment` is a `TextAlignment` enum value that defines the vertical alignment of the query text. +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +- `CancelButtonColor` is a that defines the color of the cancel button. +- `HorizontalTextAlignment` is a `TextAlignment` enum value that defines the horizontal alignment of the query text. +- `SearchCommand` is an `ICommand` that allows binding user actions, such as finger taps or clicks, to commands defined on a viewmodel. +- `SearchCommandParameter` is an `object` that specifies the parameter that should be passed to the `SearchCommand`. +- `VerticalTextAlignment` is a `TextAlignment` enum value that defines the vertical alignment of the query text. + +::: moniker-end + These properties are backed by objects, which means that they can be targets of data bindings, and styled. In addition, defines a `SearchButtonPressed` event, which is raised when the search button is clicked, or the enter key is pressed. -> [!NOTE] -> derives from the `InputView` class, from which it inherits additional properties and events. + derives from the `InputView` class, from which it inherits the following properties: + +::: moniker range="=net-maui-7.0" + +- `CharacterSpacing`, of type `double`, sets the spacing between characters in the entered text. +- `IsReadOnly`, of type `bool`, defines whether the user should be prevented from modifying text. The default value of this property is `false`. +- `IsSpellCheckEnabled`, of type `bool`, controls whether spell checking is enabled. +- `Keyboard`, of type `Keyboard`, specifies the soft input keyboard that's displayed when entering text. +- `MaxLength`, of type `int`, defines the maximum input length. +- `Placeholder`, of type `string`, defines the text that's displayed when the control is empty. +- `PlaceholderColor`, of type , defines the color of the placeholder text. +- `Text`, of type `string`, defines the text entered into the control. +- `TextColor`, of type , defines the color of the entered text. +- `TextTransform`, of type `TextTransform`, specifies the casing of the entered text. + +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +- `CharacterSpacing`, of type `double`, sets the spacing between characters in the entered text. +- `CursorPosition`, of type `int`, defines the position of the cursor within the editor. +- `FontAttributes`, of type `FontAttributes`, determines text style. +- `FontAutoScalingEnabled`, of type `bool`, defines whether the text will reflect scaling preferences set in the operating system. The default value of this property is `true`. +- `FontFamily`, of type `string`, defines the font family. +- `FontSize`, of type `double`, defines the font size. +- `IsReadOnly`, of type `bool`, defines whether the user should be prevented from modifying text. The default value of this property is `false`. +- `IsSpellCheckEnabled`, of type `bool`, controls whether spell checking is enabled. +- `IsTextPredictionEnabled`, of type `bool`, controls whether text prediction and automatic text correction is enabled. +- `Keyboard`, of type `Keyboard`, specifies the soft input keyboard that's displayed when entering text. +- `MaxLength`, of type `int`, defines the maximum input length. +- `Placeholder`, of type `string`, defines the text that's displayed when the control is empty. +- `PlaceholderColor`, of type , defines the color of the placeholder text. +- `SelectionLength`, of type `int`, represents the length of selected text within the control. +- `Text`, of type `string`, defines the text entered into the control. +- `TextColor`, of type , defines the color of the entered text. +- `TextTransform`, of type `TextTransform`, specifies the casing of the entered text. + +::: moniker-end + +These properties are backed by objects, which means that they can be targets of data bindings, and styled. + +In addition, `InputView` defines a `TextChanged` event, which is raised when the text in the changes. The `TextChangedEventArgs` object that accompanies the `TextChanged` event has `NewTextValue` and `OldTextValue` properties, which specify the new and old text, respectively. ## Create a SearchBar @@ -53,6 +102,8 @@ The equivalent C# code is: SearchBar searchBar = new SearchBar { Placeholder = "Search items..." }; ``` +[!INCLUDE [Keyboard autoscroll manager](includes/keyboardautomanagerscroll.md)] + ## Perform a search with event handlers A search can be executed using the control by attaching an event handler to one of the following events: @@ -142,3 +193,16 @@ In this example, the `BindingContext` is set to an instance of the `SearchViewMo > [!NOTE] > On iOS, the `SearchBarRenderer` class contains an overridable `UpdateCancelButton` method. This method controls when the cancel button appears, and can be overridden in a custom renderer. --> + +::: moniker range=">=net-maui-8.0" + +[!INCLUDE [Hide and show the soft input keyboard](includes/soft-input-extensions.md)] + +The following example shows how to hide the soft input keyboard on a named `searchBar`, if it's currently showing: + +```csharp +if (searchBar.IsSoftInputShowing()) + await searchBar.HideSoftInputAsync(System.Threading.CancellationToken.None); +``` + +::: moniker-end diff --git a/docs/user-interface/controls/shapes/geometries.md b/docs/user-interface/controls/shapes/geometries.md index a5be791246..a4aa7ee2e3 100644 --- a/docs/user-interface/controls/shapes/geometries.md +++ b/docs/user-interface/controls/shapes/geometries.md @@ -127,7 +127,7 @@ These properties are backed by o For more information about the enumeration, see [.NET MAUI Shapes: Fill rules](fillrules.md). > [!NOTE] -> The property is the `ContentProperty` of the class, and so does not need to be explicitly set from XAML. +> The property is the [`ContentProperty`](xref:Microsoft.Maui.Controls.ContentPropertyAttribute) of the class, and so does not need to be explicitly set from XAML. A is made up of a collection of objects, with each describing a shape in the geometry. Each is itself comprised of one or more objects, each of which describes a segment of the shape. There are many types of segments: @@ -539,7 +539,7 @@ The class defines the follow These properties are backed by objects, which means that they can be targets of data bindings, and styled. > [!NOTE] -> The `Children` property is the `ContentProperty` of the class, and so does not need to be explicitly set from XAML. +> The `Children` property is the [`ContentProperty`](xref:Microsoft.Maui.Controls.ContentPropertyAttribute) of the class, and so does not need to be explicitly set from XAML. For more information about the enumeration, see [Fill rules](fillrules.md). diff --git a/docs/user-interface/controls/webview.md b/docs/user-interface/controls/webview.md index 155a3f1395..5a57958016 100644 --- a/docs/user-interface/controls/webview.md +++ b/docs/user-interface/controls/webview.md @@ -11,10 +11,24 @@ The .NET Multi-platform App UI (.NET MAUI) defines the following properties: +::: moniker range="=net-maui-7.0" + +- `Cookies`, of type `CookieContainer`, provides storage for a collection of cookies. +- `CanGoBack`, of type `bool`, indicates whether the user can navigate to previous pages. This is a read-only property. +- `CanGoForward`, of type `bool`, indicates whether the user can navigate forward. This is a read-only property. +- `Source`, of type `WebViewSource`, represents the location that the displays. + +::: moniker-end + +::: moniker range=">=net-maui-8.0" + - `Cookies`, of type `CookieContainer`, provides storage for a collection of cookies. - `CanGoBack`, of type `bool`, indicates whether the user can navigate to previous pages. This is a read-only property. - `CanGoForward`, of type `bool`, indicates whether the user can navigate forward. This is a read-only property. - `Source`, of type `WebViewSource`, represents the location that the displays. +- `UserAgent`, of type `string`, represents the user agent. The default value is the user agent of the underlying platform browser, or `null` if it can't be determined. + +::: moniker-end These properties are backed by objects, which means that they can be targets of data bindings, and styled. @@ -380,7 +394,9 @@ function factorial(num) { The native control is a `MauiWKWebView` on iOS and Mac Catalyst, which derives from `WKWebView`. One of the `MauiWKWebView` constructor overloads enables a `WKWebViewConfiguration` object to be specified, which provides information about how to configure the `WKWebView` object. Typical configurations include setting the user agent, specifying cookies to make available to your web content, and injecting custom scripts into your web content. -You can create a `WKWebViewConfiguration` object in your app, and then configure its properties as required. Alternatively, you can call the static `MauiWKWebView.CreateConfiguration` method to retrieve .NET MAUI's `WKWebViewConfiguration` object and then modify it. The `WKWebViewConfiguration` object can then be passed to the `MauiWKWebView` constructor overload by modifying the factory method that `WebViewHandler` uses to create its native control on each platform: +You can create a `WKWebViewConfiguration` object in your app, and then configure its properties as required. Alternatively, you can call the static `MauiWKWebView.CreateConfiguration` method to retrieve .NET MAUI's `WKWebViewConfiguration` object and then modify it. The `WKWebViewConfiguration` object can then be specified as an argument to the `MauiWKWebView` constructor overload. + +Since the configuration of the native can't be changed on iOS and Mac Catalyst once the handler's platform view is created, you should create a custom handler factory delegate to modify it: ```csharp #if IOS || MACCATALYST @@ -392,10 +408,12 @@ using Microsoft.Maui.Handlers; ... #if IOS || MACCATALYST - WKWebViewConfiguration config = MauiWKWebView.CreateConfiguration(); - config.ApplicationNameForUserAgent = "MyProduct/1.0.0"; - WebViewHandler.PlatformViewFactory = - handler => new MauiWKWebView(CGRect.Empty, (WebViewHandler)handler, config); + Microsoft.Maui.Handlers.WebViewHandler.PlatformViewFactory = (handler) => + { + WKWebViewConfiguration config = MauiWKWebView.CreateConfiguration(); + config.ApplicationNameForUserAgent = "MyProduct/1.0.0"; + return new MauiWKWebView(CGRect.Empty, (WebViewHandler)handler, config); + }; #endif ``` @@ -404,6 +422,51 @@ using Microsoft.Maui.Handlers; :::zone-end +::: moniker range=">=net-maui-8.0" + +:::zone pivot="devices-ios, devices-maccatalyst" + +## Set media playback preferences on iOS and Mac Catalyst + +Inline media playback of HTML5 video, including autoplay and picture in picture, is enabled by default for the on iOS and Mac Catalyst. To change this default, or set other media playback preferences, you should create a custom handler factory delegate since media playback preferences can't be changed once the handler's platform view is created. The following code shows an example of doing this: + +```csharp +#if IOS || MACCATALYST +using WebKit; +using CoreGraphics; +using Microsoft.Maui.Platform; +using Microsoft.Maui.Handlers; +#endif +... + +#if IOS || MACCATALYST + Microsoft.Maui.Handlers.WebViewHandler.PlatformViewFactory = (handler) => + { + WKWebViewConfiguration config = MauiWKWebView.CreateConfiguration(); + + // True to play HTML5 videos inliine, false to use the native full-screen controller. + config.AllowsInlineMediaPlayback = false; + + // True to play videos over AirPlay, otherwise false. + config.AllowsAirPlayForMediaPlayback = false; + + // True to let HTML5 videos play Picture in Picture. + config.AllowsPictureInPictureMediaPlayback = false; + + // Media types that require a user gesture to begin playing. + config.MediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypes.All; + + return new MauiWKWebView(CGRect.Empty, (WebViewHandler)handler, config); + }; +#endif +``` + +For more information about configuring a on iOS, see [Configure the native WebView on iOS and Mac Catalyst](#configure-the-native-webview-on-ios-and-mac-catalyst). + +:::zone-end + +::: moniker-end + :::zone pivot="devices-maccatalyst" ## Inspect a WebView on Mac Catalyst diff --git a/docs/user-interface/fonts.md b/docs/user-interface/fonts.md index 9d4d2d6578..f62514220e 100644 --- a/docs/user-interface/fonts.md +++ b/docs/user-interface/fonts.md @@ -58,7 +58,7 @@ A font can be added to your app project by dragging it into the *Resources\Fonts Fonts can also be added to other folders of your app project. However, in this scenario their build action must be manually set to **MauiFont** in the **Properties** window. -At build time, fonts are copied to your app package. +At build time, fonts are copied to your app package. For information about disabling font packaging, see [Disable font packaging](~/troubleshooting.md#disable-font-packaging). > [!NOTE] > The `*` wildcard character indicates that all the files within the folder will be treated as being font files. In addition, if you want to include files from sub-folders too, then configure it using additional wildcard characters, for example, `Resources\Fonts\**\*`. @@ -99,6 +99,39 @@ Label label2 = new Label }; ``` +::: moniker range=">=net-maui-8.0" + +On Android, the following system fonts can be consumed by setting them as the value of the `FontFamily` property: + +- monospace +- serif +- sans-serif (or sansserif) +- sans-serif-black (or sansserif-black) +- sans-serif-condensed (or sansserif-condensed) +- sans-serif-condensed-light (or sansserif-condensed-light) +- sans-serif-light (or sansserif-light) +- sans-serif-medium (or sansserif-medium) + +For example, the monospace system font can be consumed with the following XAML: + +```xaml +