在将 Xamarin iOS 提交到 Apple AppStoreConnect TestFlight 时获取“ITMS-90338:非公共 API 使用”和“ITMS-90809:已弃用的 API 使用” 已安装的 NuGet 包/第 3 方库:

问题描述

在向 Apple 的 TestFlight 提交 Xamarin.Forms iOS 应用后,我们收到以下消息。

消息:

亲爱的开发者:

我们发现您的应用最近交付的一个或多个问题, “[捆绑包名称]”[捆绑包版本]([捆绑包版本])。请更正以下内容 问题,然后重新上传

ITMS-90338:非公开 API 使用 - 应用引用非公开 [项目名称] 中的选择器: applicationWillTerminate,fontWeight,newSocketQueueForConnectionFromAddress:onSocket:,setorientation:animated:,socket:didConnectToHost:port:,socket:didReadPartialDataOfLength:tag:,套接字:didReceiveTrust:completionHandler:, 套接字:didWritePartialDataOfLength:标签:, socket:shouldTimeoutReadWithTag:elapsed:bytesDone:,socket:shouldTimeoutWriteWithTag:elapsed:bytesDone:,socketDidCloseReadStream:,socketDidSecure:,terminateWithSuccess。如果 源代码中的方法名称与列出的私有 Apple API 匹配 以上,更改您的方法名称将有助于防止此应用程序 在以后的提交中被标记。此外,请注意,一个或 更多的上述 API 可能位于一个静态库中 包含在您的应用程序中。如果是这样,它们必须被移除。为了更进一步的 信息,请访问技术支持信息,网址为 http://developer.apple.com/support/technical/

ITMS-90809:已弃用的 API 使用 - 使用 UIWebView 的新应用程序不适用 不再接受。相反,使用 WKWebView 来提高安全性和 可靠性。了解更多 (https://developer.apple.com/documentation/uikit/uiwebview)。

最好的问候,

应用商店团队

我已经查找了这些消息并尝试了很多都无济于事。如果有人能帮助 Apple 接受我们的提交,我将不胜感激。

让我分享更多关于

的细节

环境:

这是一个 Xamarin.Forms 应用,我们使用 Azure DevOps 的构建管道(特别是 Xamarin.iOS task 版本 2.*)构建并使用 Azure DevOps 的发布管道发布。我们将其发布到 Microsoft AppCenter,然后从那里下载 *.ipa。我们在 Mac 上使用 Apple AppStore 中的 Transporter 应用程序将其提交给 Apple 的 AppStoreConnect TestFlight。

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

已安装的 NuGet 包/第 3 方库:

<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>

显然,该应用正在使用 Xamarin.Forms 5,其中对 UIWebView has been removed 的引用。

在我们的项目中,我们仅在一个页面中使用 Web 视图,尽管 Xamarin 的认渲染器已更改为 WkWebView,但我们已经为此创建了一个自定义渲染器以使用 {{1} } 以防万一(当然我们确保使用新控件)。

跨平台控制:

WkWebView

iOS 特定的渲染器:

public class CustomWebView : Xamarin.Forms.WebView
{
}

Azure 构建管道上使用的构建代理macos-10.15(可以在该 link 上找到代理的完整规范)。

我们的尝试:

关于第一条消息(ITMS-90338:非公共 API 使用),在处理了 Stackoverflow 和 Xamarin 论坛上的大量帖子后,我们发现人们建议我们应该将链接行为设置为 [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 { } } (即我们已经为每个构建配置做了),但是为了确定,我们决定告诉 MSBuild 和 MTouch 以确保这是使用的链接行为。

我们开始在 the pipeline task 的参数部分向 MSBuild 发送 Link SDK Only;我们向 MTouch 发送了 /p:MtouchLink="SdkOnly"

这些都没有奏效,所以我们开始调查安装的软件包,并尝试卸载尽可能多的软件包,但仍然没有用。

关于后一条消息 (ITMS-90809: Deprecated API Usage),我们知道 as of Xamarin Forms 4.5,a new flag was introduced 以确保 /p:MtouchExtraArgs="--linksdkonly" 未被引用。此外,我们知道从 Xamarin.iOS 13.16 起,出于相关目的引入了更多标志:UIWebView 用于在构建日志中警告我们是否有任何对 warn-on-type-ref=UIKit.UIWebView 的引用,以及 { {1}} 以强行删除对被拒绝类型(包括 UIWebView)的所有引用(如果有)。

所以,以下是我们最终在 MTouch 参数中使用的内容optimize=force-rejected-types-removal,但这仍然不起作用,我们甚至没有在构建日志中收到任何 UIWebView 引用的警告。

具有讽刺意味的是,相同的配置确实适用于我们提交的早期应用程序(使用早期 Xamarin.Forms 版本),并且警告标志确实向我们显示警告,在链接之前存在对 /p:MtouchExtraArgs="--warn-on-type-ref=UIKit.UIWebView --optimize=experimental-xforms-product-type --optimize=force-rejected-types-removal --linksdkonly" 的引用,没有链接后不再存在。

如果有人让我们知道如何解决这个问题或在哪里查找这个问题,甚至我们应该在哪里开票,我们将不胜感激。

解决方法

Apple 拒绝此提交版本的原因有两个。

ITMS-90338:非公共 API 使用 - 应用程序引用 [项目名称] 中的非公共选择器: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:,terminateWith.

这意味着你需要修改其他名称的方法列表名称,因为这些名称会与苹果系统的私有方法名称冲突。您需要找到它们并用其他名称替换它们。

ITMS-90809:不推荐使用 API - 不再接受使用 UIWebView 的新应用。而是使用 WKWebView 来提高安全性和可靠性。

从 2020 年 4 月开始,仍使用已弃用的 UIWebView API 的 Apple will reject apps。虽然 Xamarin.Forms 已切换到 WKWebView 作为默认值,但 Xamarin.Forms 二进制文件中仍存在对旧版 SDK 的引用。当前的 iOS 链接器行为并没有消除这一点,因此当您提交到 App Store 时,已弃用的 UIWebView API 似乎仍会从您的应用中引用。

链接器的预览版本可用于解决此问题。要启用预览,您需要向链接器提供额外的参数 --optimize=experimental-xforms-product-type

详细步骤可以参考UIWebView Deprecation and Xamarin.Forms

,

我们想通了。毕竟,问题是在生产版本中无意中引用了应用中心库;我们的AppDelegate.cs中有这个:

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

结果是我们不小心用 ENABLE_TEST_CLOUD 和其他标志编译了生产版本。