Видаліть елементи брелока, коли додаток видалено


238

Я використовую код scifihifi-iphone idandersen для брелока і зберігаю пароль за допомогою

[SFHFKeychainUtils storeUsername:@"User" andPassword:@"123"
              forServiceName:@"TestService" updateExisting:YES error:&error];

Коли я видаляю програму з пристрою, пароль залишається у брелок.

Я хочу видалити пароль з брелка, коли користувач видаляє програму з пристрою. Як я можу це зробити?


13
Оскільки ваш код не запускається під час видалення вашої програми, у вас немає способу зробити це.
Джонатан Грінспан

1
Я думаю, що ви можете видалити елемент брелока лише з додатка, але не перед його видаленням. Ви можете подивитися метод deleteItem SFHFKeychainUtils, щоб видалити ім’я користувача або пароль з брелка.
matteodv

Відповіді:


406

Ви можете скористатися тим , що NSUserDefaults мають очищені від деінсталяції програми. Наприклад:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //Clear keychain on first run in case of reinstallation
    if (![[NSUserDefaults standardUserDefaults] objectForKey:@"FirstRun"]) {
        // Delete values from keychain here
        [[NSUserDefaults standardUserDefaults] setValue:@"1strun" forKey:@"FirstRun"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }

    //...Other stuff that usually happens in didFinishLaunching
}

Це перевіряє та встановлює ключ / значення "FirstRun" NSUserDefaultsпід час першого запуску програми, якщо воно ще не встановлено. Там є коментар, куди слід поставити код, щоб видалити значення з брелка. Синхронізацію можна викликати, щоб переконатися, що ключ / значення "FirstRun" негайно зберігається у випадку, якщо користувач вбиває додаток вручну до того, як система збереже його.


2
Я погоджуюся з Amro, що ви можете видалити / очистити брелок після першого запуску програми. Це дозволить очистити все, що було встановлено до видалення додатка востаннє. Я зробив це для одного з моїх додатків, у яких зберігаються облікові дані Facebook / Twitter, і він працює досить добре, знаючи той факт, що лише ваш додаток має доступ до будь-якого ключового ланцюжка, який був встановлений.
XCool

Дякую за цю підказку.
iOSAppDev

3
NSUserDefaults не видаляються, коли користувач вручну закриває додаток. synchronizeУ цьому випадку втрачаються лише ті значення, які ви встановили, але або система (періодично), або ви ще не синхронізувались з диском (дзвонивши ). Добре зателефонувати синхронізувати після встановлення першого ключа запуску. І так, NSUserDefaults очищаються, коли пристрій скидається (а не відновлюється з резервної копії), і це добре в цьому випадку.
Amro

5
Ви помиляєтесь і, ймовірно, робите щось, що призводить до очищення стандартних налаштувань користувачів. Вся суть NSUserDefaults полягає в збереженні налаштувань, щоб ці налаштування зберігалися за допомогою декількох запусків програм. Знову ж таки, скидання пристрою або видалення програми призведе до видалення за замовчуванням користувачів. Подивіться, скільки людей підписали цю відповідь і перевірте ваш код. Потім переходите читати документацію. Чорт, надішліть мені відповідний код, і я покажу вам, що ви робите не так. Так було з iOS 2.0. Проголосуйте проти, але я б запропонував спочатку написати ізольований, простий тестовий випадок.
Amro

9
Я б не дуже впевнено використовував для цього NSUserDefault. Чому? Погляньте на цю тему: stackoverflow.com/questions/20269116/… . Якщо ви запускаєте додаток із фону, є випадки, коли ваші користувацькі ключі в NSUserDefaults просто не встановлені. Застосування цієї відповіді призведе до видалення користувацьких ключів Keychain, хоча ви цього справді не хотіли!
Aurelien Porte

40

Для користувачів, які шукають Swift 3.0 версії відповіді @ amro:

let userDefaults = UserDefaults.standard

