Ошибка при сохранении в связке ключей с iphone sdk

То, что может сделать JVM, определяется байт-кодом JVM (что Вы находите в .class файлах), а не исходный язык. Так изменение языка исходного кода высокого уровня не собирается оказывать существенное влияние на доступную функциональность.

, Что касается какой требуется, чтобы писать компилятор для JVM, все, что действительно необходимо сделать, генерируют корректный байт-код / .class файлы. Как Вы пишете/компилируете, что код с альтернативным видом компилятора зависит от рассматриваемого компилятора, но однажды выходы компилятора .class файлы, выполняя их не отличается, чем выполнение .class файлов, сгенерированных javac.

28
задан Matthias Bauch 7 April 2011 в 20:35
поделиться

3 ответа

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

[self.keychainItemWrapper setObject:@"MY_APP_CREDENTIALS" forKey:(id)kSecAttrService];
//@"MY_APP_CREDENTIALS" can be any string.

Я нашел эту запись в блоге очень полезной: «В терминах базы данных вы можете подумать, что они являются уникальным индексом для двух атрибутов kSecAttrAccount, kSecAttrService, требующих комбинации этих два атрибута, которые должны быть уникальными для каждой записи в цепочке для ключей. " (из http://useyourloaf.com/blog/2010/4/28/keychain-duplicate-item-when-adding-password.html ).

Кроме того, в примере проекта Apple, использующего этот код, они создают экземпляр KeychainItemWrapper в делегате приложения. Я не знаю, если это необходимо, но мне нравится как можно точнее следовать их примерам:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
//there will be some standard code here.
KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MY_APP_CREDENTIALS" accessGroup:nil];
self.keychainWrapper = wrapper;
[self.keychainWrapper setObject:@"MYOBJECT" forKey:(id)kSecAttrService];
[wrapper release];
}

Я думаю, что это ошибка в коде оболочки. Логика в основном говорит: «Эта запись уже существует? Нет, это не так. Хорошо, я добавлю ее. Ой, вы не можете добавить ее, потому что она уже есть».

Вам также может понадобиться установить kSecAttrAccount; Я никогда не пробовал без установки этого значения, поскольку он предназначен для сохранения имени пользователя, которое идет с паролем:

[self.wrapper setObject:txtUserName.text forKey:(id)kSecAttrAccount];   
61
ответ дан 28 November 2019 в 02:34
поделиться

Для меня решение состояло в том, что я создал KeychainItemWrapper «синглтон» и использовал его во всем приложении. (На самом деле, в моем случае, у меня был одноэлементный словарь, полный KeychainItemWrapper -s, потому что я использую больше, чем один.)

Это решило проблему, когда я добирался до пути к коду, который фактически сказал: « существует ли этот элемент в цепочке для ключей? Нет? Затем добавьте его. Ой! NSAssert() Я пытаюсь добавить уже существующий элемент (Ошибка -25299) "

Пока я не уверен, Я подозреваю, что проблема связана с синхронизацией цепочки для ключей. У меня были похожие проблемы с NSUserDefaults, когда я записывал в NSUD, затем, где-нибудь в коде, получал standardUserDefaults и читал из них, а обновление еще не произошло (потому что я не сделал [ud synchronize] ], пока.)

В коде моя рутина выглядит так:

+ (KeychainItemWrapper*) keyChainWrapperForKeyID: (NSString*) keyID
{
    static dispatch_once_t onceToken = 0;
    static NSMutableDictionary *rfcuKeyChains = nil;
    dispatch_once(&onceToken, ^{
        rfcuKeyChains = [NSMutableDictionary new];
    });

    KeychainItemWrapper *keychain = nil;
    @synchronized (rfcuKeyChains)
    {
        keychain = [rfcuKeyChains objectForKey: keyID];
        if (keychain == nil)
        {
            keychain = [[KeychainItemWrapper alloc] initWithIdentifier: keyID accessGroup: nil];
            [rfcuKeyChains setObject: keychain forKey: keyID];
        }
    }

    return keychain;
}

И я использую ее так:

KeychainItemWrapper *keychain = [RFCUtils keyChainWrapperForKeyID: keyID];
NSString *firstLaunch = [keychain objectForKey: (__bridge id)(kSecAttrAccount)];
if (firstLaunch == nil)
{
    [keychain setObject: MY_APP_KEY forKey: (__bridge id)(kSecAttrAccount)];
}

(и т. звонки в другие места.)

1
ответ дан 28 November 2019 в 02:34
поделиться

Я попробовал все решения, слушайте выше, но у меня ничего не получалось. Он работал только на реальном устройстве, но не на симуляторе.

Мое решение запустить его на симуляторе состояло в том, чтобы включить «Право доступа к цепочке ключей».

Доля брелок права

0
ответ дан 28 November 2019 в 02:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: