1

一部の NSPredicateEditor/NSPredicateEditorRowTemplate値が OS X によって自動的にローカライズされていることがわかりました。

.equalToこれは、演算子の文字列へのマッピングで簡単に確認できますis

しかし、UTI 文字列がその UTI の人間が読めるバージョンにマッピングされていることに気付きました。

以下、設定したの"public.image"ですが と表示されてしまいます"image"

NSPredicateEditor の UTI 演算子

func setupPredicateEditor() {
    let left = [NSExpression(forKeyPath: "Type")]

    let operators = [NSComparisonPredicate.Operator.equalTo.rawValue as NSNumber]

    let right = [
        NSExpression(forConstantValue: "public.image"),
        NSExpression(forConstantValue: "public.text"),
        NSExpression(forConstantValue: "public.fakeUTI"),
        ];

    let rowTemplate = NSPredicateEditorRowTemplate.init(leftExpressions: left, rightExpressions: right, modifier: .all, operators: operators, options: 0)
    predicateEditor.rowTemplates = [rowTemplate]

    predicateEditor.addRow(self)
}

特定の有効な UTI のみがこの方法でマップされます。Operators と UTI 以外の他の形式に自動ローカライズされた文字列が与えられるかどうかはわかりません。

NSPredicateEditor と Row Templatesをローカライズしたいので、これは問題です。

述語をローカライズするプロセスには、キーをローカライズされた値に一致させることが含まれます。

KEY: "%[left]@ %[is]@ %[right]@"
VAL: "%1$[left_display_string]@ %2$[is]@ %3$[right_display_string]@"

問題は、キーの値がUI に表示される文字列と一致する必要があることです。行テンプレートの左右の式に最初に設定された文字列ではありません。

"public.image"そのため、キーで使用してローカライズできません。UI は何らかの理由で既にこれを にローカライズしてい"image"ます。行テンプレートをローカライズしたい場合は、"image"代わりに文字列を使用する必要があります。そして、この文字列がどのように、またはなぜ選択されているのかわかりません"image"

テストによってこれらの文字列を特定し、式をローカライズされた文字列にマップするテーブルを作成できます。しかし、テストしていない文字列について心配する必要がないように、この自動ローカリゼーションを無効にするソリューションが必要です。

UTI が自動的にローカライズされるのはなぜですか? 他の値は同じ扱いを受けますか?

UTI 文字列および/または述語エディター全体の自動ローカライズを無効にする方法はありますか?

4

3 に答える 3

1

You can call the private API methods directly to use the system's mapping.

In Swift this requires a bridging header:

#import <AppKit/AppKit.h>

@interface NSPredicateEditorRowTemplate ()

- (NSString *)_displayValueForKeyPath:(CFStringRef)keyPath;
- (NSString *)_displayValueForConstantValue:(CFStringRef)constantValue;
- (NSString *)_displayValueForCompoundPredicateType:(NSCompoundPredicateType)compoundPredicateType;
- (NSString *)_displayValueForPredicateOperator:(NSPredicateOperatorType)predicateOperator;

@end

These private methods can then be called like so:

let keyPath = rowTemplate._displayValue(forKeyPath: kMDItemFSSize) // "File size"
let constantValue = rowTemplate._displayValue(forConstantValue: "com.apple.application" as CFString) // "application"
let compoundPredicateType = rowTemplate._displayValue(for: .or) // "Any"

The three above work, but I'm currently having issues with _displayValueForPredicateOperator: crashing with EXC_BAD_ACCESS or returning the wrong string translation.

于 2019-06-10T07:56:14.443 に答える