Skip to content

Releases

v17.0.0: Update to .NET 11

Choose a tag to compare

@TheCodeTraveler TheCodeTraveler released this 10 Nov 20:27
Immutable release. Only release title and notes can be modified.
52c000a

This release updates CommunityToolkit.Maui to .NET 11.

It also enables Runtime Async only on the net11.0-windows TFM. Runtime Async is not enabled on the Mono Runtime and is not recommended for any NuGet library that may be consumed by an app using the Mono Runtime.

We have removed code supporting the Tizen TFM as Tizen was no longer supported in .NET MAUI starting with .NET 10.

We have also removed code supporting CommunityToolkit.Maui.Maps. See the Release Notes for CommunityToolkit.Maui.Maps v5.0.0 for more information.

Breaking Changes

The update to .NET 11 required us to modify some APIs and their underlying behavior. Please find the features you use, below, and update your apps accordingly.

All packages
API
  • Minimum OS versions in the API. The AppBuilderExtensions classes declare [SupportedOSPlatform] iOS 15.0, Mac Catalyst 17.0 and Android 24.0 (MediaElement: Android 26.0), the .NET MAUI 11 minimums. Attributes that only restated a version below these minimums are removed or made versionless; this only relaxes the analyzer. Feature-specific changes are in the CameraView, FileSaver and FolderPicker, MediaElement, NavigationBar (Android), SemanticOrderView, and StatusBar and StatusBarBehavior sections.
  • No Tizen API surface. The Tizen [SupportedOSPlatform] and [UnsupportedOSPlatform] attributes and the Tizen code paths are removed.
Behavior
  • Converters use the culture the binding passes. With no ConverterCulture, .NET MAUI passes CultureInfo.CurrentUICulture, as .NET MAUI 10 did.
    • These converters used the thread's CurrentCulture instead: ColorToCmykStringConverter, ColorToHslStringConverter, ColorToHslaStringConverter, CompareConverter, IsInRangeConverter, ListToStringConverter, MathExpressionConverter and MultiMathExpressionConverter.
    • Their output changes only when ConverterCulture is set or when an app's UI language differs from its regional format.
    • TextCaseConverter always used invariant casing instead, so its output also changes when the binding's culture is Turkish or Azerbaijani (see its section).
    • A null culture (calling a converter directly) keeps the previous behavior.
    • Each converter's section says what it does with the culture. ColorToRgbaStringConverter, DateTimeOffsetConverter and DoubleToIntConverter have separate changes, also in their sections.
Setup
  • .NET 11 only. The libraries target net11.0 and its platforms; .NET 10 apps should stay on the last .NET 10 releases (CommunityToolkit.Maui 15.x, CommunityToolkit.Maui.Camera 6.x, CommunityToolkit.Maui.MediaElement 10.x). The minimum OS versions are .NET MAUI 11's: iOS 15.0, Mac Catalyst 17.0 (macOS 14), Android 7.0 (API 24), Windows 10 1809 (10.0.17763); CommunityToolkit.Maui.MediaElement still requires Android 8.0 (API 26). .NET MAUI 11 itself no longer supports the older versions.
  • Tizen is no longer supported. The packages already shipped no Tizen target; .NET MAUI 11 dropped Tizen.
  • Dependencies: the libraries reference .NET MAUI 11 (Microsoft.Maui.Controls 11.0.0), and CommunityToolkit.Maui.Core references System.Speech 11.0.0 on Windows (pending: RC versions until the last commit).
Smaller changes
  • Windows: the async methods of the net11.0-windows assemblies are runtime async. No API or functional change: the compiler no longer generates async state machines for these methods (except async void ones), and the runtime handles their suspension instead.
  • Informational, from .NET MAUI 11: on iOS and Mac Catalyst, .NET MAUI 11 skips animations while the system's Reduce Motion setting is on, so the toolkit's animations (TouchBehavior, FadeAnimation, the animation behaviors) finish at once for those users. The toolkit doesn't change this.
CameraView
API
  • CommunityToolkit.Maui.Camera declares [SupportedOSPlatform] Windows 10.0.17763 (was 10.0.10240), like the other libraries.
ColorConversionExtensions
API
  • New ToCmykString(CultureInfo?) and ToHslString(CultureInfo?) overloads. A null culture uses CurrentCulture.
Behavior
  • ToHslaString(CultureInfo?) formats the hue, saturation and lightness with the given culture too, not only the alpha, so the string no longer mixes two cultures. A null culture still uses CurrentCulture.
ColorToCmykStringConverter, ColorToHslStringConverter and ColorToHslaStringConverter
Behavior
  • Percentages are formatted with the culture the binding passes (see All packages).
  • ColorToHslaStringConverter: the string no longer mixes two cultures (see ColorConversionExtensions).
