0
votes

We're receiving the following message upon submitting our Xamarin.Forms iOS app to Apple's TestFlight.

the Message:

Dear Developer,

We identified one or more issues with a recent delivery for your app, "[bundle name]" [bundle version] ([bundle version]). Please correct the following issues, then upload again.

ITMS-90338: Non-public API usage - The app references non-public selectors in [project name]: applicationWillTerminate, fontWeight, newSocketQueueForConnectionFromAddress:onSocket:, setOrientation:animated:, socket:didConnectToHost:port:, socket:didReadPartialDataOfLength:tag:, socket:didReceiveTrust:completionHandler:, socket:didWritePartialDataOfLength:tag:, socket:shouldTimeoutReadWithTag:elapsed:bytesDone:, socket:shouldTimeoutWriteWithTag:elapsed:bytesDone:, socketDidCloseReadStream:, socketDidSecure:, terminateWithSuccess. If method names in your source code match the private Apple APIs listed above, altering your method names will help prevent this app from being flagged in future submissions. In addition, note that one or more of the above APIs may be located in a static library that was included with your app. If so, they must be removed. For further information, visit the Technical Support Information at http://developer.apple.com/support/technical/

ITMS-90809: Deprecated API Usage - New apps that use UIWebView are no longer accepted. Instead, use WKWebView for improved security and reliability. Learn more (https://developer.apple.com/documentation/uikit/uiwebview).

Best regards,

The App Store Team

I have looked up the messages and made too many attempts to no avail. I'd appreciate it if someone could help having Apple to accept our submission.

Let me share more details about

the Environment:

This is a Xamarin.Forms app that we build using Azure DevOps's build pipelines (specifically, Xamarin.iOS task version 2.*) and release using Azure DevOps's release pipelines. We release that to Microsoft AppCenter and we then download the *.ipa from there. We submit it to Apple's AppStoreConnect TestFlight using Transporter app on the Mac from Apple's AppStore.

XCode version used: 12.2
.Net Core SDK version used: 3.1.x
Mono Version used: 6.12.0
Xamarin iOS SDK version used: 14.6.0.15
NuGet tool version used: 5.8.0

Installed NuGet Packages/3rd-party Libraries:

<PackageReference Include="Abp">
  <Version>5.14.0</Version>
</PackageReference>
<PackageReference Include="Abp.AutoMapper">
  <Version>5.14.0</Version>
</PackageReference>
<PackageReference Include="Abp.Web.Common">
  <Version>5.14.0</Version>
</PackageReference>
<PackageReference Include="Acr.Support">
  <Version>2.1.0</Version>
</PackageReference>
<PackageReference Include="Acr.UserDialogs">
  <Version>7.1.0.475</Version>
</PackageReference>
<PackageReference Include="Castle.Core">
  <Version>4.4.1</Version>
</PackageReference>
<PackageReference Include="Castle.LoggingFacility">
  <Version>5.1.1</Version>
</PackageReference>
<PackageReference Include="Castle.Windsor">
  <Version>5.1.1</Version>
</PackageReference>
<PackageReference Include="Flurl">
  <Version>2.8.2</Version>
</PackageReference>
<PackageReference Include="Flurl.Http">
  <Version>2.4.2</Version>
</PackageReference>
<PackageReference Include="JetBrains.Annotations">
  <Version>2020.3.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.AppCenter.Analytics">
  <Version>4.1.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.AppCenter.Crashes">
  <Version>4.1.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.CSharp">
  <Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.Win32.Primitives">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="NETStandard.Library">
  <Version>2.0.3</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
  <Version>12.0.3</Version>
</PackageReference>
<PackageReference Include="NUglify">
  <Version>1.13.2</Version>
</PackageReference>
<PackageReference Include="Plugin.Permissions">
  <Version>6.0.1</Version>
</PackageReference>
<PackageReference Include="Refractored.MvvmHelpers">
  <Version>1.6.2</Version>
</PackageReference>
<PackageReference Include="Rg.Plugins.Popup">
  <Version>2.0.0.10</Version>
</PackageReference>
<PackageReference Include="Splat">
  <Version>10.0.1</Version>
</PackageReference>
<PackageReference Include="System.AppContext">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Collections">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Collections.Concurrent">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Collections.Specialized">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.ComponentModel">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.ComponentModel.Annotations">
  <Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.ComponentModel.TypeConverter">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Configuration.ConfigurationManager">
  <Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.Console">
  <Version>4.3.1</Version>
</PackageReference>
<PackageReference Include="System.Data.Common">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Diagnostics.Debug">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Diagnostics.Tools">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Diagnostics.TraceSource">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Diagnostics.Tracing">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Dynamic.Runtime">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Globalization">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Globalization.Calendars">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.IO">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.IO.Compression">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.IO.Compression.ZipFile">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.IO.FileSystem">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.IO.FileSystem.Primitives">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Linq">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Linq.Expressions">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Linq.Queryable">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Memory">
  <Version>4.5.3</Version>
</PackageReference>
<PackageReference Include="System.Net.Http">
  <Version>4.3.4</Version>
</PackageReference>
<PackageReference Include="System.Net.Primitives">
  <Version>4.3.1</Version>
</PackageReference>
<PackageReference Include="System.Net.Sockets">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.ObjectModel">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Reflection">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Reflection.Emit">
  <Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.Reflection.Emit.ILGeneration">
  <Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.Reflection.Emit.Lightweight">
  <Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.Reflection.Extensions">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Reflection.Primitives">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Reflection.TypeExtensions">
  <Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.Resources.ResourceManager">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Runtime">
  <Version>4.3.1</Version>
</PackageReference>
<PackageReference Include="System.Runtime.CompilerServices.Unsafe">
  <Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.Runtime.Extensions">
  <Version>4.3.1</Version>
</PackageReference>
<PackageReference Include="System.Runtime.Handles">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Runtime.InteropServices">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Runtime.InteropServices.RuntimeInformation">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Runtime.Loader">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Runtime.Numerics">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Runtime.Serialization.Formatters">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Runtime.Serialization.Primitives">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Security.AccessControl">
  <Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Claims">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Cryptography.Algorithms">
  <Version>4.3.1</Version>
</PackageReference>
<PackageReference Include="System.Security.Cryptography.Encoding">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Cryptography.Primitives">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Cryptography.X509Certificates">
  <Version>4.3.2</Version>
</PackageReference>
<PackageReference Include="System.Security.Permissions">
  <Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Principal.Windows">
  <Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.Text.Encoding">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Text.Encoding.CodePages">
  <Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.Text.Encoding.Extensions">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Text.Encodings.Web">
  <Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.Text.Json">
  <Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.Text.RegularExpressions">
  <Version>4.3.1</Version>
</PackageReference>
<PackageReference Include="System.Threading">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Threading.Tasks">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Threading.Thread">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Threading.Timer">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.ValueTuple">
  <Version>4.5.0</Version>
</PackageReference>
<PackageReference Include="System.Xml.ReaderWriter">
  <Version>4.3.1</Version>
</PackageReference>
<PackageReference Include="System.Xml.XDocument">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Xml.XmlDocument">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Xml.XmlSerializer">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Xml.XPath.XmlDocument">
  <Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="TimeZoneConverter">
  <Version>3.3.0</Version>
</PackageReference>
<PackageReference Include="Xam.Plugin.Connectivity">
  <Version>3.2.0</Version>
</PackageReference>
<PackageReference Include="Xam.Plugin.Geolocator">
  <Version>4.5.0.6</Version>
</PackageReference>
<PackageReference Include="Xam.Plugin.Iconize.FontAwesome">
  <Version>3.5.0.123</Version>
</PackageReference>
<PackageReference Include="Xam.Plugin.Iconize.Material">
  <Version>3.5.0.123</Version>
</PackageReference>
<PackageReference Include="Xam.Plugin.Media">
  <Version>5.0.1</Version>
</PackageReference>
<PackageReference Include="Xam.Plugins.Forms.ImageCircle">
  <Version>3.0.0.5</Version>
</PackageReference>
<PackageReference Include="Xam.Plugins.ImageCropper">
  <Version>1.2.0</Version>
</PackageReference>
<PackageReference Include="Xam.Plugins.Settings">
  <Version>3.1.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.Azure.NotificationHubs.iOS">
  <Version>3.1.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.Build.Download">
  <Version>0.10.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.CommunityToolkit">
  <Version>1.0.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.Essentials">
  <Version>1.6.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.FFImageLoading">
  <Version>2.4.11.982</Version>
</PackageReference>
<PackageReference Include="Xamarin.FFImageLoading.Forms">
  <Version>2.4.11.982</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms">
  <Version>5.0.0.1931</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms.Maps">
  <Version>5.0.0.1931</Version>
</PackageReference>
<PackageReference Include="Xamarin.Google.iOS.Maps">
  <Version>3.9.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.TestCloud.Agent">
  <Version>0.22.1</Version>
</PackageReference>
<PackageReference Include="XamarinFastEntry.Behaviors">
  <Version>1.1.1</Version>
</PackageReference>

Apparently, the app is using Xamarin.Forms 5 in which the reference to UIWebView has been removed.

In our project, we're using a web view only in one page and even though Xamarin's default renderer for that was changed to WkWebView, we have made a custom-renderer for that to use WkWebView just in case (and of course we made sure to utilize the new control).

Cross-platform control:

public class CustomWebView : Xamarin.Forms.WebView
{
}

iOS-specific renderer:

[assembly: Xamarin.Forms.ExportRenderer(typeof(Our.CrossPlatform.Project.CustomWebView), typeof(Our.Project.Renderer.CustomWebViewRenderer))]

namespace Our.Project.Renderer
{
    public class CustomWebViewRenderer : Xamarin.Forms.Platform.iOS.WkWebViewRenderer
    {
    }
}

The build agent used on Azure build pipelines: macos-10.15 (the full specifications of the Agent could be found on that link).

what we tried:

Regarding the first message (ITMS-90338: Non-public API usage) and after processing a lot of posts on Stackoverflow and Xamarin Forums, we found that people suggest we should set the linking behavior to Link SDK Only (which we already do for each and every build configuration), however and just to be sure, we decided to tell both MSBuild and MTouch to make sure that this is the linking behavior used.

We started sending /p:MtouchLink="SdkOnly" to MSBuild in the pipeline task's arguments section; and to MTouch, we sent /p:MtouchExtraArgs="--linksdkonly".

None of that worked, so we started looking into the packages installed and we tried to uninstall as many of them as possible but still this didn't work.

Regarding the latter message (ITMS-90809: Deprecated API Usage), we're aware that as of Xamarin Forms 4.5, a new flag was introduced to make sure UIWebView is not referenced. Also, we're aware that as of Xamarin.iOS 13.16, a couple more flags were introduced for relevant purposes: warn-on-type-ref=UIKit.UIWebView to warn us in the build logs if there's any references to UIWebView, and optimize=force-rejected-types-removal to forcefully remove all references to rejected types (including UIWebView) if any were found.

So, here's what we ended up using in MTouch arguments: /p:MtouchExtraArgs="--warn-on-type-ref=UIKit.UIWebView --optimize=experimental-xforms-product-type --optimize=force-rejected-types-removal --linksdkonly", but nonetheless that didn't work and we didn't even receive a warning of any UIWebView references in the build logs.

Ironically, the same configuration did work for us with earlier apps we submitted (with earlier Xamarin.Forms versions) and the warning flag did show us a warning that there was a reference to UIWebView before the linking that no longer existed after the linking.

We'd appreciate it if someone let us know how to fix this or where to look this up or even where shall we open a ticket.

2

2 Answers

0
votes

There are two reasons why Apple reject this submitted version.

ITMS-90338: Non-public API usage - The app references non-public selectors in [project name]: applicationWillTerminate, fontWeight, newSocketQueueForConnectionFromAddress:onSocket:, setOrientation:animated:, socket:didConnectToHost:port:, socket:didReadPartialDataOfLength:tag:, socket:didReceiveTrust:completionHandler:, socket:didWritePartialDataOfLength:tag:, socket:shouldTimeoutReadWithTag:elapsed:bytesDone:, socket:shouldTimeoutWriteWithTag:elapsed:bytesDone:, socketDidCloseReadStream:, socketDidSecure:, terminateWithSuccess.

This means that you need to modify the list names of methods with another name, because these names will conflict with the private method names of Apple's system. You need to find them and replace them with other names.

ITMS-90809: Deprecated API Usage - New apps that use UIWebView are no longer accepted. Instead, use WKWebView for improved security and reliability.

Starting in April 2020, Apple will reject apps that still use the deprecated UIWebView API. While Xamarin.Forms has switched to WKWebView as the default, there is still a reference to the older SDK in the Xamarin.Forms binaries. Current iOS linker behavior does not remove this, and as a result the deprecated UIWebView API will still appear to be referenced from your app when you submit to the App Store.

A preview version of the linker is available to fix this issue. To enable the preview, you will need to supply an additional argument --optimize=experimental-xforms-product-type to the linker.

Detailed steps can refer to UIWebView Deprecation and Xamarin.Forms.

0
votes

We figured it out. After all, the problem was app center libraries being unintendedly referenced in the production build; we have this in our AppDelegate.cs:

#if ENABLE_TEST_CLOUD
                Xamarin.Calabash.Start();
#endif

And it turned out we were accidentally compiling the production build with ENABLE_TEST_CLOUD along with other flags.