Xamarin.iOS 9 – 故障排除

本文提供了在 Xamarin.iOS 应用中使用 iOS 9 的几个故障排除提示。

iOS 8 模拟器在哪里?

如果已安装 Xcode 7(或更高版本),默认情况下,它会自动将所有 iOS 8 模拟器替换为 iOS 9 模拟器。 如果仍需要在 iOS 8 上进行测试,可以启动 Xcode,然后下载并安装 iOS 8 模拟器。

在 Xcode 中 ,选择“Xcode ”菜单,然后选择 “首选项...”>下载

iOS 8 Simulators Downloads

选择“立即检查并安装”按钮以重新安装 iOS 8 模拟器。

具有左/右属性错误的布局约束

在 iOS 8(及更早版本中),情节提要中的 UI 元素可以在同一布局中使用右和左属性(NSLayoutAttributeRight& NSLayoutAttributeLeft和前导尾随属性) NSLayoutAttributeTrailingNSLayoutAttributeLeading 的组合

如果同一情节提要在 iOS 9 中运行,则会导致出现以下形式的异常:

由于未捕获的异常“NSInvalidArgumentException”而终止应用,原因:“*** +[NSLayoutConstraint constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:]:不能在前导/尾随属性和右/左属性之间进行约束。 对两者或两者都使用前导/尾随。

iOS 9 强制实施布局以使用向右前导尾随属性,但不能同时使用这两个属性。 若要解决此问题,请更改所有布局约束,以使用情节提要文件中设置的相同属性。

有关详细信息,请参阅 iOS 9 约束错误 Stack Overflow 讨论。

错误 ITMS-90535:意外的 CFBundleExecutable 密钥

切换到 iOS 9 后,从应用使用第三方组件(特别是我们现有的 Google 地图 组件)在 iOS 8(或更早版本)上编译和运行),尝试将新生成提交到 iTunes 连接可以在表单中收到错误:

错误 ITMS-90535:意外的 CFBundleExecutable 密钥。 “Payload/app-name.app/component.bundle”上的捆绑包不包含捆绑包可执行文件...

通常可以通过在项目中查找命名捆绑包来解决此问题,就像错误消息所建议的那样,通过删除密钥来CFBundleExecutable编辑Info.plist捆绑包中的问题。 CFBundlePackageType还应将密钥设置为BNDL该键。

进行这些更改后,请清理并重新生成整个项目。 进行这些更改后,可以提交到 iTunes 连接,而不会出现问题。

有关详细信息,请参阅此 Stack Overflow 讨论。

CFNetwork SSLHandshake 失败 (-9824) 错误

尝试直接或从 iOS 9 中的 Web 视图连接到 Internet 时,可能会收到以下格式的错误:

2015-09-04 14:38:05.757 FormsWebViewiOS[2553:30362] CFNetwork SSLHandshake failed (-9824)
2015-09-04 14:38:05.758 FormsWebViewiOS[2553:30363] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)

或者采用以下形式:

2015-09-04 14:39:17.881 FormsWebViewiOS[2568:30974] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure.
Temporary exceptions can be configured via your app's Info.plist file.

在 iOS9 中,应用传输安全(ATS)强制在 Internet 资源(例如应用的后端服务器)和应用之间建立安全连接。 此外,ATS 要求使用 HTTPS 协议和高级 API 通信进行通信,以便使用 TLS 版本 1.2 和转发保密进行加密。

由于 ATS 默认在为 iOS 9 和 OS X 10.11(El Capitan)生成的应用中启用,因此使用 NSURLConnection的所有 CFURL连接或 NSURLSession 将受到 ATS 安全要求的约束。 如果连接不符合这些要求,它们将失败并出现异常。

有关如何解决此问题的信息,请参阅应用传输安全指南的 ATS 选择退出部分。

我的现有应用未在 iOS 9 上运行

有关重新生成和重新部署现有应用以在 iOS 9 上运行的说明,请参阅 iOS 9 兼容性信息

构造函数中的 UICollectionViewCell.ContentView 为 Null

原因: 在 iOS 9 中, initWithFrame: 由于 iOS 9 中的行为更改,因此需要构造函数作为 UICollectionView 文档状态。 如果为指定的标识符注册了类,并且必须创建新单元格,则现在通过调用其 initWithFrame: 方法初始化该单元格。

修复: 添加如下所示的 initWithFrame: 构造函数:

[Export ("initWithFrame:")]
public YourCellClassName (CGRect frame) : base (frame)
{
    Initialize (); // refactor initialize code into a method
}

相关示例: MotionGraphTextKitDemo

从 Xib/Nib 加载视图时,UIView 无法使用 Coder Init

原因:initWithCoder:从接口生成器 Xib 文件加载视图时调用构造函数。 如果未导出此构造函数,则非托管代码无法调用它的托管版本。 以前(例如在 iOS 8 中), IntPtr 调用构造函数来初始化视图。