ColorToRgbaStringConverter
Behavior
  • Converts back its own output in comma-decimal cultures; before, RGBA(255,0,0,0,5) under de-DE converted back to Transparent. A direct call with a null culture uses CurrentCulture both ways. (The HSLA and CMYKA converters are one-way.)
CompareConverter
Behavior
  • Strings are compared with the culture's collation, using the culture the binding passes (see All packages).
DateTimeOffsetConverter
Behavior
  • No longer applies the culture's calendar to the date: it produced wrong years under th-TH and fa-IR and threw under ar-SA. It also keeps sub-microsecond ticks.
DoubleToIntConverter
Behavior
  • Parses a string ConverterParameter with the invariant culture first, so ConverterParameter=2.5 means 2.5 for every user, and falls back to the binding's culture, so 2,5 still works in comma-decimal cultures.
  • A parameter with only . separators is now always a decimal: 1.000 under de-DE means 1 (it meant 1000).
DrawingView
Behavior
  • On iOS and Mac Catalyst, exporting an image off the main thread no longer risks a crash on .NET 11's CoreCLR (the CGColor of a temporary UIColor could be freed while it was read).
EventToCommandBehavior
API
  • New EventToCommandBehavior.EventArgsConverterCulture property (CultureInfo?, default null = CultureInfo.InvariantCulture, the previous behavior).
FileSaver and FolderPicker
API
  • The [SupportedOSPlatform] attributes iOS14.0/MacCatalyst14.0 on FileSaver and FolderPicker are now iOS/MacCatalyst (see All packages).
Behavior
  • On Windows (.NET 11):
    • With no visible app window they fail with FileSaveException / FolderPickerException ("No active window found") as on .NET 10, instead of opening a dialog over a hidden window.
    • An app with no windows no longer gets an ArgumentOutOfRangeException, and .NET MAUI embedded in a WinUI app no longer gets a false "No active window found".
    • Canceling the CancellationToken closes the open save or folder dialog and returns a canceled result, as on .NET 10, instead of waiting until the person closes the dialog. If the person has the "Confirm Save As" prompt open, the save ends canceled once they answer it, and nothing is written.
    • Picks on the same window now take turns: a pick that starts while another FileSaver or FolderPicker dialog is open on that window waits until that dialog closes, and canceling its token ends the wait with a canceled result.
    • A cancel can still close a dialog that other code opened on the same window during the canceled pick, such as the app's own message box, because nothing marks a picker dialog as the toolkit's.
GravatarImageSource
Behavior
  • The default-image keyword sent to Gravatar is lowercased with the invariant culture. Under Turkish and Azerbaijani cultures identicon and monsterid were sent as ıdenticon and monsterıd, which Gravatar doesn't recognize.
IsInRangeConverter
Behavior
  • Strings are compared with the culture's collation, using the culture the binding passes (see All packages).
ListToStringConverter
Behavior
  • Numbers and dates in the list are formatted with the culture the binding passes (see All packages).
  • A custom item type whose ToString() differs from its IFormattable.ToString(null, provider) changes output even without a culture.
...
Read more

MediaElement v12.0.0: Update to .NET 11

Choose a tag to compare

@TheCodeTraveler TheCodeTraveler released this 10 Nov 20:38
Immutable release. Only release title and notes can be modified.
52c000a

This release updates CommunityToolkit.Maui to .NET 11.

It also enables Runtime Async only on the net11.0-windows TFM. Runtime Async is not enabled on the Mono Runtime and is not recommended for any NuGet library that may be consumed by an app using the Mono Runtime.

We have removed code supporting the Tizen TFM as Tizen was no longer supported in .NET MAUI starting with .NET 10.

Breaking Changes

The update to .NET 11 required us to modify some APIs and their underlying behavior.

All packages
API
  • Minimum OS versions in the API. The AppBuilderExtensions classes declare [SupportedOSPlatform] iOS 15.0, Mac Catalyst 17.0 and Android 24.0 (MediaElement: Android 26.0), the .NET MAUI 11 minimums. Attributes that only restated a version below these minimums are removed or made versionless; this only relaxes the analyzer. Feature-specific changes are in the CameraView, FileSaver and FolderPicker, MediaElement, NavigationBar (Android), SemanticOrderView, and StatusBar and StatusBarBehavior sections.
  • No Tizen API surface. The Tizen [SupportedOSPlatform] and [UnsupportedOSPlatform] attributes and the Tizen code paths are removed.
Setup
  • .NET 11 only. The libraries target net11.0 and its platforms
  • Tizen is no longer supported. The packages already shipped no Tizen target; .NET MAUI 11 dropped Tizen.
  • Dependencies: the libraries reference .NET MAUI 11 (Microsoft.Maui.Controls 11.0.0)
Smaller changes
  • Windows: the async methods of the net11.0-windows assemblies are runtime async. No API or functional change: the compiler no longer generates async state machines for these methods (except async void ones), and the runtime handles their suspension instead.

