ลบรายการพวงกุญแจเมื่อถอนการติดตั้งแอพ


238

ฉันใช้รหัส scifihifi-iphone ของ idandersenสำหรับพวงกุญแจและบันทึกรหัสผ่านโดยใช้

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

เมื่อฉันลบแอปพลิเคชันออกจากอุปกรณ์รหัสผ่านจะยังคงอยู่ในพวงกุญแจ

ฉันต้องการลบรหัสผ่านออกจากพวงกุญแจเมื่อผู้ใช้ลบแอปพลิเคชันจากอุปกรณ์ ฉันจะทำสิ่งนี้ได้อย่างไร


13
เนื่องจากรหัสของคุณไม่ทำงานเมื่อใบสมัครของคุณถูกลบคุณไม่มีทางทำเช่นนี้
Jonathan Grynspan

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

สำหรับผู้ใช้ที่กำลังมองหาคำตอบของ @ amro รุ่นSwift 3.0 :

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
ควรลบการซิงโครไนซ์สาย
Pochi

30

ไม่มีทริกเกอร์ให้ทำรหัสเมื่อลบแอพออกจากอุปกรณ์ การเข้าถึงพวงกุญแจขึ้นอยู่กับโปรไฟล์การจัดเตรียมที่ใช้เพื่อเซ็นชื่อแอปพลิเคชัน ดังนั้นแอปพลิเคชันอื่น ๆ จะไม่สามารถเข้าถึงข้อมูลนี้ในพวงกุญแจ

มันไม่ได้ช่วยให้คุณมุ่งหวังที่จะลบรหัสผ่านในพวงกุญแจเมื่อผู้ใช้ลบแอปพลิเคชันออกจากอุปกรณ์ แต่ควรให้ความสะดวกสบายกับคุณว่ารหัสผ่านนั้นไม่สามารถเข้าถึงได้


ดังนั้นหากเราเปลี่ยนโปรไฟล์การจัดสรรของแอปพลิเคชันของเราจะสามารถเข้าถึงค่าที่เก็บไว้ก่อนหน้านี้ในพวงกุญแจได้หรือไม่
Moaz Saeed

27

สำหรับผู้ที่มองหาคำตอบของ @ amro รุ่น Swift:

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

... และเพื่อล้างบันทึกจากพวงกุญแจ (แสดงความคิดเห็นข้างต้น)

        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 ล้อมรอบตัวคุณไว้
Christopher Stephan

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")ค่าเริ่มต้นที่เป็นเท็จหากคีย์ไม่มีอยู่ และไม่จำเป็นต้องซิงโครไนซ์ ()
CharlesA

3

นี่น่าจะเป็นพฤติกรรมเริ่มต้นใน iOS 10.3 ตามพฤติกรรมที่ผู้คนเคยเห็นในเบต้า # 2 ยังไม่พบเอกสารที่เป็นทางการเกี่ยวกับเรื่องนี้ดังนั้นโปรดแสดงความคิดเห็นหากคุณมี


7
จนกระทั่งเบต้า 5 ฉันเดาว่าการเปิดตัว iOS 10.3 สาธารณะจะไม่มีการเปลี่ยนแปลงนี้
Jakub Truhlář
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.