if !userDefaults.bool(forKey: "hasRunBefore") {
     // Remove Keychain items here

     // Update the flag indicator
     userDefaults.set(true, forKey: "hasRunBefore")
}

* зауважте, що функція синхронізації () застаріла


2
if !userDefaults.bool(forKey: "hasRunBefore") {Це просто чистіше.
nefarianblack

1
Виклик синхронізації повинен бути видалений.
Почі

30

Немає тригера для виконання коду, коли додаток видалено з пристрою. Доступ до брелка залежить від профілю забезпечення, який використовується для підписання програми. Тому жодна інша програма не зможе отримати доступ до цієї інформації в брелок.

Це не допомагає, якщо ви прагнете видалити пароль у брелок, коли користувач видаляє програму з пристрою, але це повинно вам забезпечити доступність пароля (лише після повторної інсталяції оригінальної програми).


Отже, якщо ми змінимо профіль забезпечення нашого додатку, чи зможе він отримати доступ до раніше збережених значень у брелоку.
Моаз Саїд

27

Для тих, хто шукає швидкої версії відповіді @ amro:

    let userDefaults = NSUserDefaults.standardUserDefaults()

    if userDefaults.boolForKey("hasRunBefore") == false {

        // remove keychain items here


        // update the flag indicator
        userDefaults.setBool(true, forKey: "hasRunBefore")
        userDefaults.synchronize() // forces the app to update the NSUserDefaults

        return
    }

9

Версія C # Xamarin

    const string FIRST_RUN = "hasRunBefore";
    var userDefaults = NSUserDefaults.StandardUserDefaults;
    if (!userDefaults.BoolForKey(FIRST_RUN))
    {
        //TODO: remove keychain items
        userDefaults.SetBool(true, FIRST_RUN);
        userDefaults.Synchronize();
    }

... і очистити записи з брелка (коментар TODO вище)

        var securityRecords = new[] { SecKind.GenericPassword,
                                    SecKind.Certificate,
                                    SecKind.Identity,
                                    SecKind.InternetPassword,
                                    SecKind.Key
                                };
        foreach (var recordKind in securityRecords)
        {
            SecRecord query = new SecRecord(recordKind);
            SecKeyChain.Remove(query);
        }

1
Використовуючи if (VersionTracking.IsFirstLaunchEver) {// remove keychain items}з Xamarin.Essentials, вам не потрібен код для userDefaults. Xamarin.Essentials обгортає це для вас .
Крістофер Стефан

7

Файли будуть видалені з каталогу документів вашої програми, коли користувач видалить програму. Знаючи це, все, що вам потрібно зробити, це перевірити, чи існує файл як перше, що відбувається в application:didFinishLaunchingWithOptions:. Після цього беззастережно створіть файл (навіть якщо це лише фіктивний файл).

Якщо файл не існував під час перевірки, ви знаєте, що це перший запуск з моменту останньої установки. Якщо вам потрібно дізнатися пізніше в додатку, збережіть булевий результат для члена-делегата додатка.


7

Відповідь @ amro переведена на Swift 4.0:

if UserDefaults.standard.object(forKey: "FirstInstall") == nil {
    UserDefaults.standard.set(false, forKey: "FirstInstall")
    UserDefaults.standard.synchronize()
}

Або навіть if !UserDefaults.standard.bool(forKey: "FirstInstall")які за замовчуванням знаходяться на помилках, якщо ключ не існує. І. Синхронізувати () не потрібно.
ЧарльзА

3

Це, мабуть, поведінка за замовчуванням на iOS 10.3 на основі поведінки, в якій люди були свідками бета-версії №2. Ще не знайшли жодної офіційної документації з цього приводу, тому, будь ласка, прокоментуйте, якщо у вас є.


7
Думаю, що до бета-версії 5, я думаю, публічний реліз iOS 10.3 не змінює цієї зміни.
Jakub Truhlář
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.