What's Changed

Housekeeping

  • Bump actions/setup-java from 6.1.0 to 6.2.0 by @dependabot[bot] in #3376
  • [housekeeping] Automated PR to fix formatting errors by @github-actions[bot] in #3386
  • Bump actions/setup-dotnet from 6.0.0 to 6.1.0 by @dependabot[bot] in #3377
  • Bump the dotnet-tools group with 3 updates by @dependabot[bot] in #3379
  • Bump Microsoft.Extensions.Logging.Console from 10.0.11 to 10.0.14 by @dependabot[bot] in #3382
  • Bump PolySharp from 1.16.0 to 1.17.0 by @dependabot[bot] in #3389
  • Bump xunit.v3 from 4.0.2 to 4.0.3 by @dependabot[bot] in #3390

Full Changelog: 16.0.0...17.0.0

Camera v8.0.0: Update to .NET 11

Choose a tag to compare

@TheCodeTraveler TheCodeTraveler released this 10 Nov 20:32
Immutable release. Only release title and notes can be modified.
52c000a

This release updates CommunityToolkit.Maui.Camera to .NET 11.

It also enables Runtime Async only on the net11.0-windows TFM. Runtime Async is not enabled on the Mono Runtime and is not recommended for any NuGet library that may be consumed by an app using the Mono Runtime.

We have removed code supporting the Tizen TFM as Tizen was no longer supported in .NET MAUI starting with .NET 10.

Breaking Changes

The update to .NET 11 required us to modify some APIs and their underlying behavior. Please find the features you use, below, and update your apps accordingly.

All packages
API
  • Minimum OS versions in the API. The AppBuilderExtensions classes declare [SupportedOSPlatform] iOS 15.0, Mac Catalyst 17.0 and Android 24.0 (MediaElement: Android 26.0), the .NET MAUI 11 minimums. Attributes that only restated a version below these minimums are removed or made versionless; this only relaxes the analyzer. Feature-specific changes are in the CameraView, FileSaver and FolderPicker, MediaElement, NavigationBar (Android), SemanticOrderView, and StatusBar and StatusBarBehavior sections.
  • No Tizen API surface. The Tizen [SupportedOSPlatform] and [UnsupportedOSPlatform] attributes and the Tizen code paths are removed.
Setup
  • .NET 11 only. The libraries target net11.0 and its platforms. The minimum OS versions align with .NET MAUI 11's: iOS 15.0, Mac Catalyst 17.0 (macOS 14), Android 7.0 (API 24), Windows 10 1809 (10.0.17763)
  • Tizen is no longer supported. The packages already shipped no Tizen target; .NET MAUI 11 dropped Tizen.
Smaller changes
  • Windows: the async methods of the net11.0-windows assemblies are runtime async. No API or functional change: the compiler no longer generates async state machines for these methods (except async void ones), and the runtime handles their suspension instead.
CameraView
API
  • CommunityToolkit.Maui.Camera declares [SupportedOSPlatform] Windows 10.0.17763 (was 10.0.10240), like the other libraries.

What's Changed

Full Changelog: 16.0.0...17.0.0

v16.0.0 Bug Fix-A-Palooza

Choose a tag to compare

@TheCodeTraveler TheCodeTraveler released this 09 Nov 00:04
Immutable release. Only release title and notes can be modified.
991e2cb

v16.0.0 Bug Fix-A-Palooza 🎉

We have FINALLY implemented Device Tests! These are platform-specific unit tests that run on iOS, Android, MacCatalyst and Windows. This allows us to unit test all platform-specific code and has MASSIVELY increased our Unit Test Code Coverage:

  • 90.8% Code Coverage on CommunityToolkit.Maui
  • 96.7% Code Coverage on CommunityToolkit.Maui.Camera
  • 95% Code Coverage on CommunityToolkit.Maui.Core
  • 91.8% Code Coverage on CommunityToolkti.Maui.MediaElement

And thanks to the new Device Tests (along with excellent contributions from the community), this Release contains fixes for a whopping 58 Issues. 💪

Breaking Changes

To fix certain bugs, and re-align features to ensure they behave the same across all platforms, we did have to modify some APIs and the associated underlying behavior. Please find the features you use, below, and update your apps accordingly.

All packages
  • API: Null arguments throw ArgumentNullException at the call. Public and protected members of the five libraries now guard the non-nullable reference parameters they cannot handle (about 275 guards).
    • A null that used to cause a NullReferenceException later (or was stored silently) fails at the call, with a ParamName. What to do: fix the caller.
    • An async member throws from the call itself, before it returns a Task.
    • Null arguments that a member handled before are still accepted, for example an IProgress<double> or a Paint background of null.
    • Feature-specific effects are listed in each feature's section.
    • BasePlatformBehavior guards only bindable. A null platform view passes through, because the Android IconTintColorBehavior accepts it.
  • Setup: CommunityToolkit.Maui.Core on Android adds a <queries> entry for the launcher (MAIN/HOME) to the app's merged manifest through the package's library manifest (src/CommunityToolkit.Maui.Core/AndroidManifest.xml). Badge needs it on Android 11 and later. If your app or Play listing reviews <queries>, check the merged manifest.
  • Setup: Dependencies: on Windows, CommunityToolkit.Maui.Core references System.Speech 10.0.11 (it was 10.0.1). No action is needed unless you pin the package. This comes from #3288 on main, not from this PR.