修复: 创建和导出 initWithCoder: 构造函数,如下所示:

[Export ("initWithCoder:")]
public YourClassName (NSCoder coder) : base (coder)
{
    Initialize (); // refactor initialize code into a method
}

相关示例: 聊天

Dyld 消息:没有名称的缓存映像...

在日志中可能会遇到以下信息的崩溃:

Dyld Error Message:
Dyld Message: no cach image with name (/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore)

原因: 这是 Apple 本机链接器中的一个 bug,当它们公开专用框架(在 iOS 7 中公开 JavaScriptCore 之前是专用框架),并且应用的部署目标是在框架专用时用于 iOS 版本。 在这种情况下,Apple 的链接器将链接到框架的专用版本,而不是公共版本。

修复: 这将针对 iOS 9 进行寻址,但有一种简单的解决方法,你可以同时自行应用:只需针对项目中的更高 iOS 版本(在本例中可以尝试 iOS 7)。 其他框架可能表现出类似的问题,例如 WebKit 框架在 iOS 8 中公开(因此面向 iOS 7 将导致此错误;应将 iOS 8 定向到应用中使用 WebKit)。

不受信任的企业开发人员

尝试在实际 iOS 硬件上运行 Xamarin.iOS 应用的 iOS 9 版本时,可能会收到一条消息,指出开发人员帐户在设备上不受信任。 例如:

Untrusted Enterprise Developer alert

若要解决此问题,请执行以下操作:

  1. 在开发 Mac 上启动 Xcode (最新 beta 版本)。

  2. “窗口”菜单中选择“设备”以打开“设备”窗口:

    The Devices Window

  3. “设备 ”端面板中,选择设备,右键单击并选择“ 显示预配配置文件...”

    SShow Provisioning Profiles

  4. 选择设备上当前存在的每个预配配置文件,然后选择 - 用于删除它的按钮:

    Deleting a provisioning profile

  5. “Xcode ”菜单中,选择“ 首选项...”“帐户

    Xcode account preferences

  6. 单击“查看详细信息...”按钮,然后选择“下载所有”按钮:

    Download all profiles

  7. 列表完成更新后,选择“ 完成 ”按钮并关闭“首选项”窗口。

  8. 从 iOS 设备中删除尝试测试的 Xamarin.iOS 应用的现有版本。

  9. 返回到 Visual Studio for Mac,执行干净生成,并尝试在设备上重新运行应用。

在看到 Xcode 加载的新预配配置文件之前,可能需要停止并重启 Visual Studio for Mac。 你可能还需要调整 Xamarin.iOS 应用的 iOS 捆绑签名 选项,以选择新的预配配置文件。

启动屏幕问题

iOS 9 现在强制实施启动屏幕要求,以便不再重复使用相同的启动图像来支持不同的界面方向。 有关详细信息,请参阅 Apple 的 UILanchImage 参考

(可选)可以使用情节提要文件来呈现应用的启动屏幕,而不是使用一组 .png 图像文件。 这是 Apple 提供启动屏幕的首选方法。 有关详细信息,请参阅我们的统一情节提要指南。

最后,你的应用必须使用情节提要文件作为其启动屏幕,并支持所有四个界面方向(纵向、倒排纵向、横向向左和横向向右)以考虑在“幻灯片翻过”面板或拆分视图模式下运行。 要详细了解 iOS 9 的新多任务处理功能,请参阅我们的 iPad 多任务处理指南。

NSInternalInconsistencyException 异常

编译并运行适用于 iOS 9 的现有 Xamarin.iOS 应用时,可能会收到以下格式的错误:

Objective-C 引发异常。 名称:NSInternalInconsistencyException 原因:应用程序窗口预期在应用程序启动结束时具有根视图控制器

由于应用 Windows 预计在应用程序启动结束时具有根视图控制器,并且现有应用不会引发此错误。

此问题至少有两种可能的解决方法:

  1. 更新应用以使用情节提要文件而不是 xib 文件来定义其用户界面。 这需要大量的时间来更正,具体取决于应用的大小以及如何使用 Xcode 的 Interface Builder 布局情节提要的知识。 有关详细信息,请参阅我们的 统一情节提要 简介文档。
  2. RootViewControllerFinishedLaunching类中AppDelegate设置应用窗口的属性,以指向应用的 UI 中的视图控制器。

何时初始化视图和视图控制器

使用 Xamarin.iOS 时,可以在构造函数内初始化视图或视图控制器,这些构造函数在托管代码中公开内容时调用,但会中断 iOS 设计。

通常,不应初始化任何可以从构造函数回调 Objective-C 代码的任何内容,因为无法确定何时调用它。 这也意味着有一个更好的位置(其他 .ctor)或调用重写(没有 Objective-C 事件),在这种情况下,应该进行此初始化。