Ios 如何在打开UIDocument时显示错误消息?
我有一个基于文档的iOS应用程序,当它第一次打开文档时,主视图控制器调用Ios 如何在打开UIDocument时显示错误消息?,ios,cocoa-touch,ios11,uidocument,Ios,Cocoa Touch,Ios11,Uidocument,我有一个基于文档的iOS应用程序,当它第一次打开文档时,主视图控制器调用UIDocument.open document.open { success in if success { ... set up UI ... } else { ??? } } 这里的问题是,如果success为false,则我无法访问该错误。通常,在这些情况下,苹果的API会向回调传递可选的Error参数,但由于某些原因,这里没有 我在应用程序的UIDocument子类中找到了可以重写的方法: ove
UIDocument.open
document.open { success in
if success { ... set up UI ... }
else { ??? }
}
这里的问题是,如果success
为false,则我无法访问该错误。通常,在这些情况下,苹果的API会向回调传递可选的Error
参数,但由于某些原因,这里没有
我在应用程序的UIDocument
子类中找到了可以重写的方法:
override func handleError(_ error: Error, userInteractionPermitted: Bool) {
现在,在该方法中,我有了错误
,但我无法轻松访问调用document.open的视图控制器,我需要显示类似于UIAlertController
的内容来显示错误消息。此handleError
方法也在非主线程上调用
看起来我需要通过在实例或全局变量中传递信息来进行协调。因为这似乎比苹果通常的设计更尴尬——我希望open
的完成处理程序中会出现错误,所以我想我可能遗漏了一些东西
是否有其他建议的方法获取错误对象并向用户显示消息?Rob
如果你真的想变得“快速”,你可以实现一个闭包来做到这一点,而不需要静态/全局变量
我将首先定义一个枚举,该枚举对UIDocument的API调用的成功和失败案例进行建模。通用结果枚举是一种非常常见的方法
枚举结果{
案例失败(错误)
成功案例(T)
}
在此基础上,我将在类中定义一个可选闭包,用于处理UIDocument.open的结果
我要做的实现是这样的:
类文档管理器:UIDocument{
var OnTestedDocumentOpen:((结果)->无效)?
func打开(文档:UIDocument){
document.open{结果为
guard result else{return}//我们仅在结果成功时继续
//检查以确保有人设置了处理结果的函数
如果让OnAttendedDocumentOpen=self.OnAttendedDocumentOpen{
OnTestedDocumentOpen(.success(result))
}
}
}
重写func handleError(error:error,UserInteractionAllowed:Bool){
//检查以确保有人设置了处理结果的函数
如果让OnAttendedDocumentOpen=self.OnAttendedDocumentOpen{
OnTestedDocumentOpen(.failure(error))
}
}
}
然后,我将从任何一个类使用DocumentManager,您将执行以下操作:
class使用文档管理器的其他类{
让documentManger=DocumentManager()
让someViewController=UIViewController()
func someFunction(){
documentManger.OnAttendedDocumentOpen={(结果)位于
切换结果{
案例。失败(let错误):
DispatchQueue.main.async{
showAlert(目标:self.someViewController,标题:error.localizedDescription)
}
成功案例:
//做点什么
返回
}
}
}
}
好处:这是我编写的一个静态函数,用于在某些视图控制器上显示UIAlertController
/** Easily Create, Customize, and Present an UIAlertController on a UIViewController
- Parameters:
- target: The instance of a UIViewController that you would like to present tye UIAlertController upon.
- title: The `title` for the UIAlertController.
- message: Optional `message` field for the UIAlertController. nil by default
- style: The `preferredStyle` for the UIAlertController. UIAlertControllerStyle.alert by default
- actionList: A list of `UIAlertAction`. If no action is added, `[UIAlertAction(title: "OK", style: .default, handler: nil)]` will be added.
*/
func showAlert(target: UIViewController, title: String, message: String? = nil, style: UIAlertControllerStyle = .alert, actionList: [UIAlertAction] = [UIAlertAction(title: "OK", style: .default, handler: nil)] ) {
let alert = UIAlertController(title: title, message: message, preferredStyle: style)
for action in actionList {
alert.addAction(action)
}
// Check to see if the target viewController current is currently presenting a ViewController
if target.presentedViewController == nil {
target.present(alert, animated: true, completion: nil)
}
}
谁在呼叫document.open?它是视图控制器吗?它在AppDelegate中吗?如果我有更好的理解,我想我能帮上忙。如果它只是一个视图控制器,您可以在视图控制器中覆盖该功能,并能够显示警报。你能分享更多的代码吗?好的,我已经编辑了这个问题,希望能提高一点清晰度。可能除了当你是UIDocument(不是UIViewController)时如何显示警报的问题之外,所有的问题都是重复的。你能不能从AppDelegate中获取根ViewController并用它来显示警报?也许吧。当我试着这样做时,我得到了一个错误,如果我需要讨论的话,我想这应该是一个单独的问题。它说警告:尝试显示不在窗口层次结构中的视图谢谢,我接受这个答案。我同意您的主要观点:为调用UIDocument.open的视图控制器提供某种回调。然而,我对DocumentManager
的设计感到不舒服。您不想在DocumentManager
(使用新的open(doc)
方法)和Document
之间建立is-a关系,后者已经有了open()
方法。我想知道我的handleError()
是否应该调用超类实现?如果我要调用finishedHandlingError(\uu:recovered:)
。