MonoTouch не может получить значение существующего элемента цепочки для ключей

Кажется, я не могу получить значение из цепочки для ключей, поскольку она всегда возвращает ItemNotFound. Код, который я использую, выглядит следующим образом:

private static Guid GetID()
    {           
        Guid returnGuid = Guid.Empty;
        SecStatusCode code;
        SecRecord queryRec = new SecRecord (SecKind.GenericPassword) { Service = KEYCHAIN_SERVICE, Label = KEYCHAIN_SERVICE, Account = KEYCHAIN_ACCOUNT };
        queryRec = SecKeyChain.QueryAsRecord (queryRec, out code);

        if (code == SecStatusCode.Success && queryRec != null && queryRec.Generic != null )
        {
            returnGuid = new Guid(NSString.FromData(queryRec.Generic, NSStringEncoding.UTF8));
        }

        return returnGuid;

    }

Когда я пытаюсь установить значение, оно возвращает DuplicateItem со следующим кодом:

private static SecStatusCode SetID (Guid setID)
    {           
        SecStatusCode code = SecKeyChain.Add (new SecRecord (SecKind.GenericPassword) {
            Service = KEYCHAIN_SERVICE,
            Label = KEYCHAIN_SERVICE,
            Account = KEYCHAIN_ACCOUNT,
            Generic = NSData.FromString(Convert.ToString(setID), NSStringEncoding.UTF8),
            Accessible = SecAccessible.Always
        } );

        return code;
    }

Любая помощь будет здорово!


person davoc bradley    schedule 28.02.2012    source источник


Ответы (1)


Я скопировал ваш код в Touch.Unit решение, и оно работает как на симуляторе, так и на устройствах.

    [Test]
    public void CheckId ()
    {
        Guid g = Guid.NewGuid ();
        SetID (g);
        Assert.That (g, Is.EqualTo (GetID ()), "same guid");
    }

Единственное, что мне пришлось изменить, это ваши KEYCHAIN_* константы на строки, я оставил те же значения (т.е. просто добавил кавычки).

Теперь, если вы выполните код второй раз, вы получите код ошибки DuplicateItem, потому что SetID снова пытается установить тот же элемент, и когда вы запрашиваете Guid, вы получу первый - приведет к ошибке.

У вас есть два варианта: удалить существующий элемент или обновить его. Например. чтобы удалить существующий элемент...

    static SecStatusCode SetID (Guid setID)
    {
        SecRecord queryRec = new SecRecord (SecKind.GenericPassword) { 
            Service = "KEYCHAIN_SERVICE", 
            Label = "KEYCHAIN_SERVICE", 
            Account = "KEYCHAIN_ACCOUNT" 
        };
        var record = new SecRecord (SecKind.GenericPassword) {
            Service = "KEYCHAIN_SERVICE",
            Label = "KEYCHAIN_SERVICE",
            Account = "KEYCHAIN_ACCOUNT",
            Generic = NSData.FromString (Convert.ToString (setID), NSStringEncoding.UTF8),
            Accessible = SecAccessible.Always
        };
        SecStatusCode code = SecKeyChain.Add (record);
        if (code == SecStatusCode.DuplicateItem) {
            code = SecKeyChain.Remove (queryRec);
            if (code == SecStatusCode.Success)
                code = SecKeyChain.Add (record);
        }
        return code;
    }

Примечание. Я никогда не получал ItemNotFound при тестировании.

person poupou    schedule 28.02.2012
comment
Это действительно странно, я попытался удалить дублированный код ключа, и он возвращается с ItemNotFound, поэтому я не могу его удалить и не могу его прочитать. Я попробую изменить свои константы, чтобы он искал новую связку ключей, посмотрите, что исправляет. Обновлю, как только протестирую. - person davoc bradley; 28.02.2012
comment
Странно, у него должна быть деформированная цепочка для ключей или что-то вроде того, как если бы я изменил свои константы, теперь он работает нормально, это расстраивает. Я отметил вас правильно, спасибо за вашу помощь. - person davoc bradley; 28.02.2012