Search code examples
c#xamarin.iosxamarinmonodevelopkeychain

Error with testing xamarin app in iOS iPhone device


I've got this piece of code.

    SecRecord rec = new SecRecord (SecKind.GenericPassword);
    rec.Generic = NSData.FromString ("pass");
    SecStatusCode res;
    SecRecord match = SecKeyChain.QueryAsRecord (rec, out res);

    if (res == SecStatusCode.Success)
        txtLogin.Text = match.ValueData.ToString ();

    SecRecord login = new SecRecord (SecKind.GenericPassword) {
        Generic = NSData.FromString ("login") 
    };
    SecStatusCode reslogin;
    SecRecord matchlogin = SecKeyChain.QueryAsRecord (login, out reslogin);

    if (reslogin == SecStatusCode.Success)
        txtPassword.Text = matchlogin.ValueData.ToString ();

When I debug on the iPhone simulator all is working fine, but when I start debugging on an iPhone it gives me an error.

System.InvalidCastException: Cannot cast from source type to destination type.
at MonoTouch.Foundation.NSMutableDictionary.LowlevelFromObjectAndKey (IntPtr obj, IntPtr key) [0x00000] in /Developer/MonoTouch/Source/maccore/src/Foundation/.pmcs-compat.NSMutableDictionary.cs:408
at MonoTouch.Security.SecRecord..ctor (SecKind secKind) [0x0002d] in /Developer/MonoTouch/Source/maccore/src/Security/.pmcs-compat.Items.cs:619
at CompanyIOS.LoginController.ViewDidLoad () [0x00008] in /Users/nickolas/Projects/CompanyWorkSolution/CompanyIOS/LoginController.cs:38
at at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/.pmcs-compat.UIApplication.cs:38
at CompanyIOS.Application.Main (System.String[] args) [0x00008] in /Users/nickolas/Projects/CompanyWorkSolution/CompanyIOS/Main.cs:17

I can't understand what cast I'm missing. Please help me to figure out where the problem is.


Solution

  • The issue might have to do with using the "Generic" property. Here is a previous answer I had with accessing the keychain. Here is my sample code:

            SecRecord existingRec = new SecRecord (SecKind.GenericPassword) { 
                Service = Keychain.USER_SERVICE, 
                Label = Keychain.USER_LABEL 
            };
    
            var record = new SecRecord (SecKind.GenericPassword) {
                Service = Keychain.USER_SERVICE, 
                Label = Keychain.USER_LABEL, 
                Account = username,
                ValueData = NSData.FromString (password),
                Accessible = SecAccessible.Always
            };
    
            SecStatusCode code = SecKeyChain.Add (record);
            if (code == SecStatusCode.DuplicateItem) {
                code = SecKeyChain.Remove (existingRec);
                if (code == SecStatusCode.Success)
                    code = SecKeyChain.Add (record);
            }
    

    Can you also show which line is line 38 in LoginController since that is where it is throwing the exception?