[net9.0] Merge main into net9.0.

This commit is contained in:
Rolf Bjarne Kvinge 2024-03-22 10:20:42 +01:00
Родитель 31d1517902 24f1054635
Коммит daa9d6a2c8
28 изменённых файлов: 1074 добавлений и 189 удалений

48
.github/workflows/yamllint.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,48 @@
# yamllint disable rule:line-length rule:document-start rule:truthy
name: PR yamllint check
on: pull_request
permissions:
contents: read
pull-requests: write
jobs:
rebase:
name: yamllint check
runs-on: ubuntu-latest
steps:
- name: 'Checkout'
uses: actions/checkout@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: Install yamllint
run: pip install yamllint
- name: Lint YAML pipeline files
id: lint-pipeline
working-directory: ./tools/devops/automation
run: |
RESULT=$(yamllint . -f github)
if [ -n "$RESULT" ]; then
echo "YAML Lint found issues"
echo "$RESULT"
echo "::set-output name=result::$RESULT"
exit 1
fi
# only post a comment if the linting fails
- name: Post comment
uses: unsplash/comment-on-pr@v1.3.0
if: failure()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
msg: |
[yaml-lint] YamlLint found issues in the pipeline files.
${{ steps.lint-pipeline.outputs.result }}
check_for_duplicate_msg: true
delete_prev_regex_msg: "YamlLint found issues in the pipeline files."
duplicate_msg_pattern: "YamlLint found issues in the pipeline files."

Просмотреть файл

