iOS 中 NSErrorRecoveryAttempting、NSError 和 UIAlertView 的正确用法是什么?

发布于 2024-11-06 07:51:24 字数 274 浏览 11 评论 0原文

我无法找到在 iOS 上一起使用 NSErrorUIAlertViewNSErrorRecoveryAttempting 的正确方法的示例。我能找到的大多数文档和示例都涵盖了 OS X 上的等效功能,其中相关行为由 Cocoa 集成。但在 iOS 中,似乎有必要“手动”执行此操作,并且我找不到如何完成此操作的好示例。

我非常感谢一些使用 NSError 中的信息来支持从向用户报告的 NSErrors 进行恢复尝试的最佳实践示例。

I'm having trouble finding examples of the correct way to use NSError, UIAlertView, and NSErrorRecoveryAttempting together on iOS. Most of the documentation and examples I can find cover the equivalent functionality on OS X, where the relevant behaviors are integrated by Cocoa. But in iOS it seems to be necessary do do this "by hand", and I can't find good examples of how it's done.

I'd very much appreciate a few examples of best practice in using information in NSError to support recovery attempts from NSErrors reported to the user.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

滥情空心 2024-11-13 07:51:24

根据苹果的文档:

重要提示:NSError 类在 Mac OS X 和 iOS 上都可用。但是,错误响应程序和错误恢复 API 和机制仅在应用程序工具包 (Mac OS X) 中可用。

因此,我不确定您是否可以使用 NSErrorRecoveryAttempting 即使它似乎在文档中定义了(看起来这是 UIKit 文档的一个区域,在更新后尚未更新)从 AppKit 的文档复制)。

以下是我处理代码中错误的方法:

NSError *error = nil;
id result = [SomeClass doSomething:&error];

if (!result) {
    NSLog(@"Do something failed: %@", error);
    UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Something failed!" message:@"There was an error doing something." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
    [alert show];
    return;
}

According to Apple's documentation:

Important: The NSError class is available on both Mac OS X and iOS. However, the error-responder and error-recovery APIs and mechanisms are available only in the Application Kit (Mac OS X).

So, I'm not sure if you can use NSErrorRecoveryAttempting even though it does appear to be defined in the documentation (it looks like this is an area of the UIKit docs that have not yet been updated after being copied from AppKit's documentation).

Here is how I handle errors in my code:

NSError *error = nil;
id result = [SomeClass doSomething:&error];

if (!result) {
    NSLog(@"Do something failed: %@", error);
    UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Something failed!" message:@"There was an error doing something." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
    [alert show];
    return;
}
笨死的猪 2024-11-13 07:51:24

我找到了一个很好的例子。

以下博客文章和 GitHub 代码(包括示例项目)

请参阅 James Beith http 的 ://www.realmacsoftware.com/blog/cocoa-error-handling-and-recovery

https://github.com/realmacsoftware/RMErrorRecoveryAttempter

我能够在 iPhone 模拟器上成功使用它。

I found a great example of this.

See the following blog post and GitHub code (including sample project) by James Beith

http://www.realmacsoftware.com/blog/cocoa-error-handling-and-recovery

https://github.com/realmacsoftware/RMErrorRecoveryAttempter

I was able to successfully use this on the iPhone simulator.

恬淡成诗 2024-11-13 07:51:24

我试图在 UIKit 中镜像 AppKit 的错误处理机制,主要是因为我想利用响应者链向上转发错误。我还没有对此进行充分测试,但目前它看起来如下所示。

它非常接近地反映了 AppKit,但可以重写 will/did 挂钩以分别执行自定义错误呈现和恢复。默认行为是显示 UIAlertView 进行演示并使用 psuedo-NSErrorRecoveryAttempting 对象进行恢复。

@implementation UIResponder (ErrorHandling)

- (void)presentError:(NSError *)error
        completion:(void (^)(BOOL recovered))completion
{
    if (nil == (error = [self willPresentError:error])) {
        return;
    }
    if (self.nextResponder) {
        [self.nextResponder presentError:error completion:completion];
        return;
    }

    // Code to create and show UIAlertView
    // e.g. https://github.com/jayway/CWUIKit/blob/master/Classes/UIAlertView%2BCWErrorHandler.m

    // The UIAlertViewDelegate calls didPresentError...
}

/*
 Override to customise the error object as in AppKit.
 You can also perform your own error presentation, and return nil to terminate the default handling.
 Custom error presentation UI should still call didPresentError... when dismissed
 */
- (NSError *)willPresentError:(NSError *)error
{
    return error;
}

/*
 Override to perform custom error recovery.
 */
- (void)didPresentError:(NSError *)error optionIndex:(NSInteger)optionIndex completion:(void (^)(BOOL recovered))completion
{
    id recoveryAttempter = [error recoveryAttempter];
    if ([recoveryAttempter respondsToSelector:@selector(attemptRecoveryFromError:optionIndex:completion:)]) {
        [recoveryAttempter attemptRecoveryFromError:error optionIndex:optionIndex completion:completion];
    }
}

@end

I'm trying to mirror AppKit's error handling mechanism in UIKit, mainly because I want to take advantage of the responder chain to forward errors upwards. I haven't tested this fully, but at the moment it's looking like below.

It reflects AppKit pretty closely, but the will/did hooks can be overridden to perform custom error presentation and recovery respectively. The default behaviour is to show a UIAlertView for presentation and use a psuedo-NSErrorRecoveryAttempting object for recovery.

@implementation UIResponder (ErrorHandling)

- (void)presentError:(NSError *)error
        completion:(void (^)(BOOL recovered))completion
{
    if (nil == (error = [self willPresentError:error])) {
        return;
    }
    if (self.nextResponder) {
        [self.nextResponder presentError:error completion:completion];
        return;
    }

    // Code to create and show UIAlertView
    // e.g. https://github.com/jayway/CWUIKit/blob/master/Classes/UIAlertView%2BCWErrorHandler.m

    // The UIAlertViewDelegate calls didPresentError...
}

/*
 Override to customise the error object as in AppKit.
 You can also perform your own error presentation, and return nil to terminate the default handling.
 Custom error presentation UI should still call didPresentError... when dismissed
 */
- (NSError *)willPresentError:(NSError *)error
{
    return error;
}

/*
 Override to perform custom error recovery.
 */
- (void)didPresentError:(NSError *)error optionIndex:(NSInteger)optionIndex completion:(void (^)(BOOL recovered))completion
{
    id recoveryAttempter = [error recoveryAttempter];
    if ([recoveryAttempter respondsToSelector:@selector(attemptRecoveryFromError:optionIndex:completion:)]) {
        [recoveryAttempter attemptRecoveryFromError:error optionIndex:optionIndex completion:completion];
    }
}

@end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文