我发现OS X会自动对某些 NSPredicateEditor
/ NSPredicateEditorRowTemplate
值进行本地化。
在运算符映射中很容易观察到:.equalTo
到字符串is
。
但我只是注意到UTI字符串被映射到该UTI的人类可读版本。
下面,我设置了"public.image"
但它显示为"image"
。
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以这种方式映射。我不知道运算符和UTI之外的其他格式是否都有自动本地化字符串。
这是一个问题,因为我想要localize my NSPredicateEditor and Row Templates。
本地化谓词的过程涉及将键与本地化值匹配。
KEY: "%[left]@ %[is]@ %[right]@"
VAL: "%1$[left_display_string]@ %2$[is]@ %3$[right_display_string]@"
问题是密钥中的值必须与UI 中显示的字符串匹配。不是最初设置为行模板的左右表达式的字符串。
因此,我无法使用密钥中的"public.image"
进行本地化。用户界面由于某种原因已经将其本地化为"image"
。如果我想本地化行模板,我必须使用字符串"image"
。我不知道这个"image"
字符串是如何或为何被选中的。
我可以通过测试确定这些字符串,然后编写一个将表达式映射到本地化字符串的表。但是我希望有一个解决方案来禁用这种自动本地化,这样我就不必担心我没有测试过的字符串。
为什么UTI会自动本地化?其他值是否接受相同的治疗?
有没有办法禁用UTI字符串和/或整个谓词编辑器的自动本地化?
答案 0 :(得分:1)
不是答案,而是一些信息:NSPredicateEditorRowTemplate
翻译_displayValueForConstantValue:
中的字符串。它使用字典:
{
"com.apple.application" = application;
"com.apple.pict" = PICT;
"com.apple.protected-mpeg-4-audio" = "purchased music";
"com.apple.rtfd" = RTFD;
"com.compuserve.gif" = GIF;
"com.microsoft.bmp" = BMP;
"public.audio" = music;
"public.folder" = folder;
"public.html" = HTML;
"public.image" = image;
"public.jpeg" = JPEG;
"public.jpeg-2000" = "JPEG 2000";
"public.mp3" = MP3;
"public.mpeg-4-audio" = "MPEG4 audio";
"public.png" = PNG;
"public.rtf" = RTF;
"public.source-code" = "source code";
"public.text" = text;
"public.tiff" = TIFF;
"public.xml" = XML;
}
BT:
AppKit`-[NSPredicateEditorRowTemplate _displayValueForConstantValue:] + 913
AppKit`-[NSPredicateEditorRowTemplate _viewFromExpressions:] + 589
AppKit`-[NSPredicateEditorRowTemplate initWithLeftExpressions:rightExpressions:modifier:operators:options:] + 205
编辑:
_displayValueForKeyPath:
使用此词典:
{
kMDItemContentCreationDate = Created;
kMDItemContentModificationDate = "Last modified";
kMDItemContentTypeTree = "File type";
kMDItemDisplayName = "File display name";
kMDItemFSContentChangeDate = "Change date";
kMDItemFSCreationDate = "Creation date";
kMDItemFSName = "File name";
kMDItemFSOwnerGroupID = "Owner group id";
kMDItemFSOwnerUserID = "Owner user ID";
kMDItemFSSize = "File size";
kMDItemLastUsedDate = "Last opened";
kMDItemPath = "File path";
}
_displayValueForPredicateOperator:
和_displayValueForCompoundPredicateType:
将枚举翻译为字符串。
这应该记录在案,但不是。我在_displayValueForConstantValue:
上放了一个断点,我看着发生了什么。字典是硬编码的,在其他版本的macOS中可能有所不同。
答案 1 :(得分:0)
扩展Willeke的好答案:
将符号断点添加到以下私有方法中以查看映射。
_displayValueForKeyPath:
_displayValueForConstantValue:
_displayValueForCompoundPredicateType:
_displayValueForPredicateOperator:
中断时,将断点放在包含objc_msgSend
的行上,然后在此处再次中断。
然后输入po $rax
以打印映射表。
在下面两种情况下,它不使用字典,但是在命中断点时可以看到字符串。
{
kMDItemContentCreationDate = Created;
kMDItemContentModificationDate = "Last modified";
kMDItemContentTypeTree = "File type";
kMDItemDisplayName = "File display name";
kMDItemFSContentChangeDate = "Change date";
kMDItemFSCreationDate = "Creation date";
kMDItemFSName = "File name";
kMDItemFSOwnerGroupID = "Owner group id";
kMDItemFSOwnerUserID = "Owner user ID";
kMDItemFSSize = "File size";
kMDItemLastUsedDate = "Last opened";
kMDItemPath = "File path";
}
{
"com.apple.application" = application;
"com.apple.pict" = PICT;
"com.apple.protected-mpeg-4-audio" = "purchased music";
"com.apple.rtfd" = RTFD;
"com.compuserve.gif" = GIF;
"com.microsoft.bmp" = BMP;
"public.audio" = music;
"public.folder" = folder;
"public.html" = HTML;
"public.image" = image;
"public.jpeg" = JPEG;
"public.jpeg-2000" = "JPEG 2000";
"public.mp3" = MP3;
"public.mpeg-4-audio" = "MPEG4 audio";
"public.png" = PNG;
"public.rtf" = RTF;
"public.source-code" = "source code";
"public.text" = text;
"public.tiff" = TIFF;
"public.xml" = XML;
}
0x7fff32a7342c <+20>: leaq 0x5ca25255(%rip), %rax ; @"Any"
0x7fff32a73434 <+28>: leaq 0x5c9c8dad(%rip), %rax ; @"None"
0x7fff32a7343c <+36>: leaq 0x5ca00ac5(%rip), %rax ; @"All"
0x7fff32a73456 <+62>: leaq 0x5ca2524b(%rip), %rdx ; @"(unknown compound type %ld)"
0x7fff32a7331b <+42>: leaq 0x5ca251c6(%rip), %rax ; @"is less than"
0x7fff32a73332 <+65>: leaq 0x5ca251cf(%rip), %rax ; @"is less than or equal to"
0x7fff32a7334a <+89>: leaq 0x5ca252f7(%rip), %rax ; @"between"
0x7fff32a73356 <+101>: leaq 0x5ca251cb(%rip), %rax ; @"is greater than"
0x7fff32a73362 <+113>: leaq 0x5ca251df(%rip), %rax ; @"is greater than or equal to"
0x7fff32a7336b <+122>: leaq 0x5ca251f6(%rip), %rax ; @"is"
0x7fff32a73374 <+131>: leaq 0x5ca2520d(%rip), %rax ; @"is not"
0x7fff32a7337d <+140>: leaq 0x5ca25224(%rip), %rax ; @"matches"
0x7fff32a73386 <+149>: leaq 0x5ca2523b(%rip), %rax ; @"is like"
0x7fff32a7338f <+158>: leaq 0x5ca25252(%rip), %rax ; @"begins with"
0x7fff32a73398 <+167>: leaq 0x5ca25269(%rip), %rax ; @"ends with"
0x7fff32a733a1 <+176>: leaq 0x5ca01300(%rip), %rax ; @"in"
0x7fff32a733aa <+185>: leaq 0x5ca25277(%rip), %rax ; @"contains"
0x7fff32a733d4 <+227>: leaq 0x5ca2528d(%rip), %rdx ; @"(unknown predicate operator %ld)"
答案 2 :(得分:0)
您可以直接调用私有API方法来使用系统的映射。
在Swift中,这需要一个桥接头:
#import <AppKit/AppKit.h>
@interface NSPredicateEditorRowTemplate ()
- (NSString *)_displayValueForKeyPath:(CFStringRef)keyPath;
- (NSString *)_displayValueForConstantValue:(CFStringRef)constantValue;
- (NSString *)_displayValueForCompoundPredicateType:(NSCompoundPredicateType)compoundPredicateType;
- (NSString *)_displayValueForPredicateOperator:(NSPredicateOperatorType)predicateOperator;
@end
然后可以像下面这样调用这些私有方法:
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"
以上三个方法均有效,但是我目前遇到_displayValueForPredicateOperator:
与EXC_BAD_ACCESS
崩溃或返回错误的字符串翻译的问题。