@ -0,0 +1,263 @@
# Apples privacy manifest policy requirements
Apple is introducing new privacy policies that affect .NET applications targeting macOS, Mac Catalyst, iOS, iPadOS, and tvOS platforms on the App Stores. The policies affect how app developers are expected to disclose how they use any data collected from a users device and why certain APIs are being used. Developers will provide the details for these in a [privacy manifest file][PrivacyManifestFiles] that is included in the application bundle.
The [data collection](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_data_use_in_privacy_manifests) policies require you to declare the types of data that you collect and describe the data in a [privacy manifest files][PrivacyManifestFiles]. Apart from how to properly include the [privacy manifest files][PrivacyManifestFiles] in your .NET project, this document does not go into any detail on the data collection settings. The Apple documentation should be sufficient for declaring how your App or framework uses data it collects from users.
The [Required Reason APIs][RequiredReasonAPI] policy forces app developers to identify certain categories of APIs that their app, or frameworks use and to provide a reason for their use. This information is provided in a [privacy manifest files][PrivacyManifestFiles] along with the data collection information. This document will provide .NET application developers the information needed to provide a `PrivacyInfo.xcprivacy` file with thier .NET applications with the proper policy settings to pass the [Required Reason APIs][RequiredReasonAPI] checks when submitting to the Apple App Stores.
The privacy manifest file (`PrivacyInfo.xcprivacy`) lists the [types of data](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_data_use_in_privacy_manifests) your .NET MAUI application, or any third-party SDKs and packages collect, and the reasons for using certain [Required Reason APIs][RequiredReasonAPI] categories.
**Important:** If the use of the [Required Reason APIs][RequiredReasonAPI] by you or third-party SDKs isnt declared in the privacy manifest, your application might be rejected by the App Store. For more information, visit Apples documentation on [Required Reasons APIs][RequiredReasonAPI].
## Prepare your .NET MAUI applications for Apples privacy manifest policy
You must review your native code, C# code, and data collection and tracking practices to understand if Apples privacy manifest policy applies to you. Follow these guidelines to decide if you need to include a privacy manifest file in your product:
* If your application includes any third-party SDKs or packages, then these third-party components (if applicable) must provision their own privacy manifest files separately. **Note:** Its your responsibility however, to make sure that the owners of these third-party components include privacy manifest files. Microsoft isnt responsible for any third-party privacy manifest, and their data collection and tracking practices.
* If your application includes the [.NET APIs][C#NETAPIs] that call certain native APIs listed in the Apples [Required Reason API][RequiredReasonAPI] categories, then you must assess your product for the API usage. For assessing what constitutes as part of data collection and tracking practices, refer to Apples documentation on [privacy manifest files][PrivacyManifestFiles]. **Note:** Its your responsibility to assess your use of each of these APIs and declare the applicable reasons for using them.
Depending on whether youre using [.NET for iOS or .NET MAUI to develop an application](#privacy-manifest-for-net-maui-and-net-for-ios-or-tvos-applications) or providing [ObjectiveC or Swift Binding packages](#privacy-manifest-for-binding-projects) to use with .NET MAUI applications, the requirement for providing a privacy manifest file might differ.
**Note:** The above guidelines are provided for your convenience. Its important that you review Apples documentation on [privacy manifest files][PrivacyManifestFiles] before creating a privacy manifest for your project.
**Important:**
The following information is provided based on Apple's documentation as of March 2024. It is recommended that you review Apples documentation on [privacy manifest files][PrivacyManifestFiles] when creating a privacy manifest for your project to ensure you are using the most recent guidelines. If you find any discrepancies in the information below, please [file a bug](https://github.com/dotnet/maui/issues) and include the API in question.
## Privacy manifest for .NET MAUI and .NET for iOS or tvOS applications
If youre developing an application using .NET MAUI, consider the following steps:
1. Assess if your native application code uses any of the following APIs:
* APIs listed under the [Required Reason API][RequiredReasonAPI] category.
* The [C# .NET APIs][C#NETAPIs] in .NET MAUI framework.
1. If you meet one or both of the conditions from step 1, or if you have disabled [linking](https://learn.microsoft.com/xamarin/ios/deploy-test/linker?tabs=macos), which will retain all of the [C# .NET APIs][C#NETAPIs], then [create a privacy manifest file](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files#4284009) following the [example](#example) to add a `PrivacyInfo.xcprivacy` file to your project.
1. In the privacy manifest file, declare the approved reasons for using the [Required Reasons APIs][RequiredReasonAPI] or [C# .NET APIs][C#NETAPIs], as applicable.
**Important:** If you dont declare the reasons for the use of APIs, your application might be rejected by the App Store.
Verify if your native application code collects any type of data [categorized by Apple](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_data_use_in_privacy_manifests#4250555) and declare those data types in the privacy manifest file as applicable. Any third-party SDKs or packages used in your application must include their own separate manifest files to declare data collection and the use of any [Required Reasons APIs][RequiredReasonAPI] with approved reasons.
### Notes:
* Its your responsibility to check the accuracy of the privacy manifest within the .NET MAUI app and if any third-party components included in your .NET MAUI project require any declarations in you privacy manifest. Its recommended that you search these third-party components for any references to a privacy manifest declaration.
* If youre developing an application using .NET MAUI as a library, check if your native application code collects any of the following information outside of the .NET MAUI project:
* [Data collection](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_data_use_in_privacy_manifests)
* [Required Reasons APIs][RequiredReasonAPI]
If it does, then you must declare their usage in the privacy manifest file.
## Privacy manifest for Binding projects
If you are Binding project owner, and you are binding a xcframework, then the xcframework provider will need to include the `PrivacyInfo.xcprivacy` file as part of the xcframework. Otherwise, there are two options, provide documentation for package consumers to create the `PrivacyInfo.xcprivacy` file properly or change the bindings to bind an xcframework that has the `PrivacyInfo.xcprivacy` file included. It is currently not possible for Binding project authors to include a `PrivacyInfo.xcprivacy` file outside an xcframework that will be recognized by Apple when submitting an app.
## C# .NET APIs in .NET MAUI
.NET for iOS, tvOS and .NET MAUI build on top of the .NET runtime and BCL. Each SDK's API usages are detailed in the links below.
* [.NET Runtime and BCL API usages]()
* [.NET for iOS, tvOS and Xamarin.iOS API Usages]()
* [.NET MAUI and Xamarin.Forms API Usages]()
All .NET Apps that target devices running iOS, iPadOS, or tvOS will require a `PrivacyInfo.xcprivacy` file in the app bundle. This is due to the .NET Runtime and BCL using [Required Reasons APIs][RequiredReasonAPI] that are not removed regardless of the [linking](https://learn.microsoft.com/xamarin/ios/deploy-test/linker?tabs=macos) setting. The following three API categories and their associated reasons must be in the `PrivacyInfo.xcprivacy`.
* NSPrivacyAccessedAPICategoryFileTimestamp - C617.1
* NSPrivacyAccessedAPICategorySystemBootTime - 35F9.1
* NSPrivacyAccessedAPICategoryDiskSpace - E174.1
Additionally, if you use the `NSUserDefaults` APIs in your app, you will need to add the `NSPrivacyAccessedAPICategoryUserDefaults` API category, with a reason code of `CA92.1`.
See the example below for detailed instructions on how to add a `PrivacyInfo.xcprivacy` file to your App.
# Example
Let's look at how you would add a Privacy Manifest file to an application that uses the following APIs:
* [NSUserDefaults](https://learn.microsoft.com/dotnet/api/foundation.nsuserdefaults)
* [NSProcessInfo.SystemUptime](https://learn.microsoft.com/dotnet/api/foundation.nsprocessinfo.systemuptime)
* [NSFileManager.ModificationDate](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.modificationdate)
How they are used is not that important for this example, but the `why` will determine the reason code needed for the privacy manifest.
## Adding the `PrivacyInfo.xcprivacy` file to your project
The `PrivacyInfo.xcprivacy` is consider a resource when it is time to build the bundle. In accordance with [Placing Content in a Bundle](https://developer.apple.com/documentation/bundleresources/placing_content_in_a_bundle) the file is placed in the root of the Bundle. Use the proper set of instructions below for your project type:
### .NET MAUI
1. Create a new blank file named `PrivacyInfo.xcprivacy` in the `Platforms/iOS` folder in your .NET MAUI project.
1. In your favorite text editor, edit the .NET MAUI csproj project file.
1. Add the following elements to the bottom of the root `<Project>` element:
```xml
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
<BundleResource Include="Platforms\iOS\PrivacyInfo.xcprivacy" LogicalName="PrivacyInfo.xcprivacy" />
</ItemGroup>
```
This will package the file into the iOS app at the root of the bundle.
### .NET for iOS (net?-ios)
1. Create a new blank file named `PrivacyInfo.xcprivacy` in the `Resources` folder in your .NET for iOS project. This is all that is needed to package the file into the iOS app at the root of the bundle.
### .NET for tvOS (net?-tvos)
1. Create a new blank file named `PrivacyInfo.xcprivacy` in the root folder in your .NET for tvOS project.
1. In your favorite text editor, edit the .NET for tvOS csproj project file.
1. Add the following elements to the bottom of the root `<Project>` element:
```xml
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tvos'">
<BundleResource Include="PrivacyInfo.xcprivacy" LogicalName="PrivacyInfo.xcprivacy" />
</ItemGroup>
```
This will package the file into the tvOS app at the root of the bundle.
### Xamarin.iOS including Xamarin.Forms
1. Create a new blank file named `PrivacyInfo.xcprivacy` in the root folder of your Xamarin.iOS project.
1. In your favorite text editor, edit the Xamarin.iOS csproj project file.
1. Locate the `<ItemGroup>` that contains other `<BundleResource>` elements and add the following element:
```xml
<BundleResource Include="PrivacyInfo.xcprivacy" LogicalName="PrivacyInfo.xcprivacy" />
```
This will package the file into the iOS app at the root of the bundle.
Now that the file has been created in the proper location your project, it needs to be ppopulated with the correct settings for your app or framework.
## Creating the `PrivacyInfo.xcprivacy` file
We will start by building the contents of the `PrivacyInfo.xcprivacy` file, and then go through each supported platform and how to properly configure your project so the file is included in the bundle properly.
Since the application is based on .NET, a privacy manifest is required. Let's walkthrough the steps needed to add a privacy manifest that declares our usages of the above three API's.
1. Open Xcode and either create new `App` project, or open an existing one.
1. In Xcode use the File->New->File menu to open the `Choose a new template for your file:` dialog box.
1. Scroll down until you find the `App Privacy` template.
1. Select the `App Privacy` template and then click `Next`
1. In the `Save As` dialog, leave the filename as `PrivacyInfo` as that is the required name for the file.
1. Click `Create` and close Xcode.
1. Use Finder to copy the `PrivacyInfo.xcprivacy` file from the Xcode project to your documents folder for now.
1. The Xcode project is no longer needed and can be deleted.
You should now have a file named `PrivacyInfo.xcprivacy` under your documents folder with contents similar to:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!--
... omitted for brevity
-->
<plist version="1.0">
<dict/>
</plist>
```
Use your favorite text editor, like [Visual Studio Code](https://aka.ms/vscode), to open the file for editing.
You can add the entries for the APIs usage to the `PrivacyInfo.xcproject` as follows:
1. Edit the `PrivacyInfo.xcprivacy` file to appear as follows:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!--
... omitted for brevity
-->
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
</array>
</dict>
</plist>
```
This adds the `NSPrivacyAccessAPITypes` key where each category usage will be added.
1. Since the .NET runtime and BCL include APIs from the [File timestamp][FileTimestampAPIs], [System boot time][SystemBootTimeAPIs], [Disk space][DiskSpaceAPIs] API categories, add the following to the `NSPrivacyAccessedAPITypes` array:
```xml
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>E174.1</string>
</array>
</dict>
```
1. For the [NSProcessInfo.SystemUptime](https://learn.microsoft.com/dotnet/api/foundation.nsprocessinfo.systemuptime), a reason code of `35F9.1` is needed since that is the only reason code available. But since the .NET runtime and BCL already included that category and reason, there is nothing additional to add.
1. For the [NSFileManager.ModificationDate](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.modificationdate), a reason code of `C617.1` is needed since the modification dates are stored as a hash using [NSUserDefaults](https://learn.microsoft.com/dotnet/api/foundation.nsuserdefaults) but not displayed to the user. Again, the .NET runtime and BCL requirements have already satisfied this category and reason so no additional changes are needed.
1. For the [NSUserDefaults](https://learn.microsoft.com/dotnet/api/foundation.nsuserdefaults), a reason code of `CA92.1` is provided since the data accessed is only accessible to the app itself. Add the following element to the `NSPrivacyAccessedAPITypes` array:
```xml
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
```
The complete `PrivacyInfo.xcprivacy` should now look similar to:
```xml
<!--
... comments and headers omitted for brevity
-->
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>E174.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
</dict>
</plist>
```
Once added to your project, the `PrivacyInfo.xcprivacy` file will need to be updated if there are any additional API usages from additional categories or additional reasons for usage. This will include adding a NuGet package or Binding project that calls into any of Apples [Required Reason APIs][RequiredReasonAPI]. It is ultimately your responsibility to provide an accurate `PrivacyInfo.xcprivacy` file, failing to do so may result in the App Store rejecting your submission.
[RequiredReasonAPI]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api
[PrivacyManifestFiles]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
[C#NETAPIs]: #c-net-apis-in-net-maui
[FileTimestampAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278393
[SystemBootTimeAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278394
[DiskSpaceAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278397
[ActiveKeyboardAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278400
[UserDefaultsAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278401

Просмотреть файл

@ -0,0 +1,213 @@
# Required Reasons API usage in .NET, Mono and the BCL
The tables provide lists of C# .NET APIs that call the [Required Reasons APIs][RequiredReasonAPI] organized by category. These API usages are present in your app even if you do not explicitly call them. Therefore, you will be required to provide the API categories and reasons provided below in your apps `PrivacyInfo.xcprivacy` file. You may have to provide additional reason codes if you use the APIs directly, see [Required Reasons APIs][RequiredReasonAPI] for more information on the reason codes.
**Note:** The following lists are verified only for .NET versions 8.0.0 and later.
### [File timestamp APIs][FileTimestampAPIs]
The following APIs either directly or indirectly access file timestamps and require reasons for use. Use the string `NSPrivacyAccessedAPICategoryFileTimestamp` as the value for the `NSPrivacyAccessedAPIType` key in your `NSPrivacyAccessedAPITypes` dictionary. Refer to [File timestamp APIs][FileTimestampAPIs] for any additional relevant values to add to the `NSPrivacyAccessedAPITypeReasons` array.
| .NET API | Internal Usages | CoreClr Usages | Mono Usages
| - | - | - | - |
| [System.Diagnostics.FileVersionInfo](https://learn.microsoft.com/dotnet/api/System.Diagnostics.FileVersionInfo) | [Interop.Sys.LStat](https://source.dot.net/#System.Private.CoreLib/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Stat.cs,65) | SystemNative_LStat | g_file_test
| [System.IO.Compression.ZipFile.CreateFromDirectory](https://learn.microsoft.com/dotnet/api/System.IO.Compression.ZipFile.CreateFromDirectory) | [Interop.Sys.Stat](https://source.dot.net/#System.Private.CoreLib/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Stat.cs,62) | SystemNative_Stat | mono_file_map_size
| [System.IO.Directory.CreateDirectory(string)](https://learn.microsoft.com/dotnet/api/System.IO.Directory.CreateDirectory) | [Interop.Sys.FStat](https://source.dot.net/#System.Private.CoreLib/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Stat.cs,59) | SystemNative_FStat |
| [System.IO.Directory.CreateDirectory(string, UnixFileMode)](https://learn.microsoft.com/dotnet/api/System.IO.Directory.CreateDirectory) | [System.Runtime.Loader.AssemblyLoadContext.ResolveSatelliteAssembly](https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs,763)
| [System.IO.Directory.Delete(string)](https://learn.microsoft.com/dotnet/api/System.IO.Directory.Delete)
| [System.IO.Directory.Exists(string?)](https://learn.microsoft.com/dotnet/api/System.IO.Directory.Exists)
| [System.IO.Directory.GetCreationTime(string)](https://learn.microsoft.com/dotnet/api/System.IO.Directory.GetCreationTime)
| [System.IO.Directory.GetCreationTimeUtc(string)](https://learn.microsoft.com/dotnet/api/System.IO.Directory.GetCreationTimeUtc)
| [System.IO.Directory.GetLastAccessTime(string)](https://learn.microsoft.com/dotnet/api/System.IO.Directory.GetLastAccessTime)
| [System.IO.Directory.GetLastAccessTimeUtc(string)](https://learn.microsoft.com/dotnet/api/System.IO.Directory.GetLastAccessTimeUtc)
| [System.IO.Directory.GetLastWriteTime(string)](https://learn.microsoft.com/dotnet/api/System.IO.Directory.GetLastWriteTime)
| [System.IO.Directory.GetLastWriteTimeUtc(string)](https://learn.microsoft.com/dotnet/api/System.IO.Directory.GetLastWriteTimeUtc)
| [System.IO.Directory.Move(string, string)](https://learn.microsoft.com/dotnet/api/System.IO.Directory.Move)
| [System.IO.DirectoryInfo.Delete(string?)](https://learn.microsoft.com/dotnet/api/System.IO.DirectoryInfo.Delete)
| [System.IO.DirectoryInfo.MoveTo(string)](https://learn.microsoft.com/dotnet/api/System.IO.DirectoryInfo.MoveTo)
| [System.IO.Enumeration.FileSystemEntry.Attributes](https://learn.microsoft.com/dotnet/api/System.IO.Enumeration.FileSystemEntry.Attributes)
| [System.IO.Enumeration.FileSystemEntry.CreationTime](https://learn.microsoft.com/dotnet/api/System.IO.Enumeration.FileSystemEntry.CreationTime)
| [System.IO.Enumeration.FileSystemEntry.CreationTimeUtc](https://learn.microsoft.com/dotnet/api/System.IO.Enumeration.FileSystemEntry.CreationTimeUtc)
| [System.IO.Enumeration.FileSystemEntry.IsHidden](https://learn.microsoft.com/dotnet/api/System.IO.Enumeration.FileSystemEntry.IsHidden)
| [System.IO.Enumeration.FileSystemEntry.LastAccessTime](https://learn.microsoft.com/dotnet/api/System.IO.Enumeration.FileSystemEntry.Attributes)
| [System.IO.Enumeration.FileSystemEntry.LastAccessTimeUtc](https://learn.microsoft.com/dotnet/api/System.IO.Enumeration.FileSystemEntry.LastAccessTimeUtc)
| [System.IO.Enumeration.FileSystemEntry.LastWriteTime](https://learn.microsoft.com/dotnet/api/System.IO.Enumeration.FileSystemEntry.LastWriteTime)
| [System.IO.Enumeration.FileSystemEntry.LastWriteTimeUtc](https://learn.microsoft.com/dotnet/api/System.IO.Enumeration.FileSystemEntry.LastWriteTimeUtc)
| [System.IO.Enumeration.FileSystemEntry.Length](https://learn.microsoft.com/dotnet/api/System.IO.Enumeration.FileSystemEntry.Length)
| [System.IO.Enumeration.FileSystemEntry.ToFileSystemInfo()](https://learn.microsoft.com/dotnet/api/System.IO.Enumeration.FileSystemEntry.ToFileSystemInfo)
| [System.IO.File.Copy(string, string)](https://learn.microsoft.com/dotnet/api/System.IO.File.Copy)
| [System.IO.File.Copy(string, string, boolean)](https://learn.microsoft.com/dotnet/api/System.IO.File.Copy)
| [System.IO.File.Delete(string)](https://learn.microsoft.com/dotnet/api/System.IO.File.Delete)
| [System.IO.File.Exists(string?)](https://learn.microsoft.com/dotnet/api/System.IO.File.Exists)
| [System.IO.File.GetAttributes(SafeFileHandle)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetAttributes)
| [System.IO.File.GetAttributes(string)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetAttributes)
| [System.IO.File.GetCreationTime(SafeFileHandle)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetCreationTime)
| [System.IO.File.GetCreationTime(string)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetCreationTime)
| [System.IO.File.GetCreationTimeUtc(SafeFileHandle)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetCreationTimeUtc)
| [System.IO.File.GetCreationTimeUtc(string)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetCreationTimeUtc)
| [System.IO.File.GetLastAccessTime(SafeFileHandle)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetLastAccessTime)
| [System.IO.File.GetLastAccessTime(string)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetLastAccessTime)
| [System.IO.File.GetLastAccessTimeUtc(SafeFileHandle)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetLastAccessTimeUtc)
| [System.IO.File.GetLastAccessTimeUtc(string)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetLastAccessTimeUtc)
| [System.IO.File.GetLastWriteTime(SafeFileHandle)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetLastWriteTime)
| [System.IO.File.GetLastWriteTime(string)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetLastWriteTime)
| [System.IO.File.GetLastWriteTimeUtc(SafeFileHandle)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetLastWriteTimeUtc)
| [System.IO.File.GetLastWriteTimeUtc(string)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetLastWriteTimeUtc)
| [System.IO.File.GetUnixFileMode(SafeFileHandle)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetUnixFileMode)
| [System.IO.File.GetUnixFileMode(string)](https://learn.microsoft.com/dotnet/api/System.IO.File.GetUnixFileMode)
| [System.IO.File.Move(string, string)](https://learn.microsoft.com/dotnet/api/System.IO.File.Move)
| [System.IO.File.Move(string, string, boolean)](https://learn.microsoft.com/dotnet/api/System.IO.File.Move)
| [System.IO.File.OpenHandle(string, FileMode, FileAccess, FileShare, FileOptions, long)](https://learn.microsoft.com/dotnet/api/System.IO.File.OpenHandle)
| [System.IO.File.Replace(string, string, string)](https://learn.microsoft.com/dotnet/api/System.IO.File.Replace)
| [System.IO.File.Replace(string, string, string, boolean)](https://learn.microsoft.com/dotnet/api/System.IO.File.Replace)
| [System.IO.File.ReadAllBytes(string)](https://learn.microsoft.com/dotnet/api/System.IO.File.ReadAllBytes)
| [System.IO.File.ReadAllBytesAsync(string, CancellationToken)](https://learn.microsoft.com/dotnet/api/System.IO.File.ReadAllBytesAsync)
| [System.IO.FileInfo.Delete()](https://learn.microsoft.com/dotnet/api/System.IO.FileInfo.Delete)
| [System.IO.FileInfo.MoveTo(string, string)](https://learn.microsoft.com/dotnet/api/System.IO.FileInfo.MoveTo)
| [System.IO.FileInfo.MoveTo(string, string, boolean)](https://learn.microsoft.com/dotnet/api/System.IO.FileInfo.MoveTo)
| [System.IO.FileInfo.Replace(string, string)](https://learn.microsoft.com/dotnet/api/System.IO.FileInfo.Replace)
| [System.IO.FileInfo.Replace(string, string, boolean)](https://learn.microsoft.com/dotnet/api/System.IO.FileInfo.Replace)
| [System.IO.FileSystemInfo.Attributes](https://learn.microsoft.com/dotnet/api/System.IO.FileSystemInfo.Attributes)
| [System.IO.FileSystemInfo.CreationTime](https://learn.microsoft.com/dotnet/api/System.IO.FileSystemInfo.CreationTime)
| [System.IO.FileSystemInfo.CreationTimeUtc](https://learn.microsoft.com/dotnet/api/System.IO.FileSystemInfo.CreationTimeUtc)
| [System.IO.FileSystemInfo.LastAccessTime](https://learn.microsoft.com/dotnet/api/System.IO.FileSystemInfo.Attributes)
| [System.IO.FileSystemInfo.LastAccessTimeUtc](https://learn.microsoft.com/dotnet/api/System.IO.FileSystemInfo.LastAccessTimeUtc)
| [System.IO.FileSystemInfo.LastWriteTime](https://learn.microsoft.com/dotnet/api/System.IO.FileSystemInfo.LastWriteTime)
| [System.IO.FileSystemInfo.LastWriteTimeUtc](https://learn.microsoft.com/dotnet/api/System.IO.FileSystemInfo.LastWriteTimeUtc)
| [System.IO.FileSystemInfo.Length](https://learn.microsoft.com/dotnet/api/System.IO.FileSystemInfo.Length)
| [System.IO.FileSystemInfo.Refresh()](https://learn.microsoft.com/dotnet/api/System.IO.FileSystemInfo.Refresh)
| [System.IO.FileSystemInfo.UnixFileMode](https://learn.microsoft.com/dotnet/api/System.IO.FileSystemInfo.UnixFileMode)
| [System.IO.FileSystemWatcher](https://learn.microsoft.com/dotnet/api/System.IO.FileSystemWatcher)
| [System.IO.IsolatedStorage.IsolatedStorageFile.MoveDirectory(string, string)](https://learn.microsoft.com/dotnet/api/System.IO.IsolatedStorage.IsolatedStorageFile.MoveDirectory)
| [System.IO.IsolatedStorage.IsolatedStorageFile.MoveFile(string, string)](https://learn.microsoft.com/dotnet/api/System.IO.IsolatedStorage.IsolatedStorageFile.MoveFile)
| [System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(string)](https://learn.microsoft.com/dotnet/api/System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile)
| [System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(string, FileMode)](https://learn.microsoft.com/dotnet/api/System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile)
| [System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(string, FileMode, string?)](https://learn.microsoft.com/dotnet/api/System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile)
| [System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(string, FileMode, string?, long)](https://learn.microsoft.com/dotnet/api/System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile)
| [System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(string, FileMode, string?, long, MemoryMappedFileAccess)](https://learn.microsoft.com/dotnet/api/System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile)
| [System.IO.Path.Exists(string?)](https://learn.microsoft.com/dotnet/api/System.IO.Path.Exists)
| [System.IO.Pipes.AnonymousPipeClientStream](https://learn.microsoft.com/dotnet/api/System.IO.Pipes.AnonymousPipeClientStream)
| [System.IO.Pipes.AnonymousPipeServerStream](https://learn.microsoft.com/dotnet/api/System.IO.Pipes.AnonymousPipeServerStream)
| [System.IO.Pipes.NamedPipeClientStream](https://learn.microsoft.com/dotnet/api/System.IO.Pipes.NamedPipeClientStream)
| [System.IO.Pipes.NamedPipeServerStream](https://learn.microsoft.com/dotnet/api/System.IO.Pipes.NamedPipeServerStream)
| [System.IO.RandomAccess.GetLength(SafeFileHandle)](https://learn.microsoft.com/dotnet/api/System.IO.RandomAccess.GetLength)
| [System.Formats.Tar.TarWriter.WriteEntry(TarEntry)](https://learn.microsoft.com/dotnet/api/System.Formats.Tar.TarWriter.WriteEntry)
| [System.Formats.Tar.TarWriter.WriteEntry(string, string)](https://learn.microsoft.com/dotnet/api/System.Formats.Tar.TarWriter.WriteEntry)
| [System.Formats.Tar.TarWriter.WriteEntryAsync(TarEntry, CancellationToken)](https://learn.microsoft.com/dotnet/api/System.Formats.Tar.TarWriter.WriteEntryAsync)
| [System.Formats.Tar.TarWriter.WriteEntryAsync(string, string, CancellationToken)](https://learn.microsoft.com/dotnet/api/System.Formats.Tar.TarWriter.WriteEntryAsync)
| [System.Net.Sockets.Socket.SendPacketsAsync(SocketAsyncEventArgs)](https://learn.microsoft.com/dotnet/api/System.Net.Sockets.Socket.SendPacketsAsync)
| [System.TimeZoneInfo.Local](https://learn.microsoft.com/dotnet/api/System.TimeZoneInfo.Local)
For example, if you use any of the APIs listed above, your `PrivacyInfo.xcprivacy` would contain the `dict` element in the `NSPrivacyAccessedAPITypes` key's array as shown below:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
</array>
</dict>
</plist>
```
Additional reason codes from [File timestamp APIs][FileTimestampAPIs] can be provided in the array following the `NSPrivacyAccessedAPITypeReasons` key.
### [System boot time APIs][SystemBootTimeAPIs]
The following APIs either directly or indirectly access the system boot time and require reasons for use. Use the string `NSPrivacyAccessedAPICategorySystemBootTime` as the value for the `NSPrivacyAccessedAPIType` key in your `NSPrivacyAccessedAPITypes` dictionary. If you only access the system boot time from the list of APIs below, then use the `35F9.1` value in the `NSPrivacyAccessedAPITypeReasons` array.
| .NET API | Internal Usages | CoreClr Usages | Mono Usages
| - | - | - | - |
| [System.Environment.TickCount](https://learn.microsoft.com/dotnet/api/System.Environment.TickCount) | | | mono_msec_boottime
| [System.Environment.TickCount64](https://learn.microsoft.com/dotnet/api/System.Environment.TickCount64) | | | mono_domain_finalize
| | | | mono_join_uninterrupted
| | | | mono_msec_ticks
| | | | mono_100ns_ticks
| | | | threads_wait_pending_joinable_threads
| | | | current_time
For example, if you use any of the APIs listed above, your `PrivacyInfo.xcprivacy` would contain the `dict` element in the `NSPrivacyAccessedAPITypes` key's array as shown below:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
</array>
</dict>
</plist>
```
### [Disk space APIs][DiskSpaceAPIs]
The following APIs either directly or indirectly access the available disk space and require reasons for use. Use the string `NSPrivacyAccessedAPICategoryDiskSpace` as the value for the `NSPrivacyAccessedAPIType` key in your `NSPrivacyAccessedAPITypes` dictionary. If you access the available disk space from the list of APIs below, then use [Disk space APIs][DiskSpaceAPIs] to determine the correct values to place in the `NSPrivacyAccessedAPITypeReasons` array.
| .NET API | Internal Usages | CoreClr Usages | Mono Usages
| - | - | - | - |
| [System.IO.DriveInfo.AvailableFreeSpace](https://learn.microsoft.com/dotnet/api/System.IO.DriveInfo.AvailableFreeSpace) | [Interop.Sys.TryGetFileSystemType](https://source.dot.net/#System.Private.CoreLib/src/libraries/Common/src/Interop/Unix/System.Native/Interop.UnixFileSystemTypes.cs,155) | SystemNative_GetFileSystemType | |
| [System.IO.DriveInfo.DriveFormat](https://learn.microsoft.com/dotnet/api/System.IO.DriveInfo.DriveFormat) | [Interop.Sys.GetSpaceInfoForMountPoint](https://source.dot.net/#System.IO.FileSystem.DriveInfo/src/libraries/Common/src/Interop/Unix/System.Native/Interop.MountPoints.FormatInfo.cs,34) | SystemNative_GetSpaceInfoForMountPoint | |
| [System.IO.DriveInfo.DriveType](https://learn.microsoft.com/dotnet/api/System.IO.DriveInfo.DriveType) | [Interop.Sys.GetFormatInfoForMountPoint](https://source.dot.net/#System.IO.FileSystem.DriveInfo/src/libraries/Common/src/Interop/Unix/System.Native/Interop.MountPoints.FormatInfo.cs,37) | SystemNative_GetFormatInfoForMountPoint |
| [System.IO.DriveInfo.TotalFreeSpace](https://learn.microsoft.com/dotnet/api/System.IO.DriveInfo.TotalFreeSpace)
| [System.IO.DriveInfo.TotalSize](https://learn.microsoft.com/dotnet/api/System.IO.DriveInfo.TotalSize)
| [System.IO.File.Copy(string, string)](https://learn.microsoft.com/dotnet/api/System.IO.File.Copy)
| [System.IO.File.Copy(string, string, boolean)](https://learn.microsoft.com/dotnet/api/System.IO.File.Copy)
| [System.IO.File.OpenHandle(string, FileMode, FileAccess, FileShare, FileOptions, long)](https://learn.microsoft.com/dotnet/api/System.IO.File.OpenHandle)
| [System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(string)](https://learn.microsoft.com/dotnet/api/System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile)
| [System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(string, FileMode)](https://learn.microsoft.com/dotnet/api/System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile)
| [System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(string, FileMode, string?)](https://learn.microsoft.com/dotnet/api/System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile)
| [System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(string, FileMode, string?, long)](https://learn.microsoft.com/dotnet/api/System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile)
| [System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(string, FileMode, string?, long, MemoryMappedFileAccess)](https://learn.microsoft.com/dotnet/api/System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile)
| [System.TimeZoneInfo.Local](https://learn.microsoft.com/dotnet/api/System.TimeZoneInfo.Local)
| [System.Net.Sockets.Socket.SendPacketsAsync(SocketAsyncEventArgs)](https://learn.microsoft.com/dotnet/api/System.Net.Sockets.Socket.SendPacketsAsync)
For example, if you use any of the APIs listed above, your `PrivacyInfo.xcprivacy` would contain the `dict` element in the `NSPrivacyAccessedAPITypes` key's array as shown below:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>E174.1</string>
</array>
</dict>
</array>
</dict>
</plist>
```
Reason codes from [Disk space APIs][DiskSpaceAPIs] can be provided in the array following the `NSPrivacyAccessedAPITypeReasons` key.
[RequiredReasonAPI]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api
[PrivacyManifestFiles]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
[C#NETAPIs]: #c-net-apis-in-net-maui
[FileTimestampAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278393
[SystemBootTimeAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278394
[DiskSpaceAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278397
[ActiveKeyboardAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278400
[UserDefaultsAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278401

Просмотреть файл

@ -0,0 +1,46 @@
# Required Reasons API usage in .NET MAUI and Xamarin.Forms
The tables provide lists of C# .NET APIs that call the [Required Reasons APIs][RequiredReasonAPI] organized by category. If your application, SDK or package code calls any of the APIs from these lists, declare the reasons for their use in your privacy manifest file following the guidelines specified in Apples documentation on [Required Reasons APIs][RequiredReasonAPI].
**Note:** The following lists are verified only for .NET MAUI versions 8.0.0 and later.
### [User defaults APIs][UserDefaultsAPIs]
The following APIs either directly or indirectly access user defaults and require reasons for use. Use the string `NSPrivacyAccessedAPICategoryUserDefaults` as the value for the `NSPrivacyAccessedAPIType` key in your `NSPrivacyAccessedAPITypes` dictionary. If you only access the user defaults from the list of APIs below, then use the value `C56D.1` in the `NSPrivacyAccessedAPITypeReasons` array. Refer to [User defaults APIs][UserDefaultsAPIs] to determine the any additional relevant values to place in the `NSPrivacyAccessedAPITypeReasons` array.
| API usage |
| - |
| [NSUserDefaults](https://learn.microsoft.com/dotnet/api/foundation.nsuserdefaults) |
For example, if you use any of the APIs listed above, your `PrivacyInfo.xcprivacy` would contain the `dict` element in the `NSPrivacyAccessedAPITypes` key's array as shown below:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>...</string>
</array>
</dict>
</array>
</dict>
</plist>
```
Reason codes from [User defaults APIs][UserDefaultsAPIs] need to be provided in the array following the `NSPrivacyAccessedAPITypeReasons` key.
[RequiredReasonAPI]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api
[PrivacyManifestFiles]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
[C#NETAPIs]: #c-net-apis-in-net-maui
[FileTimestampAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278393
[SystemBootTimeAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278394
[DiskSpaceAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278397
[ActiveKeyboardAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278400
[UserDefaultsAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278401

Просмотреть файл

@ -0,0 +1,189 @@
# Required Reasons API usage in .NET for iOS, tvOS, and Xamarin.iOS
The tables provide lists of C# .NET APIs that call the [Required Reasons APIs][RequiredReasonAPI] organized by category. If your application, SDK or package code calls any of the APIs from these lists, declare the reasons for their use in your privacy manifest file following the guidelines specified in Apples documentation on [Required Reasons APIs][RequiredReasonAPI].
**Note:** The following lists are verified only for .NET for iOS, tvOS and Xamarin.iOS versions 8.0.4 and later.
### [File timestamp APIs][FileTimestampAPIs]
The following APIs either directly or indirectly access file timestamps and require reasons for use. Use the string `NSPrivacyAccessedAPICategoryFileTimestamp` as the value for the `NSPrivacyAccessedAPIType` key in your `NSPrivacyAccessedAPITypes` dictionary. Refer to [File timestamp APIs][FileTimestampAPIs] for any additional relevent values to add to the `NSPrivacyAccessedAPITypeReasons` array.
| Foundation APIs | UIKit APIs | AppKit APIs |
| - | - | - |
| [NSFileManager.CreationDate](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.creationdate) | [UIDocument.FileModificationDate](https://learn.microsoft.com/dotnet/api/uikit.uidocument.filemodificationdate) | [NSDocument.FileModificationDate](https://learn.microsoft.com/dotnet/api/appkit.nsdocument.filemodificationdate) |
| [NSFileManager.ModificationDate](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.modificationdate)
| [NSFileManager.SetAttributes(NSDictionary, string, NSError)](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.setattributes)
| [NSFileManager.SetAttributes(NSFileAttributes, string, NSError)](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.setattributes)
| [NSFileManager.SetAttributes(NSFileAttributes, string)](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.setattributes)
| [NSFileManager.CreateDirectory(string, bool, NSDictionary, NSError)](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.createdictionary)
| [NSFileManager.CreateDirectory(string, bool, NSFileAttributes, NSError)](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.createdictionary)
| [NSFileManager.CreateDirectory(string, bool, NSFileAttributes)](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.createdictionary)
| [NSFileManager.CreateFile(string, NSData, NSDictionary)](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.createfile)
| [NSFileManager.CreateFile(string, NSData, NSFileAttributes)](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.createfile)
| [NSFileManager.GetAttributes(string, NSError)](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.getattributes)
| [NSFileManager.GetAttributes(string)](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.getattributes)
| [NSDictionary.ToFileAttributes()](https://learn.microsoft.com/dotnet/api/foundation.nsdictionary.tofileattributes)
| [NSUrl.ContentModificationDateKey](https://learn.microsoft.com/dotnet/api/foundation.nsurl.contentmodificationdatekey)
| [NSUrl.CreationDateKey](https://learn.microsoft.com/dotnet/api/foundation.nsurl.creationdatekey)
For example, if you use any of the APIs listed above, your `PrivacyInfo.xcprivacy` would contain the `dict` element in the `NSPrivacyAccessedAPITypes` key's array as shown below:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>...</string>
</array>
</dict>
</array>
</dict>
</plist>
```
Additional reason codes from [File timestamp APIs][FileTimestampAPIs] can be provided in the array following the `NSPrivacyAccessedAPITypeReasons` key.
### [System boot time APIs][SystemBootTimeAPIs]
The following APIs either directly or indirectly access the system boot time and require reasons for use. Use the string `NSPrivacyAccessedAPICategorySystemBootTime` as the value for the `NSPrivacyAccessedAPIType` key in your `NSPrivacyAccessedAPITypes` dictionary. If you only access the system boot time from the list of APIs below, then use the `35F9.1` value in the `NSPrivacyAccessedAPITypeReasons` array.
| Foundation APIs | UIKit APIs | AppKit APIs |
| - | - | - |
| [NSProcessInfo.SystemUptime](https://learn.microsoft.com/dotnet/api/foundation.nsprocessinfo.systemuptime)
For example, if you use any of the APIs listed above, your `PrivacyInfo.xcprivacy` would contain the `dict` element in the `NSPrivacyAccessedAPITypes` key's array as shown below:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
</array>
</dict>
</plist>
```
### [Disk space APIs][DiskSpaceAPIs]
The following APIs either directly or indirectly access the available disk space and require reasons for use. Use the string `NSPrivacyAccessedAPICategoryDiskSpace` as the value for the `NSPrivacyAccessedAPIType` key in your `NSPrivacyAccessedAPITypes` dictionary. If you access the available disk space from the list of APIs below, then use [Disk space APIs][DiskSpaceAPIs] to determine the correct values to place in the `NSPrivacyAccessedAPITypeReasons` array.
| Foundation APIs | UIKit APIs | AppKit APIs |
| - | - | - |
| [NSUrl.VolumeAvailableCapacityKey](https://learn.microsoft.com/dotnet/api/foundation.nsurl.volumeavailablecapacitykey)
| [NSUrl.VolumeAvailableCapacityForImportantUsageKey](https://learn.microsoft.com/dotnet/api/foundation.nsurl.volumeavailablecapacityforimportantusagekey)
| [NSUrl.VolumeAvailableCapacityForOpportunisticUsageKey](https://learn.microsoft.com/dotnet/api/foundation.nsurl.volumeavailablecapacityforopportunisticusagekey)
| [NSUrl.VolumeTotalCapacityKey](https://learn.microsoft.com/dotnet/api/foundation.nsurl.volumetotalcapacity)
| [NSFileManager.SystemFreeSize](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.systemfreesize)
| [NSFileManager.SystemSize](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.systemsize)
| [NSFileManager.GetFileSystemAttributes(string, NSError)](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.getfilesystemattributes)
| [NSFileManager.GetFileSystemAttributes(string)](https://learn.microsoft.com/dotnet/api/foundation.nsfilemanager.getfilesystemattributes)
For example, if you use any of the APIs listed above, your `PrivacyInfo.xcprivacy` would contain the `dict` element in the `NSPrivacyAccessedAPITypes` key's array as shown below:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>...</string>
</array>
</dict>
</array>
</dict>
</plist>
```
Reason codes from [Disk space APIs][DiskSpaceAPIs] need to be provided in the array following the `NSPrivacyAccessedAPITypeReasons` key.
### [Active keyboard APIs][ActiveKeyboardAPIs]
The following APIs either directly or indirectly access the list of available keyboards and require reasons for use. Use the string `NSPrivacyAccessedAPICategoryActiveKeyboards` as the value for the `NSPrivacyAccessedAPIType` key in your `NSPrivacyAccessedAPITypes` dictionary. If you access the list of available keyboards from the list of APIs below, then use [Active keyboard APIs][ActiveKeyboardAPIs] to determine the correct values to place in the `NSPrivacyAccessedAPITypeReasons` array.
| Foundation APIs | UIKit APIs | AppKit APIs |
| - | - | - |
| | [UITextInputMode.ActiveInputModes](https://learn.microsoft.com/dotnet/api/appkit.uitextinputmode.activeinputmodes)
For example, if you use any of the APIs listed above, your `PrivacyInfo.xcprivacy` would contain the `dict` element in the `NSPrivacyAccessedAPITypes` key's array as shown below:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryActiveKeyboards</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>...</string>
</array>
</dict>
</array>
</dict>
</plist>
```
Reason codes from [Active keyboard APIs][ActiveKeyboardAPIs] need to be provided in the array following the `NSPrivacyAccessedAPITypeReasons` key.
### [User defaults APIs][UserDefaultsAPIs]
The following APIs either directly or indirectly access user defaults and require reasons for use. Use the string `NSPrivacyAccessedAPICategoryUserDefaults` as the value for the `NSPrivacyAccessedAPIType` key in your `NSPrivacyAccessedAPITypes` dictionary. If you only access the user defaults from the list of APIs below, then use the value `C56D.1` in the `NSPrivacyAccessedAPITypeReasons` array. Refer to [User defaults APIs][UserDefaultsAPIs] to determine the any additional relevant values to place in the `NSPrivacyAccessedAPITypeReasons` array.
| Foundation APIs | UIKit APIs | AppKit APIs |
| - | - | - |
| [NSUserDefaults](https://learn.microsoft.com/dotnet/api/foundation.nsuserdefaults) | | [NSUserDefaultsController.NSUserDefaultsController(NSUserDefaults, NSDictionary)](https://learn.microsoft.com/dotnet/api/appkit.nsuserdefaultscontroller.-ctor#appkit-nsuserdefaultscontroller-ctor(foundation-nsuserdefaults-foundation-nsdictionary))
| | | [NSUserDefaultsController.Defaults](https://learn.microsoft.com/dotnet/api/appkit.nsuserdefaultscontroller.defaults)
| | | [NSUserDefaultsController.SharedUserDefaultsController](https://learn.microsoft.com/dotnet/api/appkit.nsuserdefaultscontroller.shareduserdefaultscontroller)
For example, if you use any of the APIs listed above, your `PrivacyInfo.xcprivacy` would contain the `dict` element in the `NSPrivacyAccessedAPITypes` key's array as shown below:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>...</string>
</array>
</dict>
</array>
</dict>
</plist>
```
Reason codes from [User defaults APIs][UserDefaultsAPIs] need to be provided in the array following the `NSPrivacyAccessedAPITypeReasons` key.
[RequiredReasonAPI]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api
[PrivacyManifestFiles]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
[C#NETAPIs]: #c-net-apis-in-net-maui
[FileTimestampAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278393
[SystemBootTimeAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278394
[DiskSpaceAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278397
[ActiveKeyboardAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278400
[UserDefaultsAPIs]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278401

Просмотреть файл

@ -165,6 +165,12 @@
<comment>The following are literal names and should not be translated: Xcode, Apple SDK, Visual Studio
{0} - The selected Xcode / Apple SDK directory.</comment>
</data>
<data name="E0044v2" xml:space="preserve">
<value>Could not find a valid Xcode app bundle at '{0}'. Please verify that 'xcode-select -p' points to your Xcode installation. For more information see https://aka.ms/macios-missing-xcode.
</value>
<comment>The following are literal names and should not be translated: Xcode</comment>
</data>
<data name="E0045" xml:space="preserve">
<value>Could not find valid a usable Xcode developer path

Просмотреть файл

@ -260,7 +260,7 @@ namespace Xamarin.MacDev.Tasks {
// SupportedOSPlatformVersion is the iOS version for Mac Catalyst.
// But we need to store the macOS version in the app manifest, so convert it to the macOS version here.
if (!MacCatalystSupport.TryGetMacOSVersion (Sdks.GetAppleSdk (Platform).GetSdkPath (SdkVersion), SupportedOSPlatformVersion, out var convertedVersion, out var knowniOSVersions)) {
Log.LogError (MSBStrings.E0188, SupportedOSPlatformVersion, string.Join (", ", knowniOSVersions));
Log.LogError (MSBStrings.E0188, SupportedOSPlatformVersion, string.Join (", ", knowniOSVersions.OrderBy (v => v)));
return false;
}
convertedSupportedOSPlatformVersion = convertedVersion;
@ -274,7 +274,7 @@ namespace Xamarin.MacDev.Tasks {
if (!string.IsNullOrEmpty (minimumiOSVersionInManifest)) {
// Convert to the macOS version
if (!MacCatalystSupport.TryGetMacOSVersion (Sdks.GetAppleSdk (Platform).GetSdkPath (SdkVersion), minimumiOSVersionInManifest!, out var convertedVersion, out var knowniOSVersions)) {
Log.LogError (MSBStrings.E0188, minimumiOSVersionInManifest, string.Join (", ", knowniOSVersions));
Log.LogError (MSBStrings.E0188, minimumiOSVersionInManifest, string.Join (", ", knowniOSVersions.OrderBy (v => v)));
return false;
}
minimumOSVersionInManifest = convertedVersion;

Просмотреть файл

@ -235,14 +235,7 @@ namespace Xamarin.MacDev.Tasks {
{
var currentSdk = CurrentSdk;
if (!currentSdk.IsInstalled) {
string ideSdkPath;
if (string.IsNullOrEmpty (SessionId))
// SessionId is only and always defined on windows.
// We can't check 'Environment.OSVersion.Platform' since the base tasks are always executed on the Mac.
ideSdkPath = "(Projects > SDK Locations > Apple > Apple SDK)";
else
ideSdkPath = "(Tools > Options > Xamarin > iOS Settings > Apple SDK)";
Log.LogError (MSBStrings.E0044, AppleSdkSettings.InvalidDeveloperRoot, ideSdkPath);
Log.LogError (MSBStrings.E0044v2 /* Could not find a valid Xcode app bundle at '{0}'. Please verify that 'xcode-select -p' points to your Xcode installation. For more information see https://aka.ms/macios-missing-xcode. */, AppleSdkSettings.InvalidDeveloperRoot);
return false;
}
Log.LogMessage (MessageImportance.Low, "DeveloperRoot: {0}", currentSdk.DeveloperRoot);

Просмотреть файл

@ -74,7 +74,7 @@ namespace Xamarin.MacDev.Tasks {
// The minimum version in the Info.plist is the macOS version. However, the rest of our tooling
// expects the iOS version, so expose that.
if (!MacCatalystSupport.TryGetiOSVersion (Sdks.GetAppleSdk (Platform).GetSdkPath (), MinimumOSVersion!, out var convertedVersion, out var knownMacOSVersions))
Log.LogError (MSBStrings.E0187, MinimumOSVersion, string.Join (", ", knownMacOSVersions));
Log.LogError (MSBStrings.E0187, MinimumOSVersion, string.Join (", ", knownMacOSVersions.OrderBy (v => v)));
MinimumOSVersion = convertedVersion;
}

Просмотреть файл

@ -0,0 +1,34 @@
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using ObjCRuntime;
#nullable enable
namespace AVFoundation {
public partial class AVSpeechSynthesizer {
#if !XAMCORE_5_0
#if NET
[SupportedOSPlatform ("tvos13.0")]
[SupportedOSPlatform ("ios13.0")]
[SupportedOSPlatform ("maccatalyst")]
[SupportedOSPlatform ("macos")]
#endif
[BindingImpl (BindingImplOptions.Optimizable)]
[Obsolete ("Do not use this API, it doesn't work correctly. Use the non-Async version (WriteUtterance) instead.")]
[EditorBrowsable (EditorBrowsableState.Never)]
public unsafe virtual Task<AVAudioBuffer> WriteUtteranceAsync (AVSpeechUtterance utterance)
{
var tcs = new TaskCompletionSource<AVAudioBuffer> ();
WriteUtterance (utterance, (obj_) => {
tcs.SetResult (obj_!);
});
return tcs.Task;
}
#endif
}
}

Просмотреть файл

@ -7,11 +7,30 @@ namespace Compression {
// this enum as per the headers is an int NOT an NSInteger
public enum CompressionAlgorithm {
/// <summary>The LZ4 compression format.</summary>
LZ4 = 0x100,
/// <summary>The <see cref="LZ4">LZ4</see> compression format, without block headers.</summary>
LZ4Raw = 0x101,
/// <summary>The Lempel–Ziv Finite State Entropy (LZFSE) compression format.</summary>
/// <remarks>This is the format Apple recommends on Apple platforms.</remarks>
Lzfse = 0x801,
/// <summary>The Lempel–Ziv–Markov (LZMA) compression format.</summary>
/// <remarks>The encoder in the Compression framework only supports level 6. The decoder supports all compression levels.</remarks>
Lzma = 0x306,
/// <summary>The zlib compression format. This is the compression format most compatible with other platforms.</summary>
/// <remarks>The encoder in the Compression framework only supports level 5. The decoder supports all compression levels.</remarks>
Zlib = 0x205,
/// <summary>The Brotli compression format.</summary>
/// <remarks>The encoder in the Compression framework only supports the Brotli level 2 encoder. The decoder supports all compression levels.</remarks>
Brotli = 0xB02,
/// <summary>The LZBitmap compression format.</summary>
/// <remarks>This compression algorithm is only available on Apple devices.</remarks>
#if NET
[iOS (15, 0), Mac (12, 0), TV (15, 0), MacCatalyst (15, 0)]
#else
[iOS (15, 0), Mac (12, 0), TV (15, 0), Watch (8, 0)]
#endif
LZBitmap = 0x702,
}
[Internal]

Просмотреть файл

@ -68,17 +68,17 @@ namespace CoreMedia {
internal unsafe delegate* unmanaged<IntPtr, IntPtr, byte> XisDataReady;
internal unsafe delegate* unmanaged<IntPtr, IntPtr, IntPtr, int> Xcompare;
#else
internal BufferGetTimeCallback? XgetDecodeTimeStamp;
internal BufferGetTimeCallback? XgetPresentationTimeStamp;
internal BufferGetTimeCallback? XgetDuration;
internal BufferGetBooleanCallback? XisDataReady;
internal BufferCompareCallback? Xcompare;
internal IntPtr XgetDecodeTimeStamp;
internal IntPtr XgetPresentationTimeStamp;
internal IntPtr XgetDuration;
internal IntPtr XisDataReady;
internal IntPtr Xcompare;
#endif
internal IntPtr cfStringPtr_dataBecameReadyNotification;
#if NET
internal unsafe delegate* unmanaged<IntPtr, IntPtr, nint> XgetSize;
#else
internal BufferGetSizeCallback? XgetSize;
internal IntPtr XgetSize;
#endif
}
@ -107,10 +107,7 @@ namespace CoreMedia {
// CMItemCount -> CMBase.h (looks weird but it's 4 bytes in 32bits and 8 bytes in 64bits, x86_64 and ARM64)
[DllImport (Constants.CoreMediaLibrary)]
extern static OSStatus CMBufferQueueCreate (/* CFAllocatorRef */ IntPtr allocator, /* CMItemCount */ nint capacity, CMBufferCallbacks cbacks, /* CMBufferQueueRef* */ out IntPtr result);
[DllImport (Constants.CoreMediaLibrary)]
extern static OSStatus CMBufferQueueCreate (/* CFAllocatorRef */ IntPtr allocator, /* CMItemCount */ nint capacity, /* CMBufferCallbacks */ IntPtr cbacks, /* CMBufferQueueRef* */ out IntPtr result);
unsafe extern static OSStatus CMBufferQueueCreate (/* CFAllocatorRef */ IntPtr allocator, /* CMItemCount */ nint capacity, CMBufferCallbacks* cbacks, /* CMBufferQueueRef* */ IntPtr* result);
CMBufferQueue (IntPtr handle, bool owns, int count)
: base (handle, owns)
@ -155,13 +152,13 @@ namespace CoreMedia {
var cbacks = new CMBufferCallbacks () {
version = (uint) (getTotalSize is null ? 0 : 1),
refcon = GCHandle.ToIntPtr (bq.gch),
XgetDecodeTimeStamp = getDecodeTimeStamp is not null ? GetDecodeTimeStamp : null,
XgetPresentationTimeStamp = getPresentationTimeStamp is not null ? GetPresentationTimeStamp : null,
XgetDuration = getDuration is not null ? GetDuration : null,
XisDataReady = isDataReady is not null ? GetDataReady : null,
Xcompare = compare is not null ? Compare : null,
XgetDecodeTimeStamp = getDecodeTimeStamp is not null ? Marshal.GetFunctionPointerForDelegate (GetDecodeTimeStampCallback) : IntPtr.Zero,
XgetPresentationTimeStamp = getPresentationTimeStamp is not null ? Marshal.GetFunctionPointerForDelegate (GetPresentationTimeStampCallback) : IntPtr.Zero,
XgetDuration = getDuration is not null ? Marshal.GetFunctionPointerForDelegate (GetDurationCallback) : IntPtr.Zero,
XisDataReady = isDataReady is not null ? Marshal.GetFunctionPointerForDelegate (GetDataReadyCallback) : IntPtr.Zero,
Xcompare = compare is not null ? Marshal.GetFunctionPointerForDelegate (CompareCallback) : IntPtr.Zero,
cfStringPtr_dataBecameReadyNotification = dataBecameReadyNotification is null ? IntPtr.Zero : dataBecameReadyNotification.Handle,
XgetSize = getTotalSize is not null ? GetTotalSize : null
XgetSize = getTotalSize is not null ? Marshal.GetFunctionPointerForDelegate (GetTotalSizeCallback) : IntPtr.Zero
};
#endif
@ -172,7 +169,12 @@ namespace CoreMedia {
bq.compare = compare;
bq.getTotalSize = getTotalSize;
if (CMBufferQueueCreate (IntPtr.Zero, count, cbacks, out var handle) == 0) {
OSStatus rv;
IntPtr handle;
unsafe {
rv = CMBufferQueueCreate (IntPtr.Zero, count, &cbacks, &handle);
}
if (rv == 0) {
bq.InitializeHandle (handle);
return bq;
}
@ -182,7 +184,7 @@ namespace CoreMedia {
}
[DllImport (Constants.CoreMediaLibrary)]
unsafe extern static /* CMBufferCallbacks */ IntPtr CMBufferQueueGetCallbacksForUnsortedSampleBuffers ();
unsafe extern static /* CMBufferCallbacks */ CMBufferCallbacks* CMBufferQueueGetCallbacksForUnsortedSampleBuffers ();
public static CMBufferQueue? CreateUnsorted (int count)
{
@ -191,10 +193,13 @@ namespace CoreMedia {
// and can cause a crash, e.g. bug #17330
// since we don't need the managed bcallbacks (it's the native callback that will be used for this queue)
// then we can simply use an IntPtr to represent them (no GCHandle)
var callbacks = CMBufferQueueGetCallbacksForUnsortedSampleBuffers ();
if (CMBufferQueueCreate (IntPtr.Zero, count, callbacks, out var handle) == 0)
return new CMBufferQueue (handle, true, count);
IntPtr handle;
unsafe {
var callbacks = CMBufferQueueGetCallbacksForUnsortedSampleBuffers ();
if (CMBufferQueueCreate (IntPtr.Zero, count, callbacks, &handle) == 0)
return new CMBufferQueue (handle, true, count);
}
return null;
}
@ -348,6 +353,7 @@ namespace CoreMedia {
#if NET
[UnmanagedCallersOnly]
#else
static BufferGetTimeCallback GetDecodeTimeStampCallback = GetDecodeTimeStamp;
#if !MONOMAC
[MonoPInvokeCallback (typeof (BufferGetTimeCallback))]
#endif
@ -363,6 +369,7 @@ namespace CoreMedia {
#if NET
[UnmanagedCallersOnly]
#else
static BufferGetTimeCallback GetPresentationTimeStampCallback = GetPresentationTimeStamp;
#if !MONOMAC
[MonoPInvokeCallback (typeof (BufferGetTimeCallback))]
#endif
@ -378,6 +385,7 @@ namespace CoreMedia {
#if NET
[UnmanagedCallersOnly]
#else
static BufferGetTimeCallback GetDurationCallback = GetDuration;
#if !MONOMAC
[MonoPInvokeCallback (typeof (BufferGetTimeCallback))]
#endif
@ -394,6 +402,7 @@ namespace CoreMedia {
[UnmanagedCallersOnly]
static byte GetDataReady (IntPtr buffer, IntPtr refcon)
#else
static BufferGetBooleanCallback GetDataReadyCallback = GetDataReady;
#if !MONOMAC
[MonoPInvokeCallback (typeof (BufferGetBooleanCallback))]
#endif
@ -414,6 +423,7 @@ namespace CoreMedia {
#if NET
[UnmanagedCallersOnly]
#else
static BufferCompareCallback CompareCallback = Compare;
#if !MONOMAC
[MonoPInvokeCallback (typeof (BufferCompareCallback))]
#endif
@ -429,6 +439,7 @@ namespace CoreMedia {
#if NET
[UnmanagedCallersOnly]
#else
static BufferGetSizeCallback GetTotalSizeCallback = GetTotalSize;
#if !MONOMAC
[MonoPInvokeCallback (typeof (BufferGetSizeCallback))]
#endif

Просмотреть файл

@ -11,6 +11,7 @@
#nullable enable
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Collections.Generic;
@ -65,17 +66,17 @@ namespace CoreMedia {
}
[DllImport (Constants.CoreMediaLibrary)]
extern static CMSampleBufferError CMAudioSampleBufferCreateWithPacketDescriptions (
unsafe extern static CMSampleBufferError CMAudioSampleBufferCreateWithPacketDescriptions (
/* CFAllocatorRef */ IntPtr allocator,
/* CMBlockBufferRef */ IntPtr dataBuffer,
/* Boolean */ [MarshalAs (UnmanagedType.I1)] bool dataReady,
/* Boolean */ byte dataReady,
/* CMSampleBufferMakeDataReadyCallback */ IntPtr makeDataReadyCallback,
/* void */ IntPtr makeDataReadyRefcon,
/* CMFormatDescriptionRef */ IntPtr formatDescription,
/* CMItemCount */ nint numSamples,
CMTime sbufPTS,
/* AudioStreamPacketDescription* */ AudioStreamPacketDescription [] packetDescriptions,
/* CMSampleBufferRef* */ out IntPtr sBufOut);
/* AudioStreamPacketDescription* */ AudioStreamPacketDescription* packetDescriptions,
/* CMSampleBufferRef* */ IntPtr* sBufOut);
public static CMSampleBuffer? CreateWithPacketDescriptions (CMBlockBuffer? dataBuffer, CMFormatDescription formatDescription, int samplesCount,
CMTime sampleTimestamp, AudioStreamPacketDescription [] packetDescriptions, out CMSampleBufferError error)
@ -86,13 +87,18 @@ namespace CoreMedia {
ObjCRuntime.ThrowHelper.ThrowArgumentOutOfRangeException (nameof (samplesCount), "Negative");
IntPtr buffer;
error = CMAudioSampleBufferCreateWithPacketDescriptions (IntPtr.Zero,
dataBuffer.GetHandle (),
true, IntPtr.Zero, IntPtr.Zero,
formatDescription.Handle,
samplesCount, sampleTimestamp,
packetDescriptions,
out buffer);
unsafe {
fixed (AudioStreamPacketDescription* packetDescriptionsPtr = packetDescriptions) {
error = CMAudioSampleBufferCreateWithPacketDescriptions (
IntPtr.Zero,
dataBuffer.GetHandle (),
1, IntPtr.Zero, IntPtr.Zero,
formatDescription.Handle,
samplesCount, sampleTimestamp,
packetDescriptionsPtr,
&buffer);
}
}
if (error != CMSampleBufferError.None)
return null;
@ -106,7 +112,7 @@ namespace CoreMedia {
/* CMSampleBufferRef */ IntPtr originalSBuf,
/* CMItemCount */ nint numSampleTimingEntries,
CMSampleTimingInfo* sampleTimingArray,
/* CMSampleBufferRef* */ out IntPtr sBufCopyOut
/* CMSampleBufferRef* */ IntPtr* sBufCopyOut
);
public static CMSampleBuffer? CreateWithNewTiming (CMSampleBuffer original, CMSampleTimingInfo []? timing)
@ -124,7 +130,7 @@ namespace CoreMedia {
IntPtr handle;
fixed (CMSampleTimingInfo* t = timing) {
status = CMSampleBufferCreateCopyWithNewTiming (IntPtr.Zero, original.Handle, count, t, out handle);
status = CMSampleBufferCreateCopyWithNewTiming (IntPtr.Zero, original.Handle, count, t, &handle);
if (status != (OSStatus) 0)
return null;
}
@ -219,15 +225,15 @@ namespace CoreMedia {
*/
[DllImport (Constants.CoreMediaLibrary)]
static extern /* OSStatus */ CMSampleBufferError CMSampleBufferCreateForImageBuffer (
unsafe static extern /* OSStatus */ CMSampleBufferError CMSampleBufferCreateForImageBuffer (
/* CFAllocatorRef */ IntPtr allocator,
/* CVImageBufferRef */ IntPtr imageBuffer,
/* Boolean */ [MarshalAs (UnmanagedType.I1)] bool dataReady,
/* Boolean */ byte dataReady,
/* CMSampleBufferMakeDataReadyCallback */ IntPtr makeDataReadyCallback,
/* void* */ IntPtr makeDataReadyRefcon,
/* CMVideoFormatDescriptionRef */ IntPtr formatDescription,
/* const CMSampleTimingInfo* */ ref CMSampleTimingInfo sampleTiming,
/* CMSampleBufferRef* */ out IntPtr bufOut
/* const CMSampleTimingInfo* */ CMSampleTimingInfo* sampleTiming,
/* CMSampleBufferRef* */ IntPtr* bufOut
);
public static CMSampleBuffer? CreateForImageBuffer (CVImageBuffer imageBuffer, bool dataReady, CMVideoFormatDescription formatDescription, CMSampleTimingInfo sampleTiming, out CMSampleBufferError error)
@ -238,12 +244,15 @@ namespace CoreMedia {
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (formatDescription));
IntPtr buffer;
error = CMSampleBufferCreateForImageBuffer (IntPtr.Zero,
imageBuffer.Handle, dataReady,
IntPtr.Zero, IntPtr.Zero,
formatDescription.Handle,
ref sampleTiming,
out buffer);
unsafe {
error = CMSampleBufferCreateForImageBuffer (
IntPtr.Zero,
imageBuffer.Handle, dataReady.AsByte (),
IntPtr.Zero, IntPtr.Zero,
formatDescription.Handle,
&sampleTiming,
&buffer);
}
if (error != CMSampleBufferError.None)
return null;
@ -252,12 +261,11 @@ namespace CoreMedia {
}
[DllImport (Constants.CoreMediaLibrary)]
[return: MarshalAs (UnmanagedType.I1)]
extern static /* Boolean */ bool CMSampleBufferDataIsReady (/* CMSampleBufferRef */ IntPtr sbuf);
extern static /* Boolean */ byte CMSampleBufferDataIsReady (/* CMSampleBufferRef */ IntPtr sbuf);
public bool DataIsReady {
get {
return CMSampleBufferDataIsReady (Handle);
return CMSampleBufferDataIsReady (Handle) != 0;
}
}
@ -417,11 +425,11 @@ namespace CoreMedia {
}
[DllImport (Constants.CoreMediaLibrary)]
extern static /* CFArrayRef */ IntPtr CMSampleBufferGetSampleAttachmentsArray (/* CMSampleBufferRef */ IntPtr sbuf, /* Boolean */ [MarshalAs (UnmanagedType.I1)] bool createIfNecessary);
extern static /* CFArrayRef */ IntPtr CMSampleBufferGetSampleAttachmentsArray (/* CMSampleBufferRef */ IntPtr sbuf, /* Boolean */ byte createIfNecessary);
public CMSampleBufferAttachmentSettings? [] GetSampleAttachments (bool createIfNecessary)
{
var cfArrayRef = CMSampleBufferGetSampleAttachmentsArray (Handle, createIfNecessary);
var cfArrayRef = CMSampleBufferGetSampleAttachmentsArray (Handle, createIfNecessary.AsByte ());
if (cfArrayRef == IntPtr.Zero) {
return Array.Empty<CMSampleBufferAttachmentSettings> ();
} else {
@ -458,7 +466,7 @@ namespace CoreMedia {
/* CMSampleBufferRef */ IntPtr sbuf,
/* CMItemCount */ nint timingArrayEntries,
CMSampleTimingInfo* timingArrayOut,
/* CMItemCount* */ out nint timingArrayEntriesNeededOut
/* CMItemCount* */ nint* timingArrayEntriesNeededOut
);
public CMSampleTimingInfo []? GetSampleTimingInfo ()
@ -476,7 +484,7 @@ namespace CoreMedia {
if (Handle == IntPtr.Zero)
return null;
status = CMSampleBufferGetSampleTimingInfoArray (Handle, 0, null, out count);
status = CMSampleBufferGetSampleTimingInfoArray (Handle, 0, null, &count);
if (status != (OSStatus) 0)
return null;
@ -486,7 +494,7 @@ namespace CoreMedia {
return pInfo;
fixed (CMSampleTimingInfo* info = pInfo) {
status = CMSampleBufferGetSampleTimingInfoArray (Handle, count, info, out count);
status = CMSampleBufferGetSampleTimingInfoArray (Handle, count, info, &count);
if (status != (OSStatus) 0)
return null;
}
@ -525,12 +533,11 @@ namespace CoreMedia {
}
[DllImport (Constants.CoreMediaLibrary)]
[return: MarshalAs (UnmanagedType.I1)]
extern static /* Boolean */ bool CMSampleBufferIsValid (/* CMSampleBufferRef */ IntPtr sbuf);
extern static /* Boolean */ byte CMSampleBufferIsValid (/* CMSampleBufferRef */ IntPtr sbuf);
public bool IsValid {
get {
return CMSampleBufferIsValid (Handle);
return CMSampleBufferIsValid (Handle) != 0;
}
}
@ -680,14 +687,14 @@ namespace CoreMedia {
[SupportedOSPlatform ("tvos")]
#endif
[DllImport (Constants.CoreMediaLibrary)]
extern static /* OSStatus */ CMSampleBufferError CMAudioSampleBufferCreateReadyWithPacketDescriptions (
unsafe extern static /* OSStatus */ CMSampleBufferError CMAudioSampleBufferCreateReadyWithPacketDescriptions (
/* CFAllocatorRef */ IntPtr allocator,
/* CMBlockBufferRef */ IntPtr dataBuffer,
/* CMFormatDescriptionRef */ IntPtr formatDescription,
/* CMItemCount */ nint numSamples,
CMTime sbufPTS,
/* AudioStreamPacketDescription* */ AudioStreamPacketDescription []? packetDescriptions,
/* CMSampleBufferRef* */ out IntPtr sBufOut);
/* AudioStreamPacketDescription* */ AudioStreamPacketDescription* packetDescriptions,
/* CMSampleBufferRef* */ IntPtr* sBufOut);
#if NET
[SupportedOSPlatform ("ios")]
@ -705,8 +712,19 @@ namespace CoreMedia {
if (samplesCount <= 0)
ObjCRuntime.ThrowHelper.ThrowArgumentOutOfRangeException (nameof (samplesCount), "smaller than 0");
error = CMAudioSampleBufferCreateReadyWithPacketDescriptions (IntPtr.Zero, dataBuffer.Handle,
formatDescription.Handle, samplesCount, sampleTimestamp, packetDescriptions, out var buffer);
IntPtr buffer;
unsafe {
fixed (AudioStreamPacketDescription* packetDescriptionsPtr = packetDescriptions) {
error = CMAudioSampleBufferCreateReadyWithPacketDescriptions (
IntPtr.Zero,
dataBuffer.Handle,
formatDescription.Handle,
samplesCount,
sampleTimestamp,
packetDescriptionsPtr,
&buffer);
}
}
if (error != CMSampleBufferError.None)
return null;
@ -721,16 +739,16 @@ namespace CoreMedia {
[SupportedOSPlatform ("tvos")]
#endif
[DllImport (Constants.CoreMediaLibrary)]
extern static /* OSStatus */ CMSampleBufferError CMSampleBufferCreateReady (
unsafe extern static /* OSStatus */ CMSampleBufferError CMSampleBufferCreateReady (
/* CFAllocatorRef */ IntPtr allocator,
/* CMBlockBufferRef */ IntPtr dataBuffer,
/* CMFormatDescriptionRef */ IntPtr formatDescription, // can be null
/* CMItemCount */ nint numSamples, // can be 0
/* CMItemCount */ nint numSampleTimingEntries, // 0, 1 or numSamples
CMSampleTimingInfo []? sampleTimingArray, // can be null
CMSampleTimingInfo* sampleTimingArray, // can be null
/* CMItemCount */ nint numSampleSizeEntries, // 0, 1 or numSamples
/* size_t* */ nuint []? sampleSizeArray, // can be null
/* CMSampleBufferRef* */ out IntPtr sBufOut);
/* size_t* */ nuint* sampleSizeArray, // can be null
/* CMSampleBufferRef* */ IntPtr* sBufOut);
#if NET
[SupportedOSPlatform ("ios")]
@ -751,8 +769,22 @@ namespace CoreMedia {
var fdh = formatDescription.GetHandle ();
var timingCount = sampleTimingArray is null ? 0 : sampleTimingArray.Length;
var sizeCount = sampleSizeArray is null ? 0 : sampleSizeArray.Length;
error = CMSampleBufferCreateReady (IntPtr.Zero, dataBuffer.Handle, fdh, samplesCount, timingCount,
sampleTimingArray, sizeCount, sampleSizeArray, out buffer);
unsafe {
fixed (CMSampleTimingInfo* sampleTimingArrayPtr = sampleTimingArray) {
fixed (nuint* sampleSizeArrayPtr = sampleSizeArray) {
error = CMSampleBufferCreateReady (
IntPtr.Zero,
dataBuffer.Handle,
fdh,
samplesCount,
timingCount,
sampleTimingArrayPtr,
sizeCount,
sampleSizeArrayPtr,
&buffer);
}
}
}
if (error != CMSampleBufferError.None)
return null;
@ -767,12 +799,12 @@ namespace CoreMedia {
[SupportedOSPlatform ("tvos")]
#endif
[DllImport (Constants.CoreMediaLibrary)]
extern static /* OSStatus */ CMSampleBufferError CMSampleBufferCreateReadyWithImageBuffer (
unsafe extern static /* OSStatus */ CMSampleBufferError CMSampleBufferCreateReadyWithImageBuffer (
/* CFAllocatorRef */ IntPtr allocator,
/* CVImageBufferRef */ IntPtr imageBuffer,
/* CMFormatDescriptionRef */ IntPtr formatDescription, // not null
/* const CMSampleTimingInfo * CM_NONNULL */ ref CMSampleTimingInfo sampleTiming,
/* CMSampleBufferRef* */ out IntPtr sBufOut);
/* const CMSampleTimingInfo * CM_NONNULL */ CMSampleTimingInfo* sampleTiming,
/* CMSampleBufferRef* */ IntPtr* sBufOut);
#if !NET
#if !WATCH
@ -803,8 +835,14 @@ namespace CoreMedia {
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (formatDescription));
IntPtr buffer;
error = CMSampleBufferCreateReadyWithImageBuffer (IntPtr.Zero, imageBuffer.Handle,
formatDescription.Handle, ref sampleTiming, out buffer);
unsafe {
error = CMSampleBufferCreateReadyWithImageBuffer (
IntPtr.Zero,
imageBuffer.Handle,
formatDescription.Handle,
(CMSampleTimingInfo*) Unsafe.AsPointer<CMSampleTimingInfo> (ref sampleTiming),
&buffer);
}
if (error != CMSampleBufferError.None)
return null;

Просмотреть файл

@ -7,6 +7,7 @@
//
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Foundation;
@ -71,34 +72,39 @@ namespace CoreMedia {
[SupportedOSPlatform ("tvos")]
#endif
[DllImport (Constants.CoreMediaLibrary)]
extern static /* OSStatus */ CMClockError CMAudioClockCreate (/* CFAllocatorRef */ IntPtr allocator, /* CMClockRef* */ out IntPtr clockOut);
unsafe extern static /* OSStatus */ CMClockError CMAudioClockCreate (/* CFAllocatorRef */ IntPtr allocator, /* CMClockRef* */ IntPtr* clockOut);
public static CMClock? CreateAudioClock (out CMClockError clockError)
{
IntPtr ptr;
clockError = CMAudioClockCreate (IntPtr.Zero, out ptr);
unsafe {
clockError = CMAudioClockCreate (IntPtr.Zero, &ptr);
}
return clockError == CMClockError.None ? new CMClock (ptr, true) : null;
}
#endif
[DllImport (Constants.CoreMediaLibrary)]
extern static /* OSStatus */ CMClockError CMClockGetAnchorTime (/* CMClockRef */ IntPtr clock, out CMTime outClockTime, out CMTime outReferenceClockTime);
unsafe extern static /* OSStatus */ CMClockError CMClockGetAnchorTime (/* CMClockRef */ IntPtr clock, CMTime* outClockTime, CMTime* outReferenceClockTime);
public CMClockError GetAnchorTime (out CMTime clockTime, out CMTime referenceClockTime)
{
return CMClockGetAnchorTime (Handle, out clockTime, out referenceClockTime);
clockTime = default;
referenceClockTime = default;
unsafe {
return CMClockGetAnchorTime (Handle, (CMTime*) Unsafe.AsPointer<CMTime> (ref clockTime), (CMTime*) Unsafe.AsPointer<CMTime> (ref referenceClockTime));
}
}
[DllImport (Constants.CoreMediaLibrary)]
[return: MarshalAs (UnmanagedType.I1)]
extern static /* Boolean */ bool CMClockMightDrift (/* CMClockRef */ IntPtr clock, /* CMClockRef */ IntPtr otherClock);
extern static /* Boolean */ byte CMClockMightDrift (/* CMClockRef */ IntPtr clock, /* CMClockRef */ IntPtr otherClock);
public bool MightDrift (CMClock otherClock)
{
if (otherClock is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (otherClock));
return CMClockMightDrift (Handle, otherClock.Handle);
return CMClockMightDrift (Handle, otherClock.Handle) != 0;
}
[DllImport (Constants.CoreMediaLibrary)]
@ -156,14 +162,18 @@ namespace CoreMedia {
[Deprecated (PlatformName.WatchOS, 6, 0)]
#endif
[DllImport (Constants.CoreMediaLibrary)]
extern static /* OSStatus */ CMTimebaseError CMTimebaseCreateWithMasterClock (/* CFAllocatorRef */ IntPtr allocator, /* CMClockRef */ IntPtr masterClock, /* CMTimebaseRef* */ out IntPtr timebaseOut);
unsafe extern static /* OSStatus */ CMTimebaseError CMTimebaseCreateWithMasterClock (/* CFAllocatorRef */ IntPtr allocator, /* CMClockRef */ IntPtr masterClock, /* CMTimebaseRef* */ IntPtr* timebaseOut);
static IntPtr Create (CMClock masterClock)
{
if (masterClock is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (masterClock));
var error = CMTimebaseCreateWithMasterClock (IntPtr.Zero, masterClock.Handle, out var handle);
CMTimebaseError error;
IntPtr handle;
unsafe {
error = CMTimebaseCreateWithMasterClock (IntPtr.Zero, masterClock.Handle, &handle);
}
if (error != CMTimebaseError.None)
ObjCRuntime.ThrowHelper.ThrowArgumentException (error.ToString ());
return handle;
@ -190,14 +200,18 @@ namespace CoreMedia {
[Deprecated (PlatformName.WatchOS, 6, 0)]
#endif
[DllImport (Constants.CoreMediaLibrary)]
extern static /* OSStatus */ CMTimebaseError CMTimebaseCreateWithMasterTimebase (/* CFAllocatorRef */ IntPtr allocator, /* CMTimebaseRef */ IntPtr masterTimebase, /* CMTimebaseRef* */ out IntPtr timebaseOut);
unsafe extern static /* OSStatus */ CMTimebaseError CMTimebaseCreateWithMasterTimebase (/* CFAllocatorRef */ IntPtr allocator, /* CMTimebaseRef */ IntPtr masterTimebase, /* CMTimebaseRef* */ IntPtr* timebaseOut);
static IntPtr Create (CMTimebase masterTimebase)
{
if (masterTimebase is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (masterTimebase));
var error = CMTimebaseCreateWithMasterTimebase (IntPtr.Zero, masterTimebase.Handle, out var handle);
CMTimebaseError error;
IntPtr handle;
unsafe {
error = CMTimebaseCreateWithMasterTimebase (IntPtr.Zero, masterTimebase.Handle, &handle);
}
if (error != CMTimebaseError.None)
ObjCRuntime.ThrowHelper.ThrowArgumentException (error.ToString ());
return handle;
@ -220,14 +234,18 @@ namespace CoreMedia {
[MacCatalyst (15, 0)]
#endif
[DllImport (Constants.CoreMediaLibrary)]
static extern CMTimebaseError CMTimebaseCreateWithSourceClock (/* [NullAllowed] CFAllocatorRef */ IntPtr allocator, /* CMClock */ IntPtr sourceClock, /* CMTimebase */ out IntPtr timebaseOut);
unsafe static extern CMTimebaseError CMTimebaseCreateWithSourceClock (/* [NullAllowed] CFAllocatorRef */ IntPtr allocator, /* CMClock */ IntPtr sourceClock, /* CMTimebase */ IntPtr* timebaseOut);
static IntPtr Create (CFAllocator? allocator, CMClock sourceClock)
{
if (sourceClock is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (sourceClock));
var error = CMTimebaseCreateWithSourceClock (allocator.GetHandle (), sourceClock.Handle, out var handle);
CMTimebaseError error;
IntPtr handle;
unsafe {
error = CMTimebaseCreateWithSourceClock (allocator.GetHandle (), sourceClock.Handle, &handle);
}
if (error != CMTimebaseError.None)
ObjCRuntime.ThrowHelper.ThrowArgumentException (error.ToString ());
return handle;
@ -261,14 +279,18 @@ namespace CoreMedia {
[MacCatalyst (15, 0)]
#endif
[DllImport (Constants.CoreMediaLibrary)]
static extern CMTimebaseError CMTimebaseCreateWithSourceTimebase (/* [NullAllowed] CFAllocatorRef */ IntPtr allocator, /* CMTimebase */ IntPtr sourceTimebase, /* CMTimebase */ out IntPtr timebaseOut);
unsafe static extern CMTimebaseError CMTimebaseCreateWithSourceTimebase (/* [NullAllowed] CFAllocatorRef */ IntPtr allocator, /* CMTimebase */ IntPtr sourceTimebase, /* CMTimebase */ IntPtr* timebaseOut);
static IntPtr Create (CFAllocator? allocator, CMTimebase sourceTimebase)
{
if (sourceTimebase is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (sourceTimebase));
var error = CMTimebaseCreateWithSourceTimebase (allocator.GetHandle (), sourceTimebase.Handle, out var handle);
CMTimebaseError error;
IntPtr handle;
unsafe {
error = CMTimebaseCreateWithSourceTimebase (allocator.GetHandle (), sourceTimebase.Handle, &handle);
}
if (error != CMTimebaseError.None)
ObjCRuntime.ThrowHelper.ThrowArgumentException (error.ToString ());
return handle;
@ -508,11 +530,15 @@ namespace CoreMedia {
}
[DllImport (Constants.CoreMediaLibrary)]
extern static /* OSStatus */ CMTimebaseError CMTimebaseGetTimeAndRate (/* CMTimebaseRef */ IntPtr timebase, out CMTime time, /* Float64* */ out double rate);
unsafe extern static /* OSStatus */ CMTimebaseError CMTimebaseGetTimeAndRate (/* CMTimebaseRef */ IntPtr timebase, CMTime* time, /* Float64* */ double* rate);
public CMTimebaseError GetTimeAndRate (out CMTime time, out double rate)
{
return CMTimebaseGetTimeAndRate (Handle, out time, out rate);
time = default;
rate = default;
unsafe {
return CMTimebaseGetTimeAndRate (Handle, (CMTime*) Unsafe.AsPointer<CMTime> (ref time), (double*) Unsafe.AsPointer<double> (ref rate));
}
}
[DllImport (Constants.CoreMediaLibrary)]
@ -875,12 +901,12 @@ namespace CoreMedia {
}
[DllImport (Constants.CoreMediaLibrary)]
extern static /* OSStatus */ CMSyncError CMSyncGetRelativeRateAndAnchorTime (
unsafe extern static /* OSStatus */ CMSyncError CMSyncGetRelativeRateAndAnchorTime (
/* CMClockOrTimebaseRef */ IntPtr ofClockOrTimebase,
/* CMClockOrTimebaseRef */ IntPtr relativeToClockOrTimebase,
/* Float64* */ out double outRelativeRate,
out CMTime outOfClockOrTimebaseAnchorTime,
out CMTime outRelativeToClockOrTimebaseAnchorTime);
/* Float64* */ double* outRelativeRate,
CMTime* outOfClockOrTimebaseAnchorTime,
CMTime* outRelativeToClockOrTimebaseAnchorTime);
public static CMSyncError GetRelativeRateAndAnchorTime (CMClockOrTimebase clockOrTimebaseA, CMClockOrTimebase clockOrTimebaseB, out double relativeRate, out CMTime timeA, out CMTime timeB)
{
@ -890,7 +916,17 @@ namespace CoreMedia {
if (clockOrTimebaseB is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (clockOrTimebaseB));
return CMSyncGetRelativeRateAndAnchorTime (clockOrTimebaseA.Handle, clockOrTimebaseB.Handle, out relativeRate, out timeA, out timeB);
relativeRate = default;
timeA = default;
timeB = default;
unsafe {
return CMSyncGetRelativeRateAndAnchorTime (
clockOrTimebaseA.Handle,
clockOrTimebaseB.Handle,
(double*) Unsafe.AsPointer<double> (ref relativeRate),
(CMTime*) Unsafe.AsPointer<CMTime> (ref timeA),
(CMTime*) Unsafe.AsPointer<CMTime> (ref timeB));
}
}
[DllImport (Constants.CoreMediaLibrary)]
@ -907,8 +943,7 @@ namespace CoreMedia {
}
[DllImport (Constants.CoreMediaLibrary)]
[return: MarshalAs (UnmanagedType.I1)]
extern static /* Boolean */ bool CMSyncMightDrift (/* CMClockOrTimebaseRef */ IntPtr clockOrTimebase1, /* CMClockOrTimebaseRef */ IntPtr clockOrTimebase2);
extern static /* Boolean */ byte CMSyncMightDrift (/* CMClockOrTimebaseRef */ IntPtr clockOrTimebase1, /* CMClockOrTimebaseRef */ IntPtr clockOrTimebase2);
public static bool MightDrift (CMClockOrTimebase clockOrTimebaseA, CMClockOrTimebase clockOrTimebaseB)
{
@ -918,7 +953,7 @@ namespace CoreMedia {
if (clockOrTimebaseB is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (clockOrTimebaseB));
return CMSyncMightDrift (clockOrTimebaseA.Handle, clockOrTimebaseB.Handle);
return CMSyncMightDrift (clockOrTimebaseA.Handle, clockOrTimebaseB.Handle) != 0;
}
#if NET

Просмотреть файл

@ -541,9 +541,15 @@ namespace Foundation {
}
}
#if NET
// Note that this method does not work with NativeAOT, so throw an exception in that case.
// IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.Interfaces' in call to 'System.Type.GetInterfaces()'. The return value of method 'System.Object.GetType()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
[UnconditionalSuppressMessage ("", "IL2075", Justification = "The APIs this method tries to access are marked by other means, so this is linker-safe.")]
#endif
bool DynamicConformsToProtocol (NativeHandle protocol)
{
#if NET
// Note that this method does not work with NativeAOT, so throw an exception in that case.
if (Runtime.IsNativeAOT)
throw Runtime.CreateNativeAOTNotSupportedException ();
#endif

Просмотреть файл

@ -304,6 +304,17 @@ namespace ObjCRuntime {
if (trampoline is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (trampoline));
VerifyBlockDelegates (trampoline, userDelegate);
SetupBlock (trampoline, userDelegate, safe: true);
}
#if NET
// IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. The return value of method 'ObjCRuntime.MonoPInvokeCallbackAttribute.DelegateType.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
[UnconditionalSuppressMessage ("", "IL2075", Justification = "Calling GetMethod('Invoke') on a delegate type will always find something, because the invoke method can't be linked away for a delegate.")]
#endif
void VerifyBlockDelegates (Delegate trampoline, Delegate userDelegate)
{
#if !MONOMAC && !__MACCATALYST__
// Check that:
// * The trampoline is static
@ -338,7 +349,7 @@ namespace ObjCRuntime {
}
}
#endif
SetupBlock (trampoline, userDelegate, safe: true);
}
public void CleanupBlock ()

Просмотреть файл

@ -661,6 +661,10 @@ namespace Registrar {
return mi.ReturnTypeCustomAttributes.IsDefined (typeof (ReleaseAttribute), false);
}
#if NET
// IL2025: Attribute 'System.Runtime.CompilerServices.ExtensionAttribute' is being referenced in code but the trimmer was instructed to remove all instances of this attribute. If the attribute instances are necessary make sure to either remove the trimmer attribute XML portion which removes the attribute instances, or override the removal by using the trimmer XML descriptor to keep the attribute type (which in turn keeps all of its instances).
[UnconditionalSuppressMessage ("", "IL2045", Justification = "The Extension attribute is manually preserved.")]
#endif
public static bool HasThisAttributeImpl (MethodBase method)
{
var mi = method as MethodInfo;

Просмотреть файл

@ -171,8 +171,17 @@ namespace ObjCRuntime {
return path is not null;
}
#if NET
// Note that this method does not work with NativeAOT, so throw an exception in that case.
// IL2026: Using member 'System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types and members the loaded assembly depends on might be removed.
[UnconditionalSuppressMessage ("", "IL2026", Justification = "The APIs this method tries to access are marked by other means, so this is linker-safe.")]
#endif
static Assembly? ResolvingEventHandler (AssemblyLoadContext sender, AssemblyName assemblyName)
{
// Note that this method does not work with NativeAOT, so throw an exception in that case.
if (IsNativeAOT)
throw CreateNativeAOTNotSupportedException ();
if (xamarin_locate_assembly_resource (assemblyName.Name!, assemblyName.CultureName, assemblyName.Name + ".dll", out var path)) {
if (DynamicRegistrationSupported) {
return sender.LoadFromAssemblyPath (path);

Просмотреть файл

@ -641,6 +641,10 @@ namespace ObjCRuntime {
return Marshal.StringToHGlobalAuto (str.ToString ());
}
#if NET
// IL2026: Using member 'System.Reflection.Assembly.LoadFile(String)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types and members the loaded assembly depends on might be removed.
[UnconditionalSuppressMessage ("", "IL2026", Justification = "We only want the entry assembly, and then we only want the entry point, which survives trimming.")]
#endif
static unsafe Assembly? GetEntryAssembly ()
{
var asm = Assembly.GetEntryAssembly ();
@ -709,6 +713,10 @@ namespace ObjCRuntime {
RegisterAssembly (a);
}
#if NET
// IL2075: Using member 'System.Reflection.Assembly.GetReferencedAssemblies()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Assembly references might be removed.
[UnconditionalSuppressMessage ("", "IL2026", Justification = "We only want assemblies that survived trimming, so this is effectively trimmer-safe.")]
#endif
static void CollectReferencedAssemblies (List<Assembly> assemblies, Assembly assembly)
{
assemblies.Add (assembly);
@ -975,6 +983,10 @@ namespace ObjCRuntime {
}
#endregion
#if NET
// IL2075: this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. The return value of method 'ObjCRuntime.BlockProxyAttribute.Type.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
[UnconditionalSuppressMessage ("", "IL2075", Justification = "The APIs this method tries to access are marked by other means, so this is linker-safe.")]
#endif
static MethodInfo? GetBlockProxyAttributeMethod (MethodInfo method, int parameter)
{
var attrs = method.GetParameters () [parameter].GetCustomAttributes (typeof (BlockProxyAttribute), true);
@ -1036,10 +1048,23 @@ namespace ObjCRuntime {
// a the block in the given method at the given parameter into a strongly typed
// delegate
//
#if NET
// Note that the code in this method doesn't work with NativeAOT, so assert that never happens by throwing an exception in that case
// IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.Interfaces' in call to 'System.Type.GetInterfaces()'. The return value of method 'System.Reflection.MemberInfo.DeclaringType.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
// IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String, BindingFlags, Binder, Type[], ParameterModifier[])'. The return value of method 'System.Reflection.Assembly.GetType(String, Boolean)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
[UnconditionalSuppressMessage ("", "IL2075", Justification = "The APIs this method tries to access are marked by other means, so this is linker-safe.")]
// IL2026: Using member 'System.Reflection.Assembly.GetType(String, Boolean)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types might be removed."),
[UnconditionalSuppressMessage ("", "IL2026", Justification = "The APIs this method tries to access are marked by other means, so this is linker-safe.")]
// IL2065: Value passed to implicit 'this' parameter of method 'System.Type.GetMethod(String)' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements."),
[UnconditionalSuppressMessage ("", "IL2065", Justification = "The APIs this method tries to access are marked by other means, so this is linker-safe.")]
// IL2062: Value passed to parameter 'interfaceType' of method 'System.Type.GetInterfaceMap(Type)' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements."),
[UnconditionalSuppressMessage ("", "IL2062", Justification = "The APIs this method tries to access are marked by other means, so this is linker-safe.")]
#endif
[EditorBrowsable (EditorBrowsableState.Never)]
static MethodInfo? GetBlockWrapperCreator (MethodInfo method, int parameter)
{
#if NET
// Note that the code in this method doesn't work with NativeAOT, so assert that never happens by throwing an exception in that case
if (IsNativeAOT)
throw Runtime.CreateNativeAOTNotSupportedException ();
#endif

Просмотреть файл

@ -14516,7 +14516,6 @@ namespace AVFoundation {
[Export ("speakUtterance:")]
void SpeakUtterance (AVSpeechUtterance utterance);
[Async]
[Watch (6, 0), TV (13, 0), iOS (13, 0)]
[MacCatalyst (13, 1)]
[Export ("writeUtterance:toBufferCallback:")]

Просмотреть файл

@ -291,6 +291,7 @@ AVFOUNDATION_SOURCES = \
AVFoundation/AVPlayerLayer.cs \
AVFoundation/AVPlayerViewController.cs \
AVFoundation/AVSampleBufferExtensions.cs \
AVFoundation/AVSpeechSynthesizer.cs \
AVFoundation/AVTextStyleRule.cs \
AVFoundation/Events.cs \
AVFoundation/AVPlayerLooper.cs \

Просмотреть файл

@ -86,6 +86,7 @@ test.config: Makefile $(TOP)/Make.config $(TOP)/mk/mono.mk $(TOP)/eng/Version.De
@printf "$(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),$(platform)_NUGET_REF_NAME=$($(platform)_NUGET_REF_NAME)\\n)" | sed 's/^ //' >> $@
@printf "$(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(rid)_NUGET_RUNTIME_NAME=$($(rid)_NUGET_RUNTIME_NAME)\\n))" | sed 's/^ //' >> $@
@printf "$(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),SUPPORTED_API_VERSIONS_$(platform)='$(SUPPORTED_API_VERSIONS_$(platform))'\\n)" | sed 's/^ //' >> $@
@printf "ENABLE_XAMARIN=$(ENABLE_XAMARIN)" >> $@
test-system.config: Makefile $(TOP)/Make.config $(TOP)/mk/mono.mk $(TOP)/eng/Version.Details.xml
@rm -f $@
@ -118,6 +119,7 @@ test-system.config: Makefile $(TOP)/Make.config $(TOP)/mk/mono.mk $(TOP)/eng/Ver
@printf "$(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),$(platform)_NUGET_REF_NAME=$($(platform)_NUGET_REF_NAME)\\n)" | sed 's/^ //' >> $@
@printf "$(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(rid)_NUGET_RUNTIME_NAME=$($(rid)_NUGET_RUNTIME_NAME)\\n))" | sed 's/^ //' >> $@
@printf "$(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),SUPPORTED_API_VERSIONS_$(platform)='$(SUPPORTED_API_VERSIONS_$(platform))'\\n)" | sed 's/^ //' >> $@
@printf "ENABLE_XAMARIN=$(ENABLE_XAMARIN)" >> $@
clean-local::
$(Q) $(SYSTEM_XBUILD) /t:Clean /p:Platform=iPhoneSimulator /p:Configuration=$(CONFIG) $(XBUILD_VERBOSITY) tests.sln

Просмотреть файл

@ -65,19 +65,6 @@ namespace Cecil.Tests {
"AVFoundation.AVSampleCursorSyncInfo ObjCRuntime.Messaging::AVSampleCursorSyncInfo_objc_msgSendSuper_stret(System.IntPtr,System.IntPtr)",
"AVFoundation.AVSampleCursorSyncInfo ObjCRuntime.Messaging::AVSampleCursorSyncInfo_objc_msgSendSuper(System.IntPtr,System.IntPtr)",
"CoreGraphics.CGSize CoreText.CTFramesetter::CTFramesetterSuggestFrameSizeWithConstraints(System.IntPtr,Foundation.NSRange,System.IntPtr,CoreGraphics.CGSize,Foundation.NSRange&)",
"CoreMedia.CMClockError CoreMedia.CMClock::CMAudioClockCreate(System.IntPtr,System.IntPtr&)",
"CoreMedia.CMClockError CoreMedia.CMClock::CMClockGetAnchorTime(System.IntPtr,CoreMedia.CMTime&,CoreMedia.CMTime&)",
"CoreMedia.CMSampleBufferError CoreMedia.CMSampleBuffer::CMAudioSampleBufferCreateReadyWithPacketDescriptions(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,CoreMedia.CMTime,AudioToolbox.AudioStreamPacketDescription[],System.IntPtr&)",
"CoreMedia.CMSampleBufferError CoreMedia.CMSampleBuffer::CMAudioSampleBufferCreateWithPacketDescriptions(System.IntPtr,System.IntPtr,System.Boolean,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,CoreMedia.CMTime,AudioToolbox.AudioStreamPacketDescription[],System.IntPtr&)",
"CoreMedia.CMSampleBufferError CoreMedia.CMSampleBuffer::CMSampleBufferCreateForImageBuffer(System.IntPtr,System.IntPtr,System.Boolean,System.IntPtr,System.IntPtr,System.IntPtr,CoreMedia.CMSampleTimingInfo&,System.IntPtr&)",
"CoreMedia.CMSampleBufferError CoreMedia.CMSampleBuffer::CMSampleBufferCreateReady(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,CoreMedia.CMSampleTimingInfo[],System.IntPtr,System.UIntPtr[],System.IntPtr&)",
"CoreMedia.CMSampleBufferError CoreMedia.CMSampleBuffer::CMSampleBufferCreateReadyWithImageBuffer(System.IntPtr,System.IntPtr,System.IntPtr,CoreMedia.CMSampleTimingInfo&,System.IntPtr&)",
"CoreMedia.CMSyncError CoreMedia.CMClockOrTimebase::CMSyncGetRelativeRateAndAnchorTime(System.IntPtr,System.IntPtr,System.Double&,CoreMedia.CMTime&,CoreMedia.CMTime&)",
"CoreMedia.CMTimebaseError CoreMedia.CMTimebase::CMTimebaseCreateWithMasterClock(System.IntPtr,System.IntPtr,System.IntPtr&)",
"CoreMedia.CMTimebaseError CoreMedia.CMTimebase::CMTimebaseCreateWithMasterTimebase(System.IntPtr,System.IntPtr,System.IntPtr&)",
"CoreMedia.CMTimebaseError CoreMedia.CMTimebase::CMTimebaseCreateWithSourceClock(System.IntPtr,System.IntPtr,System.IntPtr&)",
"CoreMedia.CMTimebaseError CoreMedia.CMTimebase::CMTimebaseCreateWithSourceTimebase(System.IntPtr,System.IntPtr,System.IntPtr&)",
"CoreMedia.CMTimebaseError CoreMedia.CMTimebase::CMTimebaseGetTimeAndRate(System.IntPtr,CoreMedia.CMTime&,System.Double&)",
"CoreServices.LSResult CoreServices.LaunchServices::LSCanURLAcceptURL(System.IntPtr,System.IntPtr,CoreServices.LSRoles,CoreServices.LSAcceptanceFlags,System.Byte&)",
"CoreVideo.CVReturn CoreVideo.CVDisplayLink::CVDisplayLinkCreateWithActiveCGDisplays(System.IntPtr&)",
"CoreVideo.CVReturn CoreVideo.CVDisplayLink::CVDisplayLinkCreateWithCGDisplay(System.UInt32,System.IntPtr&)",
@ -173,10 +160,6 @@ namespace Cecil.Tests {
"Security.SslStatus Security.SslContext::SSLRead(System.IntPtr,System.Byte*,System.IntPtr,System.IntPtr&)",
"Security.SslStatus Security.SslContext::SSLSetSessionOption(System.IntPtr,Security.SslSessionOption,System.Boolean)",
"Security.SslStatus Security.SslContext::SSLWrite(System.IntPtr,System.Byte*,System.IntPtr,System.IntPtr&)",
"System.Boolean CoreMedia.CMClock::CMClockMightDrift(System.IntPtr,System.IntPtr)",
"System.Boolean CoreMedia.CMClockOrTimebase::CMSyncMightDrift(System.IntPtr,System.IntPtr)",
"System.Boolean CoreMedia.CMSampleBuffer::CMSampleBufferDataIsReady(System.IntPtr)",
"System.Boolean CoreMedia.CMSampleBuffer::CMSampleBufferIsValid(System.IntPtr)",
"System.Boolean CoreServices.FSEvent::FSEventsPurgeEventsForDeviceUpToEventId(System.UInt64,System.UInt64)",
"System.Boolean CoreServices.FSEventStream::FSEventStreamStart(System.IntPtr)",
"System.Boolean CoreText.CTFont::CTFontGetGlyphsForCharacters(System.IntPtr,System.Char[],System.UInt16[],System.IntPtr)",
@ -285,8 +268,6 @@ namespace Cecil.Tests {
"System.Int32 AudioUnit.AudioUnit::AudioUnitGetProperty(System.IntPtr,AudioUnit.AudioUnitPropertyIDType,AudioUnit.AudioUnitScopeType,System.UInt32,System.UInt32&,System.UInt32&)",
"System.Int32 AudioUnit.AudioUnit::AudioUnitSetProperty(System.IntPtr,AudioUnit.AudioUnitPropertyIDType,AudioUnit.AudioUnitScopeType,System.UInt32,AudioToolbox.AudioStreamBasicDescription&,System.UInt32)",
"System.Int32 AudioUnit.AUGraph::NewAUGraph(System.IntPtr&)",
"System.Int32 CoreMedia.CMBufferQueue::CMBufferQueueCreate(System.IntPtr,System.IntPtr,CoreMedia.CMBufferQueue/CMBufferCallbacks,System.IntPtr&)",
"System.Int32 CoreMedia.CMBufferQueue::CMBufferQueueCreate(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr&)",
"System.Int32 CoreVideo.CVDisplayLink::CVDisplayLinkTranslateTime(System.IntPtr,CoreVideo.CVTimeStamp,CoreVideo.CVTimeStamp&)",
"System.Int32 CoreVideo.CVMetalTextureCache::CVMetalTextureCacheCreate(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr&)",
"System.Int32 CoreWlan.CWKeychain::CWKeychainCopyWiFiEAPIdentity(System.IntPtr,System.IntPtr,System.IntPtr&)",
@ -301,9 +282,6 @@ namespace Cecil.Tests {
"System.Int32 Security.SslContext::SSLSetSessionTicketsEnabled(System.IntPtr,System.Boolean)",
"System.Int32 SystemConfiguration.NetworkReachability::SCNetworkReachabilityGetFlags(System.IntPtr,SystemConfiguration.NetworkReachabilityFlags&)",
"System.IntPtr CoreMedia.CMAttachmentBearer::CMGetAttachment(System.IntPtr,System.IntPtr,CoreMedia.CMAttachmentMode&)",
"System.IntPtr CoreMedia.CMSampleBuffer::CMSampleBufferCreateCopyWithNewTiming(System.IntPtr,System.IntPtr,System.IntPtr,CoreMedia.CMSampleTimingInfo*,System.IntPtr&)",
"System.IntPtr CoreMedia.CMSampleBuffer::CMSampleBufferGetSampleAttachmentsArray(System.IntPtr,System.Boolean)",
"System.IntPtr CoreMedia.CMSampleBuffer::CMSampleBufferGetSampleTimingInfoArray(System.IntPtr,System.IntPtr,CoreMedia.CMSampleTimingInfo*,System.IntPtr&)",
"System.IntPtr CoreServices.FSEventStream::FSEventStreamCreate(System.IntPtr,method System.Void *(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr),CoreServices.FSEventStreamContext&,System.IntPtr,System.UInt64,System.Double,CoreServices.FSEventStreamCreateFlags)",
"System.IntPtr CoreServices.FSEventStream::FSEventStreamCreateRelativeToDevice(System.IntPtr,method System.Void *(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr),CoreServices.FSEventStreamContext&,System.UInt64,System.IntPtr,System.UInt64,System.Double,CoreServices.FSEventStreamCreateFlags)",
"System.IntPtr CoreText.CTFont::CTFontCopyLocalizedName(System.IntPtr,System.IntPtr,System.IntPtr&)",

Просмотреть файл

@ -6647,12 +6647,7 @@ F:CloudKit.CKSyncEngineZoneDeletionReason.Deleted
F:CloudKit.CKSyncEngineZoneDeletionReason.EncryptedDataReset
F:CloudKit.CKSyncEngineZoneDeletionReason.Purged
F:CloudKit.CKSyncEngineZoneDeletionReason.value__
F:Compression.CompressionAlgorithm.LZ4
F:Compression.CompressionAlgorithm.LZ4Raw
F:Compression.CompressionAlgorithm.Lzfse
F:Compression.CompressionAlgorithm.Lzma
F:Compression.CompressionAlgorithm.value__
F:Compression.CompressionAlgorithm.Zlib
F:Contacts.CNAuthorizationStatus.Authorized
F:Contacts.CNAuthorizationStatus.Denied
F:Contacts.CNAuthorizationStatus.NotDetermined

Просмотреть файл

@ -28,6 +28,7 @@ namespace Cecil.Tests {
{
// We join all the APIs from all the platforms, so we can only run this test when all platforms are enabled.
Configuration.IgnoreIfAnyIgnoredPlatforms ();
Configuration.IgnoreIfNotXamarinEnabled (); // our tooling to inject docs for Apple APIs lives in maccore, so if we don't do that, we'll get a lot of false positives.
// Collect everything
var xmlMembers = new HashSet<AssemblyApi> ();

Просмотреть файл

@ -49,6 +49,7 @@ namespace Xamarin.Tests {
public static bool include_dotnet;
public static bool include_legacy_xamarin;
public static bool iOSSupports32BitArchitectures;
public static bool EnableXamarin;
static Version xcode_version;
public static Version XcodeVersion {
@ -308,6 +309,7 @@ namespace Xamarin.Tests {
DotNetExecutable = GetVariable ("DOTNET", null);
DotNetTfm = GetVariable ("DOTNET_TFM", null);
iOSSupports32BitArchitectures = !string.IsNullOrEmpty (GetVariable ("IOS_SUPPORTS_32BIT_ARCHITECTURES", ""));
EnableXamarin = !string.IsNullOrEmpty (GetVariable ("ENABLE_XAMARIN", ""));
XcodeVersionString = GetXcodeVersion (xcode_root);
#if MONOMAC
@ -1157,6 +1159,13 @@ namespace Xamarin.Tests {
Assert.Ignore ($"This test is only applicable on {platform}");
}
public static void IgnoreIfNotXamarinEnabled ()
{
if (EnableXamarin)
return;
Assert.Ignore ($"This test is only applicable if Xamarin-specific bits are enabled.");
}
public static string GetTestLibraryDirectory (ApplePlatform platform, bool? simulator = null)
{
string dir;

Просмотреть файл

@ -28,57 +28,7 @@ namespace Xamarin.Tests {
[TestCase (ApplePlatform.TVOS, "tvos-arm64")]
public void TrimmerWarningsDynamicRegistrar (ApplePlatform platform, string runtimeIdentifiers)
{
ExpectedBuildMessage [] expectedWarnings;
switch (platform) {
case ApplePlatform.iOS:
case ApplePlatform.TVOS:
expectedWarnings = new ExpectedBuildMessage [] {
new ExpectedBuildMessage ("src/Foundation/NSObject2.cs" /* line 554 */, "Foundation.NSObject.DynamicConformsToProtocol(NativeHandle): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.Interfaces' in call to 'System.Type.GetInterfaces()'. The return value of method 'System.Object.GetType()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
new ExpectedBuildMessage ("src/ObjCRuntime/Blocks.cs" /* line 313 */, "ObjCRuntime.BlockLiteral.SetupBlock(Delegate, Delegate): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. The return value of method 'ObjCRuntime.MonoPInvokeCallbackAttribute.DelegateType.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
new ExpectedBuildMessage ("src/ObjCRuntime/DynamicRegistrar.cs" /* line 542 */, "Registrar.DynamicRegistrar.HasThisAttributeImpl(MethodBase): Attribute 'System.Runtime.CompilerServices.ExtensionAttribute' is being referenced in code but the trimmer was instructed to remove all instances of this attribute. If the attribute instances are necessary make sure to either remove the trimmer attribute XML portion which removes the attribute instances, or override the removal by using the trimmer XML descriptor to keep the attribute type (which in turn keeps all of its instances)."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 714 */, "ObjCRuntime.Runtime.CollectReferencedAssemblies(List<Assembly>, Assembly): Using member 'System.Reflection.Assembly.GetReferencedAssemblies()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Assembly references might be removed."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 983 */, "ObjCRuntime.Runtime.GetBlockProxyAttributeMethod(MethodInfo, Int32): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. The return value of method 'ObjCRuntime.BlockProxyAttribute.Type.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1064 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.Interfaces' in call to 'System.Type.GetInterfaces()'. The return value of method 'System.Reflection.MemberInfo.DeclaringType.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1103 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String, BindingFlags, Binder, Type[], ParameterModifier[])'. The return value of method 'System.Reflection.Assembly.GetType(String, Boolean)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1094 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): Using member 'System.Reflection.Assembly.GetType(String, Boolean)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types might be removed by trimming. If the type name is a string literal, consider using Type.GetType instead."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1085 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): Value passed to implicit 'this' parameter of method 'System.Type.GetMethod(String)' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1068 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): Value passed to parameter 'interfaceType' of method 'System.Type.GetInterfaceMap(Type)' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements."),
};
break;
case ApplePlatform.MacOSX:
expectedWarnings = new ExpectedBuildMessage [] {
new ExpectedBuildMessage ("src/Foundation/NSObject2.cs" /* line 554 */, "Foundation.NSObject.DynamicConformsToProtocol(NativeHandle): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.Interfaces' in call to 'System.Type.GetInterfaces()'. The return value of method 'System.Object.GetType()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
new ExpectedBuildMessage ("src/ObjCRuntime/DynamicRegistrar.cs" /* line 542 */, "Registrar.DynamicRegistrar.HasThisAttributeImpl(MethodBase): Attribute 'System.Runtime.CompilerServices.ExtensionAttribute' is being referenced in code but the trimmer was instructed to remove all instances of this attribute. If the attribute instances are necessary make sure to either remove the trimmer attribute XML portion which removes the attribute instances, or override the removal by using the trimmer XML descriptor to keep the attribute type (which in turn keeps all of its instances)."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.CoreCLR.cs" /* line 177 */, "ObjCRuntime.Runtime.ResolvingEventHandler(AssemblyLoadContext, AssemblyName): Using member 'System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types and members the loaded assembly depends on might be removed."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 714 */, "ObjCRuntime.Runtime.CollectReferencedAssemblies(List<Assembly>, Assembly): Using member 'System.Reflection.Assembly.GetReferencedAssemblies()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Assembly references might be removed."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 983 */, "ObjCRuntime.Runtime.GetBlockProxyAttributeMethod(MethodInfo, Int32): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. The return value of method 'ObjCRuntime.BlockProxyAttribute.Type.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1064 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.Interfaces' in call to 'System.Type.GetInterfaces()'. The return value of method 'System.Reflection.MemberInfo.DeclaringType.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1103 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String, BindingFlags, Binder, Type[], ParameterModifier[])'. The return value of method 'System.Reflection.Assembly.GetType(String, Boolean)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1094 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): Using member 'System.Reflection.Assembly.GetType(String, Boolean)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types might be removed by trimming. If the type name is a string literal, consider using Type.GetType instead."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1085 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): Value passed to implicit 'this' parameter of method 'System.Type.GetMethod(String)' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1068 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): Value passed to parameter 'interfaceType' of method 'System.Type.GetInterfaceMap(Type)' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 648 */, "ObjCRuntime.Runtime.GetEntryAssembly(): Using member 'System.Reflection.Assembly.LoadFile(String)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types and members the loaded assembly depends on might be removed."),
};
break;
case ApplePlatform.MacCatalyst:
expectedWarnings = new ExpectedBuildMessage [] {
new ExpectedBuildMessage ("src/Foundation/NSObject2.cs" /* line 554 */, "Foundation.NSObject.DynamicConformsToProtocol(NativeHandle): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.Interfaces' in call to 'System.Type.GetInterfaces()'. The return value of method 'System.Object.GetType()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
new ExpectedBuildMessage ("src/ObjCRuntime/DynamicRegistrar.cs" /* line 542 */, "Registrar.DynamicRegistrar.HasThisAttributeImpl(MethodBase): Attribute 'System.Runtime.CompilerServices.ExtensionAttribute' is being referenced in code but the trimmer was instructed to remove all instances of this attribute. If the attribute instances are necessary make sure to either remove the trimmer attribute XML portion which removes the attribute instances, or override the removal by using the trimmer XML descriptor to keep the attribute type (which in turn keeps all of its instances)."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 714 */, "ObjCRuntime.Runtime.CollectReferencedAssemblies(List<Assembly>, Assembly): Using member 'System.Reflection.Assembly.GetReferencedAssemblies()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Assembly references might be removed."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 983 */, "ObjCRuntime.Runtime.GetBlockProxyAttributeMethod(MethodInfo, Int32): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. The return value of method 'ObjCRuntime.BlockProxyAttribute.Type.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1064 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.Interfaces' in call to 'System.Type.GetInterfaces()'. The return value of method 'System.Reflection.MemberInfo.DeclaringType.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1103 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String, BindingFlags, Binder, Type[], ParameterModifier[])'. The return value of method 'System.Reflection.Assembly.GetType(String, Boolean)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1094 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): Using member 'System.Reflection.Assembly.GetType(String, Boolean)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types might be removed by trimming. If the type name is a string literal, consider using Type.GetType instead."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1085 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): Value passed to implicit 'this' parameter of method 'System.Type.GetMethod(String)' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements."),
new ExpectedBuildMessage ("src/ObjCRuntime/Runtime.cs" /* line 1068 */, "ObjCRuntime.Runtime.GetBlockWrapperCreator(MethodInfo, Int32): Value passed to parameter 'interfaceType' of method 'System.Type.GetInterfaceMap(Type)' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements."),
};
break;
default:
Assert.Fail ($"Unknown platform: {platform}");
return;
}
TrimmerWarnings (platform, runtimeIdentifiers, "dynamic", expectedWarnings);
TrimmerWarnings (platform, runtimeIdentifiers, "dynamic", Array.Empty<ExpectedBuildMessage> ());
}
void TrimmerWarnings (ApplePlatform platform, string runtimeIdentifiers, string registrar, params ExpectedBuildMessage [] expectedWarnings)

Просмотреть файл

@ -481,7 +481,7 @@ namespace Xamarin.Bundler {
public Version GetMacCatalystmacOSVersion (Version iOSVersion)
{
if (!MacCatalystSupport.TryGetMacOSVersion (Driver.GetFrameworkDirectory (this), iOSVersion, out var value, out var knowniOSVersions))
throw ErrorHelper.CreateError (183, Errors.MX0183 /* Could not map the Mac Catalyst version {0} to a corresponding macOS version. Valid Mac Catalyst versions are: {1} */, iOSVersion.ToString (), string.Join (", ", knowniOSVersions));
throw ErrorHelper.CreateError (183, Errors.MX0183 /* Could not map the Mac Catalyst version {0} to a corresponding macOS version. Valid Mac Catalyst versions are: {1} */, iOSVersion.ToString (), string.Join (", ", knowniOSVersions.OrderBy (v => v)));
return value;
}
@ -489,7 +489,7 @@ namespace Xamarin.Bundler {
public Version GetMacCatalystiOSVersion (Version macOSVersion)
{
if (!MacCatalystSupport.TryGetiOSVersion (Driver.GetFrameworkDirectory (this), macOSVersion, out var value, out var knownMacOSVersions))
throw ErrorHelper.CreateError (184, Errors.MX0184 /* Could not map the macOS version {0} to a corresponding Mac Catalyst version. Valid macOS versions are: {1} */, macOSVersion.ToString (), string.Join (", ", knownMacOSVersions));
throw ErrorHelper.CreateError (184, Errors.MX0184 /* Could not map the macOS version {0} to a corresponding Mac Catalyst version. Valid macOS versions are: {1} */, macOSVersion.ToString (), string.Join (", ", knownMacOSVersions.OrderBy (v => v)));
return value;
}