我想将 FTP 密码存储在钥匙串中,而不是 NSUserDefaults 中。所以我使用了一个名为 EMKeyChain 的包装器来存储问题。问题是加载首选项窗口时它不会加载密码:
注意:FTPPassword 是 PreferenceController.h 中 NSTextField 的 IBOutlet
-(void)windowDidLoad
{
//Check Login Keychain
[self loadlogin];
//Set FTP Password Delegate to PreferenceController
[FTPPassword setDelegate:self];
//Load Password
EMGenericKeychainItem *keychainItem = [EMGenericKeychainItem genericKeychainItemForService:@"MelScrobbleX" withUsername: @"ftp"];
if (keychainItem.password != nil) {
[FTPPassword setValue:keychainItem.password];
}
导致这个严重的错误:
2010-09-05 19:31:51.360 MelScrobbleX[83291:a0f] -[NSSecureTextField setValue:]: unrecognized selector sent to instance 0x10c4be0
2010-09-05 19:31:51.363 MelScrobbleX[83291:a0f] HIToolbox: ignoring exception '-[NSSecureTextField setValue:]: unrecognized selector sent to instance 0x10c4be0' that raised inside Carbon event dispatch
(
0 CoreFoundation 0x977d6bba __raiseError + 410
1 libobjc.A.dylib 0x9022f509 objc_exception_throw + 56
2 CoreFoundation 0x978238db -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x9777d7e6 ___forwarding___ + 950
4 CoreFoundation 0x9777d3b2 _CF_forwarding_prep_0 + 50
5 MelScrobbleX 0x000193f2 -[PreferenceController windowDidLoad] + 157
6 AppKit 0x96d7941f -[NSWindowController _windowDidLoad] + 525
7 AppKit 0x96d072b0 -[NSWindowController window] + 123
8 AppKit 0x96f6c0f8 -[NSWindowController showWindow:] + 36
9 AppKit 0x96d61f1e -[NSApplication sendAction:to:from:] + 112
10 AppKit 0x96d61dd1 -[NSMenuItem _corePerformAction] + 435
11 AppKit 0x96d61ac2 -[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] + 174
12 AppKit 0x96d619ae -[NSMenu performActionForItemAtIndex:] + 65
13 AppKit 0x96d61961 -[NSMenu _internalPerformActionForItemAtIndex:] + 50
14 AppKit 0x96d618c7 -[NSMenuItem _internalPerformActionThroughMenuIfPossible] + 97
15 AppKit 0x96d6180b -[NSCarbonMenuImpl _carbonCommandProcessEvent:handlerCallRef:] + 336
16 AppKit 0x96d55f49 NSSLMMenuEventHandler + 404
17 HIToolbox 0x9370df2f _ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec + 1567
18 HIToolbox 0x9370d1f6 _ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec + 411
19 HIToolbox 0x9372f9bb SendEventToEventTarget + 52
20 HIToolbox 0x9375bfa7 _ZL18SendHICommandEventmPK9HICommandmmhPKvP20OpaqueEventTargetRefS5_PP14OpaqueEventRef + 448
21 HIToolbox 0x93780d1c SendMenuCommandWithContextAndModifiers + 66
22 HIToolbox 0x93780cd1 SendMenuItemSelectedEvent + 121
23 HIToolbox 0x93780bda _ZL19FinishMenuSelectionP13SelectionDataP10MenuResultS2_ + 152
24 HIToolbox 0x93902342 _ZL19PopUpMenuSelectCoreP8MenuData5PointdS1_tjPK4RecttmS4_S4_PK10__CFStringPP13OpaqueMenuRefPt + 1851
25 HIToolbox 0x93902699 _HandlePopUpMenuSelection7 + 678
26 AppKit 0x96febe97 _NSSLMPopUpCarbonMenu3 + 3938
27 AppKit 0x97275bdb +[NSStatusBarButtonCell popupStatusBarMenu:inRect:ofView:withEvent:] + 962
28 AppKit 0x97275241 -[NSStatusBarButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 151
29 AppKit 0x96e3ae93 -[NSControl mouseDown:] + 812
30 AppKit 0x96e38e9c -[NSWindow sendEvent:] + 5549
31 AppKit 0x972761f8 -[NSStatusBarWindow sendEvent:] + 82
32 AppKit 0x96d51aff -[NSApplication sendEvent:] + 6431
33 AppKit 0x96ce55bb -[NSApplication run] + 917
34 AppKit 0x96cdd5ed NSApplicationMain + 574
35 MelScrobbleX 0x00002eda start + 54
)
每次密码更改时,程序都会创建一个新的钥匙串项,即使钥匙串项已经存在。(此选择器用于 FTPPassword)
- (void)controlTextDidEndEditing:(NSNotification *)aNotification {
EMGenericKeychainItem *keychainItem = [EMGenericKeychainItem genericKeychainItemForService:@"MelScrobbleX" withUsername: @"ftp"];
if (keychainItem.password == nil) {
//Create Keychain
NSLog(@"Creating Keychain");
[EMGenericKeychainItem addGenericKeychainItemForService:@"MelScrobbleX" withUsername:@"ftp" password:[FTPPassword stringValue]];
}
else if (keychainItem.password != [FTPPassword stringValue]){
//Save Password
NSLog(@"Saving Password");
keychainItem.password = [FTPPassword stringValue];
}
else if ([[FTPPassword stringValue] length] == 0){
//Blank Password. Remove Keychain Item
NSLog(@"Deleting Password");
[keychainItem removeFromKeychain];
}
}
注意:所需的框架已经链接(Security.framework 和 Carbon.framework),这个错误在 GC 开启和关闭时发生。另外,我使用的是 Mac OS X 10.5 SDK。