xamarin / xamarin-macios

.NET for iOS, Mac Catalyst, macOS, and tvOS provide open-source bindings of the Apple SDKs for use with .NET managed languages such as C#
Other
2.44k stars 510 forks source link

iOS: NSTextList no longer working when building with XCode 15 and running on iOS 18 #21249

Open tipa opened 3 days ago

tipa commented 3 days ago

Apple platform

iOS

Framework version

net8.0-*

Affected platform version

.NET 8

Description

I am building an app that has a text editor with text formatting options as core functionality. One of those text formatting options is creating (un)ordered lists (using NSTextList). After the release of iOS 18 I was immediately notified by users that this feature stopped working on iOS 18: The list paragraph/item is not longer inset and the bullet points / numbers, that should show in front of the list item, are no longer there. I also was able to reproduce the same problematic behavior using a small Swift-app (see below) and running it on iOS 18 - so clearly an Apple/iOS issue.

However, when building the same project with XCode 16 and running it on either iOS 17 or 18, the lists are working correctly again. So I did report this issue to Apple, but I expect them to just respond with: "Just use XCode 16 then".

But with Xcode 16 seemingly not being supported with .NET until November, I am unable to do so. So at the moment I appear to be in a situation where I need to tell my customers that the list formatting option just won't be working until November, when XCode support for .NET is released...

Will there be any preview version of XCode support (perhaps alsong with .NET 9 RC) or any other wokaround that allows me to build my .NET app with XCode 16 before November?

Steps to Reproduce

Download this example Xcode project: textkit2.zip

rolfbjarne commented 3 days ago

Will there be any preview version of XCode support (perhaps alsong with .NET 9 RC)

Yes, the plan is to get Xcode 16 support in the next .NET 9 RC (which would be RC 2).

any other wokaround that allows me to build my .NET app with XCode 16 before November?

Yes, this might work:

  1. Add a NuGet.config file in your repo with this feed (or add the feed to an existing NuGet.config):

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <packageSources>
        <add key="dotnet8" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json" />
      </packageSources>
    </configuration>
  2. Save this to a file named Xcode16Rollback.json:

    {
    "microsoft.net.sdk.ios": "18.0.8246-xcode16/8.0.100",
    "microsoft.net.sdk.tvos": "18.0.8246-xcode16/8.0.100",
    "microsoft.net.sdk.maccatalyst": "18.0.8246-xcode16/8.0.100",
    "microsoft.net.sdk.macos": "15.0.8246-xcode16/8.0.100"
    }
  3. Install the Xcode 16 iOS workload:

    $ sudo dotnet workload install ios --from-rollback-file Xcode16Rollback.json -v diag
  4. Add a Directory.Build.props in your project's root directory, adding XCODE_16_0_PREVIEW to the NoWarn property:

    <Project>
        <PropertyGroup>
            <NoWarn>$(NoWarn);XCODE_16_0_PREVIEW</NoWarn>
        </PropertyGroup>
    </Project>

    (this last step won't be necessary when using the final Xcode 16 packages)

This should work when building from the command line on macOS, and probably if you're using VSCode on macOS as well. Command line or Visual Studio from Windows gets much more complicated, so I'd recommend not going down that route.

Note that these packages are straight from our CI, so the usual caveats about CI builds apply (API might change, not tested as rigorously as stable, or even preview, releases, etc.).

Can you try that and see if it works for you?

tipa commented 3 days ago

I tried your steps, but the build fails (I did dotnet build from the command line) with > 1.000 errors like: error XCODE_16_0_PREVIEW: 'CloudKit.CKRecordID' is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed

Maybe the Directory.Build.props isn't recognised? Does it have to be referenced in the .csproj file?

rolfbjarne commented 3 days ago

I tried your steps, but the build fails (I did dotnet build from the command line) with > 1.000 errors like: error XCODE_16_0_PREVIEW: 'CloudKit.CKRecordID' is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed

Maybe the Directory.Build.props isn't recognised? Does it have to be referenced in the .csproj file?

That's weird.

Can you try adding the NoWarn line in your csproj as well / instead?

If that doesn't work, please get a binlog.

tipa commented 3 days ago

Ah - I had <NoWarn> specified in my csproj already, but didn't "import" the existing values with $(NoWarn); I then also had to set Xcode 16 as default with sudo xcode-select --switch /Applications/Xcode-16.0.0.app/Contents/Developer I was then able to build the app with either the command prompt or JetBrains Rider. And it worked - the lists are rendering again! Rider even shows the new deprecation warnings for StoreKit1. Are there any "real" or known risks about using the workaround and publishing builds to production? Is there an easy way to roll back to Xcode 15, if needed? Or would I have to completely uninstall and re-install .NET & the workloads from scratch?

rolfbjarne commented 3 days ago

Are there any "real" or known risks about using the workaround and publishing builds to production?

I don't know of any issues, but that's really all that I can say too.

My personal advice would be to test, and if it works better than the current version you have in the App Store, then publish (which is really true for any version, since only your own testing can fully validate your own app).

Is there an easy way to roll back to Xcode 15, if needed? Or would I have to completely uninstall and re-install .NET & the workloads from scratch?

The following rollback file should work to get the current stable workload installed:

{
"microsoft.net.sdk.ios": "17.5.8030/8.0.100",
"microsoft.net.sdk.tvos": "17.5.8030/8.0.100",
"microsoft.net.sdk.maccatalyst": "17.5.8030/8.0.100",
"microsoft.net.sdk.macos": "14.5.8030/8.0.100"
}
tipa commented 2 days ago

It looks like this workaround doesn't work with macOS. Gives error at compile time: Microsoft.macOS.Sdk.net8.0_15.0/15.0.8246-xcode16/targets/Xamarin.Shared.Sdk.targets(1637,3): error : ld: framework not found FSKit

rolfbjarne commented 2 days ago

It looks like this workaround doesn't work with macOS. Gives error at compile time: Microsoft.macOS.Sdk.net8.0_15.0/15.0.8246-xcode16/targets/Xamarin.Shared.Sdk.targets(1637,3): error : ld: framework not found FSKit

The workload you have installed is from the latest Xcode 16 beta (6), which included the FSKit framework. Apple removed the FSKit framework from their RC+stable release, which is why you're seeing this error.

The fix is to use an updated workload, try this rollback manifest instead:

{
"microsoft.net.sdk.ios": "18.0.8287-xcode16/8.0.100",
"microsoft.net.sdk.tvos": "18.0.8287-xcode16/8.0.100",
"microsoft.net.sdk.maccatalyst": "18.0.8287-xcode16/8.0.100",
"microsoft.net.sdk.macos": "15.0.8287-xcode16/8.0.100"
}