ios - 在将 Xamarin iOS 提交到 Apple AppStoreConnect TestFlight 时获取“ITMS-90338:非公共 API 使用”和“ITMS-90809:已弃用的 API 使用”
问题描述
在将 Xamarin.Forms iOS 应用提交到 Apple 的 TestFlight 后,我们会收到以下消息。
消息:
亲爱的开发者,
我们发现您的应用最近交付的一个或多个问题,“[bundle name]”[bundle version]([bundle version])。请更正以下问题,然后重新上传。
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:, terminateWithSuccess。如果您的源代码中的方法名称与上面列出的私有 Apple API 匹配,则更改您的方法名称将有助于防止此应用在以后的提交中被标记。此外,请注意,上述一个或多个 API 可能位于您的应用程序随附的静态库中。如果是这样,它们必须被删除。 http://developer.apple.com/support/technical/
ITMS-90809:不推荐使用的 API - 不再接受使用 UIWebView 的新应用程序。相反,使用 WKWebView 来提高安全性和可靠性。了解更多(https://developer.apple.com/documentation/uikit/uiwebview)。
最好的祝福,
应用商店团队
我查看了消息并进行了太多尝试均无济于事。如果有人可以帮助让 Apple 接受我们的提交,我将不胜感激。
让我分享更多关于
环境:
这是我们使用 Azure DevOps 的构建管道(特别是Xamarin.iOS 任务版本 2.*)构建并使用 Azure DevOps 的发布管道发布的 Xamarin.Forms 应用。我们将它发布到 Microsoft AppCenter,然后*.ipa
从那里下载。我们使用来自 Apple AppStore 的 Mac 上的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
已被删除。
在我们的项目中,我们仅在一个页面中使用 Web 视图,即使 Xamarin 的默认渲染器已更改WkWebView
为WkWebView
新控件)。
跨平台控制:
public class CustomWebView : Xamarin.Forms.WebView
{
}
iOS 特定的渲染器:
[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
{
}
}
Azure 构建管道上使用的构建代理:macos-10.15(可以在该链接上找到代理的完整规范)。
我们尝试了什么:
关于第一条消息(ITMS-90338:非公共 API 使用),在处理了 Stackoverflow 和 Xamarin 论坛上的大量帖子后,我们发现人们建议我们应该将链接行为设置为Link SDK Only
(我们已经为每个构建设置了链接行为)配置),但是为了确定,我们决定告诉 MSBuild 和 MTouch 以确保这是使用的链接行为。
我们开始在管道任务的参数部分发送/p:MtouchLink="SdkOnly"
到 MSBuild ;对于 MTouch,我们发送了./p:MtouchExtraArgs="--linksdkonly"
这些都不起作用,所以我们开始查看已安装的软件包,并尝试尽可能多地卸载它们,但这仍然不起作用。
关于后一条消息 (ITMS-90809: Deprecated API Usage),我们知道从 Xamarin Forms 4.5 开始,引入了一个新标志以确保UIWebView
不被引用。此外,我们知道,从Xamarin.iOS 13.16开始,为了相关目的引入了更多标志:warn-on-type-ref=UIKit.UIWebView
在构建日志中警告我们是否有任何对 的引用UIWebView
,并optimize=force-rejected-types-removal
强制删除对被拒绝类型(包括UIWebView
)的所有引用,如果任何被发现。
所以,这就是我们最终在 MTouch 参数中使用的内容:/p:MtouchExtraArgs="--warn-on-type-ref=UIKit.UIWebView --optimize=experimental-xforms-product-type --optimize=force-rejected-types-removal --linksdkonly"
,但仍然没有用,我们甚至没有收到UIWebView
构建日志中任何引用的警告。
具有讽刺意味的是,对于我们提交的早期应用程序(使用早期 Xamarin.Forms 版本),相同的配置确实对我们有用,并且警告标志确实向我们显示了一个警告,即在链接之前存在引用,而UIWebView
在链接之后不再存在。
如果有人让我们知道如何解决此问题或在哪里查找此问题,甚至我们应该在哪里开票,我们将不胜感激。
解决方案
苹果拒绝这个提交的版本有两个原因。
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:, terminateWithSuccess。
这意味着您需要将方法的列表名称修改为另一个名称,因为这些名称会与 Apple 系统的私有方法名称冲突。您需要找到它们并用其他名称替换它们。
ITMS-90809:不推荐使用的 API - 不再接受使用 UIWebView 的新应用程序。相反,使用 WKWebView 来提高安全性和可靠性。
从 2020 年 4 月开始,Apple 将拒绝仍使用已弃用UIWebView
API 的应用程序。虽然 Xamarin.Forms 已切换WKWebView
为默认设置,但在 Xamarin.Forms 二进制文件中仍有对旧 SDK 的引用。当前的 iOS 链接器行为并没有消除这一点,因此UIWebView
当您提交到 App Store 时,您的应用程序仍然会引用已弃用的 API。
链接器的预览版本可用于解决此问题。要启用预览,您需要为--optimize=experimental-xforms-product-type
链接器提供一个附加参数。
推荐阅读
- java - 在 JPA 存储库中自定义“查找”逻辑
- c++ - 读取变量时出错:无法访问地址 x 处的内存
- java - 具有相同路径但具有不同 @RequestParam 值的多个端点
- javascript - 根据类名在画布上绘制 Font Awesome 图标
- sql - 在 pyspark 问题中转换 24 小时日期格式
- c++ - C ++将数组传递给函数而无需复制
- sql - 比较 SQL(或 AWS QuickSight)中的字符差异
- regex - 正则表达式多行
- apache-kafka - 即使没有启动记录的主题压缩,GlobalKTable 是否总是每个分区键只有 1 条记录?
- c++ - 针对循环优化 OpenCV