New APIs In This Release

  • Popup now declares IPaddingElement, which it already inherited from ContentView
  • GravatarImageSource declares IStreamImageSource, which it already inherited from StreamImageSource, and overrides Cancel() (see GravatarImageSource, after that ApiCompat run);
  • [SupportedOSPlatform("android23.0")] on the Android StatusBarBehavior (see StatusBar and StatusBarBehavior).
  • DefaultPopupSettings.BackgroundColorDark and OnInitializing (#3345)
  • NumericValidationBehavior.Interval (#3329)
AvatarView
Behavior
  • AvatarView.
    • HorizontalOptions, VerticalOptions, HeightRequest, WidthRequest, Padding, Stroke, StrokeThickness and StrokeShape are no longer local values, so an implicit AvatarView Style applies (and a Border Style with ApplyToDerivedTypes).
    • An empty image source shows Text on every platform; iOS, MacCatalyst and Windows had previously showed an empty circle. Set Text to string.Empty or "" to display a blank circle.
    • The text replaces a failed or empty image only once the image has been laid out (about one layout pass later), because a GravatarImageSource asks for its picture only after its image has a size. So:
      • An AvatarView whose Gravatar failed to load while the page opened offline shows the picture again when the Email changes or a new load succeeds.
      • Such an AvatarView may show an empty circle for that one layout pass before the text.
Badge
Setup
  • CommunityToolkit.Maui.Core adds a <queries> entry for the launcher (MAIN/HOME) to Android apps; Badge needs it on Android 11 and later (see All packages).
Behavior
  • Badge on Windows without package identity. In an unpackaged app, Badge.SetCount writes one trace line and returns, instead of throwing a COMException that ended the app. No badge appears, so package the app if you need the taskbar badge.
Camera
ColorAnimationExtensions
Behavior
  • BackgroundColorTo and TextColorTo with a rate of 0 throw ArgumentOutOfRangeException from the call. Before, the error came later on the animation ticker and ended the app. Pass a rate above 0.
DialogFragment (Android)
Behavior
  • Android modal pages and the status bar. DialogFragmentService lays the dialog of a modal page out like the activity's window, for every status bar color.
    • On Android 11 and newer, a modal page receives the status bar inset. It must keep clear of the status bar itself, as a page in the activity's window does.
    • On Android 10 and older, a modal page also receives window insets with a transparent status bar color, where it received none.
DrawingView
Behavior
  • DrawingView.
    • On iOS and Mac Catalyst, GetImageStream with no lines returns Stream.Null instead of throwing InvalidOperationException, and a NaN image size, or one that is infinite on both sides, throws ArgumentException. Handle Stream.Null where you caught the exception.
    • An image scaled to ImageOptions.DesiredSize has its pixel size rounded half away from zero on Android, iOS and Mac Catalyst, as Windows already did. A 1920 x 1080 target of a 411 DIP canvas gives 1920 x 934 on Android, where it gave 1919 x 934.
    • On Windows a line captures the pointer, so a line released outside the view completes with DrawingLineCompleted, a lost capture raises DrawingLineCancelled, and a second pointer no longer starts or changes a line. No action is needed unless you worked around the old behavior.
Smaller changes
  • An unloaded view keeps its handler and listens again when it is loaded. DrawAction draws in a canvas state of its own.
Expander
Setup
  • Windows, iOS and Mac Catalyst: UseMauiCommunityToolkit registers the Expander layout handler (see Behavior below), so keep calling it at startup. That handler keeps its own platform view even when the app sets LayoutHandler.PlatformViewFactory.
Behavior
  • Expander accessibility.
    • On Windows the Expander is a Tab stop that Enter and Space toggle. UI Automation exposes it as a Button with the ExpandCollapse and Invoke patterns.
    • On Android, iOS and Mac Catalyst the header is one element for TalkBack and VoiceOver, with expand and collapse actions.
    • The Expander's internal layout now resolves to an internal ExpanderLayoutHandler, so a handler an app registers for Grid no longer applies to the Expander's internal Grid; LayoutHandler.Mapper changes still apply.
    • On Windows, iOS and Mac Catalyst, an app's LayoutHandler.PlatformViewFactory no longer creates the platform view of that layout, so the layout keeps the platform view that gives the header this support. The factory still creates the platform views of the app's other layouts, including the ones in the Expander's Header and Content, and on Android also the platform view of that layout.
Smaller changes
  • Expander Direction can be changed again by bindings and Styles.
FileSaver and FolderPicker
API
  • Null arguments throw ArgumentNullException at the call; FileSaver and FolderPicker still return the exception in the result. (see All packages)
Behavior
  • FileSaver and FolderPicker.
    • progress reports percentages from 0 to 100. It reported fractions from 0 to 1 during the copy, then a final 100, so remove any * 100 you applied.
    • A stream that cannot seek no longer fails the save; it gets only the final report.
    • On Android, a document whose provider gives no file path, such as a cloud document, is a successful save whose FilePath is its content:// URI. It used to fail with FileSaveException. ...
Read more

MediaElement v11.0.0 Bug Fix-A-Palooza

Choose a tag to compare

@TheCodeTraveler TheCodeTraveler released this 09 Nov 00:19
Immutable release. Only release title and notes can be modified.
991e2cb

MediaElement v11.0.0 Bug Fix-A-Palooza 🎉

We have FINALLY implemented Device Tests! These are platform-specific unit tests that run on iOS, Android, MacCatalyst and Windows. This allows us to unit test all platform-specific code and has MASSIVELY increased our Unit Test Code Coverage to 91.8% Code Coverage on CommunityToolkti.Maui.MediaElement.

Breaking Changes

To fix certain bugs, and re-align features to ensure they behave the same across all platforms, we did have to modify some APIs and the associated underlying behavior. Please find the features you use, below, and update your apps accordingly.

All packages
  • API: Null arguments throw ArgumentNullException at the call. Public and protected members of the five libraries now guard the non-nullable reference parameters they cannot handle (about 275 guards).
    • A null that used to cause a NullReferenceException later (or was stored silently) fails at the call, with a ParamName. What to do: fix the caller.
    • An async member throws from the call itself, before it returns a Task.
    • Null arguments that a member handled before are still accepted, for example an IProgress<double> or a Paint background of null.
    • Feature-specific effects are listed in each feature's section.
    • BasePlatformBehavior guards only bindable. A null platform view passes through, because the Android IconTintColorBehavior accepts it.
  • Setup: CommunityToolkit.Maui.Core on Android adds a <queries> entry for the launcher (MAIN/HOME) to the app's merged manifest through the package's library manifest (src/CommunityToolkit.Maui.Core/AndroidManifest.xml). Badge needs it on Android 11 and later. If your app or Play listing reviews <queries>, check the merged manifest.
  • Setup: Dependencies: on Windows, CommunityToolkit.Maui.Core references System.Speech 10.0.11 (it was 10.0.1). No action is needed unless you pin the package. This comes from #3288 on main, not from this PR.

New APIs In This Release

  • Popup now declares IPaddingElement, which it already inherited from ContentView
  • GravatarImageSource declares IStreamImageSource, which it already inherited from StreamImageSource, and overrides Cancel() (see GravatarImageSource, after that ApiCompat run);
  • [SupportedOSPlatform("android23.0")] on the Android StatusBarBehavior (see StatusBar and StatusBarBehavior).
  • DefaultPopupSettings.BackgroundColorDark and OnInitializing (#3345)
  • NumericValidationBehavior.Interval (#3329)
MediaElement
API
  • Null arguments: FileMediaSourceConverter.ConvertFrom(null) throws ArgumentNullException.
  • Null arguments: MediaFailedEventArgs rejects null for its non-nullable members.
Behavior
  • An exception thrown by an event handler while Source changes is reported through MediaFailed.
    • Before, an exception from a StateChanged, PropertyChanged or PropertyChanging handler reached the code that set Source, or ended the app when MAUI set it from XAML or a binding.
    • Now it is logged and the change goes on. The first exception is reported once through MediaFailed: ErrorMessage names its type and message, and CurrentState is not set to Failed.
    • What to do: handle MediaFailed, and check ErrorMessage before treating every MediaFailed as a failed source.
  • MediaElement playback.
    • SeekTo clamps a position outside the media to its start or end and raises SeekCompleted. On iOS such a seek never completed.
    • SeekTo fails with the platform's exception, for example InvalidOperationException before the player is ready, where that exception ended the app.
    • Play() at the end of the media starts it again on iOS and Mac Catalyst, as on Android.
    • On Android, CurrentState reports Buffering while buffering (it was Paused) and Stopped at the end of the media.
    • A source without data empties the player and reports None.
    • What to do: check code that relied on the old states.
  • A disconnected handler stops the position timer. The MediaElement no longer keeps its page alive after the page is left. No action is needed.
    • Why: the dispatcher timer stops when the handler disconnects, and starts again when a handler connects later.
    • Found on iOS: a probe left the Sample's MediaElementPage alive 3 of 3 times after it was left (0 of 3 with the fix). The same leak is fixed and tested on Android, Mac Catalyst and Windows.
    • On Windows, MediaOpened arrives on the player's worker thread. An open that was still running when the handler disconnected no longer starts the timer again: the timer starts on the UI thread, and only while a handler is attached.
    • A second leak was in the Sample: MediaElementFromStreamPage was IAsyncDisposable, so the window's service scope kept every page that was opened.
      • iOS: a probe left the page alive 3 of 3 times before the change, 0 of 3 after.
      • Windows (the Sample at 4a8d407, 5 visits, a GC dump after the 5th Back): 0 MediaElementFromStreamPage, MediaElement or StreamMediaSource stay alive, GC heap 6.5 MB. With the Sample change reverted: 5 of each, 167.7 MB.
  • Also fixed: FileMediaSourceConverter.ConvertFrom had an inverted condition. A real path threw InvalidOperationException, and an empty or white-space string returned a source. Now a real path returns the FileMediaSource, and an empty or white-space string throws InvalidOperationException, as documented.

What's Changed

Camera v7.0.0 Bug Fix-A-Palooza 🎉

Choose a tag to compare

@TheCodeTraveler TheCodeTraveler released this 09 Nov 00:11
Immutable release. Only release title and notes can be modified.
991e2cb

We have FINALLY implemented Device Tests! These are platform-specific unit tests that run on iOS, Android, MacCatalyst and Windows. This allows us to unit test all platform-specific code and has MASSIVELY increased our Unit Test Code Coverage to 96.7% Code Coverage on CommunityToolkit.Maui.Camera.

New APIs in This Release

  • CameraView.ErrorOccurred and ErrorOccurredEventArgs (#3299)

Breaking Changes

To fix certain bugs, and re-align features to ensure they behave the same across all platforms, we did have to modify some APIs and the associated underlying behavior. Please find the features you use, below, and update your apps accordingly.

All packages
  • API: Null arguments throw ArgumentNullException at the call. Public and protected members of the five libraries now guard the non-nullable reference parameters they cannot handle (about 275 guards).
    • A null that used to cause a NullReferenceException later (or was stored silently) fails at the call, with a ParamName. What to do: fix the caller.
    • An async member throws from the call itself, before it returns a Task.
    • Null arguments that a member handled before are still accepted, for example an IProgress<double> or a Paint background of null.
    • Feature-specific effects are listed in each feature's section.
    • BasePlatformBehavior guards only bindable. A null platform view passes through, because the Android IconTintColorBehavior accepts it.
  • Setup: CommunityToolkit.Maui.Core on Android adds a <queries> entry for the launcher (MAIN/HOME) to the app's merged manifest through the package's library manifest (src/CommunityToolkit.Maui.Core/AndroidManifest.xml). Badge needs it on Android 11 and later. If your app or Play listing reviews <queries>, check the merged manifest.
  • Setup: Dependencies: on Windows, CommunityToolkit.Maui.Core references System.Speech 10.0.11 (it was 10.0.1). No action is needed unless you pin the package. This comes from #3288 on main, not from this PR.
CameraView
API
  • Null arguments: ErrorOccurredEventArgs, MediaCaptureFailedEventArgs and CameraInfo reject null for their non-nullable members.
Behavior
  • Failures are reported through events instead of exceptions.
    • StartCameraPreview(CancellationToken) no longer throws for a camera that cannot start (except in the Android failed-connection case below). It raises ErrorOccurred on every platform.
      • A cancelled token still throws OperationCanceledException.
      • A view without a handler still throws InvalidOperationException.
    • The commands let no exception escape:
      • CaptureImageCommand, StartVideoRecordingCommand and StopVideoRecordingCommand report through MediaCaptureFailed.
      • StartCameraPreviewCommand and StopCameraPreviewCommand report through ErrorOccurred.
    • Failures of the handler's own work (connecting, switching to SelectedCamera, applying ImageCaptureResolution) raise ErrorOccurred instead of ending the app.
    • Android:
      • A preview without the camera permission now fails, is reported, and stays stopped until the activity resumes with the permission. iOS and Mac Catalyst report a denied permission the same way.
      • CaptureImage before the camera has started throws CameraException instead of waiting until its token is cancelled.
    • What to do: subscribe to ErrorOccurred and MediaCaptureFailed instead of relying on try/catch.
  • Android: one ErrorOccurred for a failed connection. A StartCameraPreview called while the CameraView connects to its camera waits for the connection.
    • When the connection fails and raises ErrorOccurred, that StartCameraPreview throws the same failure to its caller instead of raising ErrorOccurred again. StartCameraPreviewCommand doesn't report it again.
    • What to do: catch the exception where you await such a start.
  • StopCameraPreview cancels starts that still wait. StopCameraPreview and StopCameraPreviewCommand now cancel a pending StartCameraPreview, a pending StartVideoRecording (both overloads), the start the view makes when it connects its camera, and a camera switch.
    • The cancelled start throws OperationCanceledException, with no ErrorOccurred or MediaCaptureFailed. A start that a stop interrupted needs a new start.
    • What to do: do not treat that exception as a failure.
    • On iOS and Mac Catalyst, StartCameraPreview with an already-cancelled token throws and no longer starts the session.
  • Video recording.
    • Android: a StartVideoRecording during a recording replaces it: the new stream receives the video, and the earlier recording's video is discarded. Camera 6.1.0 ignored the second start; iOS and Mac Catalyst already replaced it.
    • Android, iOS, Mac Catalyst and Windows: a start that arrives while an earlier start still waits for the platform joins it. It returns once that recording has started, its stream receives no video, and it throws the earlier start's failure. On iOS and Mac Catalyst this holds for a double tap too, where Camera 6.1.0 replaced the first recording.
    • StartVideoRecording returns only once the platform has started the recording (#3311), so await it before relying on the recording. On iOS and Mac Catalyst, a start cancelled while it waits releases the recording state.
    • Windows, as on Android, iOS and Mac Catalyst:
      • StopVideoRecording waits for a pending StartVideoRecording.
      • A StartVideoRecording or a second StopVideoRecording that arrives while a stop waits for Media Foundation to finish the recording waits for that stop.
    • StopVideoRecording throws CameraException on Android, iOS and Mac Catalyst when the platform reports a recording with no playable video. A recording the platform ended early that has usable video is still returned.
    • Android: when the photo session cannot be restored after a successful export, StopVideoRecording still returns the video, and the failure is raised through ErrorOccurred. Selecting another camera during a recording waits until the recording stops or is replaced.
    • Windows: a StopVideoRecording whose token is cancelled already or while the stop finishes the video:
      • It still stops the recording and throws OperationCanceledException, as on Android, iOS and Mac Catalyst. It used to ignore the token and return the video.
      • The next StopVideoRecording returns the video. A StartVideoRecording that comes first discards it and puts its stream back, as for a replaced recording.
      • The camera that the recording turned on is off again when the cancelled stop throws.
      • A cancelled stop while a start or another stop is still pending throws without stopping anything.
      • With no recording, a cancelled StopVideoRecording returns Stream.Null on every platform.
      • StopVideoRecordingCommand ends without an event.
      • Camera 6.1.0 already handled a cancelled stop this way on Android and iOS; Mac Catalyst follows iOS.
      • Catch the OperationCanceledException and call StopVideoRecording again to get the video.
    • Windows: a StartVideoRecording during a recording ends and finishes the running recording and discards its video.
      • The running recording's stream goes back to the length and position it had when that recording started.
      • The video goes to the stream of the latest start, as on Android, iOS and Mac Catalyst. The camera stays on in between.
      • Camera 6.1.0 prepared a second recording without ending the first, so the first video was left unfinished or the new stream stayed empty.
      • If you relied on the first recording continuing, call StopVideoRecording before a new start.
    • What to do: handle ErrorOccurred and CameraException. On Android, don't rely on a second start being ignored.
  • Recording while the preview is stopped starts the camera.
    • On Android, iOS, Mac Catalyst and Windows, StartVideoRecording after StopCameraPreview, or before StartCameraPreview, starts the camera and then the recording. Android already did; Camera 6.1.0 recorded nothing on iOS, Mac Catalyst and Windows.
    • A camera that the recording turned on turns off again when the recording ends. After a cancelled StopVideoRecording on Android, iOS and Mac Catalyst, it turns off only once the next stop returns the video.
    • A preview that the app started stays on.
    • When the camera can't start, a stopped preview stays stopped. On iOS, Mac Catalyst and Windows, StartVideoRecording throws the failure: for example a CameraException without a camera or without the camera permission, or on Windows an UnauthorizedAccessException when the privacy settings block the camera. StartVideoRecordingCommand reports it through MediaCaptureFailed.
    • On Android, a StartCameraPreview after SetExtensionMode on a stopped previe...
Read more

Maps v5.0.0 - Our Final Maps Release

Choose a tag to compare

@TheCodeTraveler TheCodeTraveler released this 09 Nov 00:27
Immutable release. Only release title and notes can be modified.
991e2cb

CommunityToolkit.Maui.Maps v5.0.0 - Our Final Maps Release

The good news is that you no longer need us! In .NET 10, MAUI added Windows support to .NET MAUI's own Map control, meaning CommunityToolkit.Maui.Maps is no longer needed.

We recommend moving to .NET MAUI's official Microsoft.Maui.Controls.Maps package.

What changes in this release

  • UseMauiCommunityToolkitMaps, its AppBuilderExtensions class and the Windows handler MapHandlerWindows are marked [Obsolete].
  • The CommunityToolkit.Maui.Maps code will be removed from our repo when we merge our .NET 11 PR (#3331)

How to migrate

  1. Remove the CommunityToolkit.Maui.Maps package, its using CommunityToolkit.Maui.Maps; directives and the UseMauiCommunityToolkitMaps() call.
  2. Add the Microsoft.Maui.Controls.Maps package. The toolkit package used to reference it for you.
  3. Call builder.UseMauiMaps() in MauiProgram.cs on every platform.
  4. On Windows, also add an Azure Maps key: builder.ConfigureEssentials(essentials => essentials.UseMapServiceToken("YOUR_AZURE_MAPS_SUBSCRIPTION_KEY")). Without a valid key the Windows map shows no map data. See Manage authentication in Azure Maps to get one.

What to expect on Windows
.NET MAUI's Windows map is the WinUI 3 MapControl backed by Azure Maps.

  • Supported: MoveToRegion, the Street, Satellite and Hybrid map types, traffic, scrolling, zooming and pins.
  • Not supported yet: IsShowingUser, polygons, polylines and circles in MapElements, pin labels and info windows, and MapClicked.

Learn more

What's Changed

v15.0.1 Fix WindowsAppSDK Compatibility, Remove Remaining .NET MAUI Internal API Usage

Choose a tag to compare

@TheCodeTraveler TheCodeTraveler released this 21 Aug 17:07
Immutable release. Only release title and notes can be modified.
95a8998

v15.0.1 Fix Crashes on Windows

This release removes the WindowsAppSDK v2.2.0 dependency that was causing apps to crash on Windows. Long story short, .NET 10 MAUI currently expects Windows App SDK 1.8.x, while .NET 11 expects 2.3.1.

We also found a few more internal .NET MAUI APIs that we missed in the CommunityToolkti.Maui v15.0.0 Release used by FileSaver, FolderPicker, Snackbar, Toast, Expander and TouchBehavior that we have now removed. In .NET 11. CommunityToolkit.Maui will no longer have access to internal .NET MAUI APIs. We have updated our .NET 11 Migration guidance to use CommunityToolkit.Maui v15.0.1 or later to ensure compatibility with .NET 11. Specifically,

Important

We recommend every .NET MAUI app preparing for .NET 11 install this release, v15.0.1 (or later), before .NET 11 is released in November. Apps running CommunityToolkit.Maui v14.2.2 and earlier will not be compatible with .NET 11.

What's Changed

Housekeeping

  • [housekeeping] Automated PR to fix formatting errors by @github-actions[bot] in #3286
  • Bump Microsoft.Testing.Extensions.CodeCoverage from 18.9.0 to 18.10.0 by @dependabot[bot] in #3285
  • Bump actions/checkout from 7.0.0 to 7.0.1 by @dependabot[bot] in #3275
  • Bump Microsoft.Testing.Extensions.CodeCoverage from 18.8.0 to 18.9.0 by @dependabot[bot] in #3262
  • Bump actions/setup-java from 5.6.0 to 5.7.0 by @dependabot[bot] in #3278

Full Changelog: 15.0.0...15.0.1

v15.0.0 Prevent Breaking Changes in .NET 11

Choose a tag to compare

@TheCodeTraveler TheCodeTraveler released this 24 Jul 16:19
Immutable release. Only release title and notes can be modified.
ce6adeb

.NET 11 Compatibility

This release provides compatibility with the upcoming release of .NET 11.

In .NET 11, CommunityToolkit.Maui will no longer have access to internal .NET MAUI APIs. This release removes our use of internal .NET MAUI APIs to ensure compatibility with .NET 11.

Important

We recommend every .NET MAUI app preparing for .NET 11 install v15.0.1 (or later), before .NET 11 is released in November. Apps running CommunityToolkit.Maui v14.2.2 and earlier will not be compatible with .NET 11.

What's Changed

Housekeeping

Full Changelog: 14.2.2...14.2.3

14.2.2: Prevent Popup Race Conditions, (Windows) Folder Picker Initial Path

Choose a tag to compare

@jfversluis jfversluis released this 16 Jul 19:27
Immutable release. Only release title and notes can be modified.
68105ed

Note: 14.2.2 supersedes 14.2.1, which was not published to NuGet.org due to an expired publishing credential.

Just a couple bug fixes in this one!

  • Prevent Race Conditions when closing a Popup
  • Set initial folder for FilePicker and FolderPicker on Windows

What's Changed

  • Prevent Race Condition Allowing Simultaneous Calling of Navigation.PushModalAsync() / Shell.GotoAsync() in PopupExtensions by @TheCodeTraveler in #3234
  • Add SemaphoreSlim Support for Popup CloseAsync to Avoid Race Conditions by @TheCodeTraveler in #3235
  • Set Windows Folder Picker Initial Path by @TheCodeTraveler in #3078

Housekeeping

Full Changelog: 14.2.0...14.2.2