2010-09-05 8 views
0

Je veux stocker le mot de passe FTP dans un trousseau plutôt que dans le NSUserDefaults. J'ai donc utilisé un wrapper appelé EMKeyChain pour stocker le problème. Le problème étant que ce ne sera pas charger le mot de passe lorsque la fenêtre Préférences est chargé:Problèmes EMKeyChain

Note: FTPPassword est un IBOutlet pour NSTextField dans PreferenceController.h

-(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]; 
} 

résultant dans cette grande erreur méchant:

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 
) 

Le programme crée un nouvel élément de trousseau chaque fois que le mot de passe change même si l'élément de trousseau existe déjà. (Ce sélecteur est pour 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]; 
    } 
} 

Remarques: Les cadres nécessaires sont déjà liés (Security.framework et Carbon.framework) et cette erreur se produit avec GC et hors tension. En outre, j'utilise le SDK Mac OS X 10.5.

+0

Si vous stockez simplement un mot de passe FTP, plutôt que d'utiliser un wrapper tiers, je vous recommande d'essayer 'NSURLCredential' et les classes liées. –

Répondre

2

Votre erreur indique

-[NSSecureTextField setValue:]: unrecognized selector sent to instance 0x10c4be0 

Vous devriez consulter la référence, voir NSSecureTextField. En parcourant la hiérarchie des classes, vous découvrirez finalement qu'il n'existe pas de méthode telle que setValue:.

Je suppose que vous vouliez faire

[FTPPassword setStringValue:keychainItem.password]; 

au lieu de

[FTPPassword setValue:keychainItem.password]; 

j'aurais pensé que le compilateur aurait mis en garde contre l'utilisation setValue: parce qu'il n'y a pas de méthode dans NSControl, mais J'ai trouvé this informal protocol définissant setValue: comme une méthode de catégorie de NSObject. Hélas ...

+0

C'était une erreur stupide ... mais curieusement, le compilateur n'a pas montré une erreur quand j'ai utilisé la méthode setValue. – chikorita157

+0

J'ai expliqué dans la réponse pourquoi le compilateur ne s'est pas plaint: Apple a ajouté une méthode de catégorie à 'NSObject', sans l'implémenter, pour définir un protocole informel. Google "protocole informel" pour en savoir plus à ce sujet. – Yuji