Xamarin.iOS 9 - 故障排除
本文提供了一些有关在 Xamarin.iOS 应用中使用 iOS 9 的故障排除提示。
iOS 8 模拟器在哪里?
如果已安装 Xcode 7(或更高版本),默认情况下,它会自动将所有 iOS 8 模拟器替换为 iOS 9 模拟器。 如果仍需要在 iOS 8 上进行测试,可启动 Xcode,然后下载并安装 iOS 8 模拟器。
在 Xcode 中,选择“Xcode”菜单,然后选择“首选项...”>“下载”:
选择“立即检查并安装”按钮,重新安装 iOS 8 模拟器。
具有向左/向右特性错误的布局约束
在 iOS 8(及更低版本中),Storyboard 中的 UI 元素可在同一布局中使用向右特性和向左特性(NSLayoutAttributeRight
和 NSLayoutAttributeLeft
)以及前导特性和尾随特性(NSLayoutAttributeLeading
和 NSLayoutAttributeTrailing
)的组合。
如果同一 Storyboard 在 iOS 9 中运行,则会导致出现以下形式的异常:
由于未捕获的异常 "NSInvalidArgumentException" 而终止应用,原因: "***+[NSLayoutConstraint constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:]: 无法在前导/尾随特性和向右/向左特性之间进行约束。 对两者使用前导/尾随,或两者都不使用。"
iOS 9 强制实施布局以使用向右和左或前导和尾随属性,但不能同时使用这两个属性。 为了解决此问题,请更改所有布局约束,使用 Storyboard 文件中设置的相同特性。
有关详细信息,请参阅 Stack Overflow 上关于 iOS 9 约束错误的讨论。
错误 ITMS-90535:意外的 CFBundleExecutable 密钥
从使用在 iOS 8(或更低版本)上编译和运行的第三方组件(尤其是我们的现有 Google 地图组件)的应用切换到 iOS 9 之后,当尝试将新版本提交到 iTunes Connect 时,可能会遇到以下形式的错误:
错误 ITMS-90535: 意外的 CFBundleExecutable 密钥. "Payload/app-name.app/component.bundle" 上的捆绑包中没有捆绑包可执行文件...
要解决此问题,通常可在项目中查找命名捆绑包,然后就像错误消息所建议的那样,通过删除 CFBundleExecutable
键来编辑捆绑包中的 Info.plist
。 还应将 CFBundlePackageType
键设置为 BNDL
。
进行这些更改后,请清理并重新生成整个项目。 进行这些更改后,可以提交到 iTunes Connect,而不会出现问题。
有关详细信息,请参阅此 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 进行加密。
由于为 iOS 9 和 OS X 10.11 (El Capitan) 生成的应用中默认启用了 ATS,因此使用 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
}
相关示例:MotionGraph、TextKitDemo
从 Xib/Nib 加载视图时,UIView 无法使用编码器进行初始化
原因:从 Interface Builder Xib 文件加载视图时会调用 initWithCoder:
构造函数。 如果未导出此构造函数,非托管代码无法调用其托管版本。 以前(例如在 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 版本时,可能会收到一条消息,指出你的开发人员帐户在设备上不受信任。 例如:
要解决此问题,请执行以下操作:
在开发 Mac 上启动 Xcode (最新 beta 版本)。
从“窗口”菜单中选择“设备”以打开“设备”窗口:
在“设备”端面板中,选择你的设备,右键单击并选择“显示预配配置文件...”:
选择设备上当前存在的每个预配配置文件,然后选择 - 按钮来将其删除:
从“Xcode”菜单中选择“首选项...”和“帐户”:
单击“查看详细信息...”按钮,然后选择“全部下载”按钮:
列表更新完毕后,选择“完成”按钮并关闭“首选项”窗口。
从 iOS 设备中删除尝试测试的 Xamarin.iOS 应用的现有版本。
返回到 Visual Studio for Mac,执行干净生成,然后尝试在设备上重新运行应用。
在看到 Xcode 加载的新的预配配置文件之前,可能需要停止再重启 Visual Studio for Mac。 你可能还需要调整 Xamarin.iOS 应用的“iOS 捆绑包签名”选项,选择新的预配配置文件。
启动屏幕问题
iOS 9 现在强制实施启动屏幕要求,以便不再重用相同的启动图像来支持不同的界面方向。 有关详细信息,请查看 Apple 的 UILanchImage 参考。
(可选)可以使用 storyboard 文件来呈现应用的启动屏幕,而不是使用一组 .png 图像文件。 这是 Apple 提供启动屏幕的首选方法。 有关详细信息,请参阅我们的统一 Storyboard 简介指南。
最后,你的应用必须使用 storyboard 文件来展示其启动屏幕,并支持所有四个界面方向(纵向、反置纵向、横向向左和横向向右)以考虑在“侧拉窗口”面板或“拆分视图”模式下运行。 要详细了解 iOS 9 的新多任务处理功能,请参阅我们的 iPad 多任务处理指南。
NSInternalInconsistencyException 异常
编译并运行适用于 iOS 9 的现有 Xamarin.iOS 应用时,可能会收到以下形式的错误:
引发 Objective-C 异常。 名称: NSInternalInconsistencyException 原因: 应用程序窗口预期在应用程序启动结束时具有根视图控制器
由于应用窗口预计在应用程序启动结束时具有根视图控制器,而现有应用没有,则会引发此错误。
此问题至少有两种可能的解决方法:
- 更新应用来使用 storyboard 文件而不是
xib
文件定义其用户界面。 这需要大量的时间来更正,这取决于应用的大小以及关于如何使用 Xcode Interface Builder 设置 storyboard 部署的了解。 有关详细信息,请参阅我们的统一情节提要简介文档。 - 在
AppDelegate
类中的FinishedLaunching
方法中设置应用窗口的RootViewController
属性,以指向应用 UI 中的视图控制器。
何时初始化视图和视图控制器
使用 Xamarin.iOS 时,可以在构造函数内初始化视图或视图控制器,这些构造函数在托管代码中公开内容时调用,但这会中断 iOS 设计。
通常,不应初始化任何可从构造函数回调 Objective-C 代码的内容,因为无法确定何时调用它。 这也意味着有一个更好的为止(其他 .ctor)或对重写的调用(由于 Objective-C 没有任何事件),在这种情况下,应进行此初始化。