7

Cocoa Bindingsでいつも問題を抱えていたことの1つは、ユーザーが誤った値をフォーマッタを付けたテキストフィールドに入力したときなどのエラー表示です。通常、私はレスポンダチェーンのどこかでwillPresentError:をオーバーライドしますが、Bindingsシステムによって作成されたNSErrorオブジェクトには、何が失敗したかを示すための十分な情報が含まれていないか、エラーでもカスタマイズしたいと思っています。私は、方程式からバインディングを完全に削除し、検証の問題が発生したときに私自身のエラーを作成することができましたが、私はそのような有用なものを投げ捨てるように感じます。バインディングが関係している場合、どのようにNSErrorプレゼンテーションを上書きするのですか?

NSControlデリゲートメソッドを実装し、ビューコントローラのインスタンス変数に失敗したコントロールを格納することで、この問題を回避できました。 willPresentError:が回ってくるまでにnilでなければ、私は何の検証に失敗したのか知っています。

- (BOOL)control:(NSControl *)control didFailToFormatString:(NSString *)string errorDescription:(NSString *)error; 
{ 
    _errorSender = [control retain]; 
    return NO; 
} 

- (NSError *)willPresentError:(NSError *)error; 
{ 
    if (_errorSender != nil) 
    { 
     NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:[error userInfo]]; 
     NSString *help = NSLocalizedString(@"Why are you always messing up? You are a terrible person.", @""); 

     [_errorSender release]; 
     _errorSender = nil; 
     [userInfo setObject:help forKey:NSLocalizedRecoverySuggestionErrorKey]; 

     return [NSError errorWithDomain:[error domain] code:[error code] userInfo:userInfo]; 
    } 

    return [super willPresentError:error]; 
} 

たときに最初の応答者の変更これは動作しますが、私は、ビューコントローラにcommitEditingを呼び出し、それは私には部分的にしか役立ちますないとき。

私が見ることができる唯一の他の選択肢は、NSFormatterを式から外し、コアデータ管理対象オブジェクトでvalidateValue:forKey:error:を使用して検証を処理することです。これはフォーマッタを使用するのと同じくらい私には意味がありませんが、少なくともNSErrorオブジェクトを完全に制御できます。

このような種類のエラー処理を行うには、何かが欠けているはずです。助言がありますか?

答えて

4

I could completely remove bindings from the equation and create my own errors when validation problems occur, but I feel like I would be throwing out some useful stuff that way.

あなたは別のエラー(そのuserInfoそのキーが含まれている1)で1つのエラー(そのキーのオブジェクト)をラップするNSUnderlyingErrorKeyを使用することができます。

The only other option I can see is taking NSFormatter out of the equation, and using validateValue:forKey:error: in my Core Data managed objects to handle validation. This doesn't make as much sense to me as using a formatter, but at least I'd have full control over the NSError object.

これらは2つのレベルであり、相互に排他的ではありません。フォーマッタの検証はビューレイヤーで行われます。キー値の検証(この場合、管理オブジェクト内)はモデルレイヤーにあります。

ビューレイヤで問題のバリデーションが行われる場合は、NSFormatterクラスをサブクラス化しておいてください(まだ実装していない場合)。getObjectValue:forString:errorDescription:を実装して、より具体的なエラーの説明を返します。 (私はバインディングが実際にかかわらず、このエラーの説明を使用するかどうかはわかりません。あなたがチェックする必要があります。)検証は、モデル層で起こる必要がある場合は、validate<Key>:error:validateValue:forKey:error:のシングル財産版)を実装

あなたNSManagedObjectのサブクラスで。

制約の一部がモデルレイヤーにあり、その他がビューレイヤーにある場合は、両方を実行します。あなたのアプリとあなたの小切手に合っていれば、フォーマッタや他の小切手のチェックを実装することは自由です。

+1

NSFormatterをサブクラス化していますが、バインディングではNSStringエラーメッセージを使用していますが、最後のNSAlertはまだかなり骨がありません(エラーに回復提案を追加したいと思います)。私が行っている検証は、NSFormatterのサブクラスに適しているようです。そのため、私のモデルにキー値の検証を実装することを躊躇しています。私は、何か問題が起きたときにフロントエンドのエラーメッセージをカスタマイズできるように、データモデルとは関係のないあらゆる種類の文字列解析を終わらせます。 –

関連する問題