Xóa các mục móc khóa khi gỡ cài đặt ứng dụng


238

Tôi đang sử dụng mã scifihifi-iphone của idandersen cho móc khóa và lưu mật khẩu bằng cách sử dụng

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

Khi tôi xóa ứng dụng khỏi thiết bị, mật khẩu vẫn nằm trong móc khóa.

Tôi muốn xóa mật khẩu khỏi móc khóa khi người dùng xóa ứng dụng khỏi thiết bị. Tôi có thể làm cái này như thế nào?


13
Vì mã của bạn không chạy khi ứng dụng của bạn bị xóa, bạn không có cách nào để làm điều này.
Jonathan Grynspan

1
Tôi nghĩ rằng bạn chỉ có thể xóa một mục móc khóa từ bên trong ứng dụng, nhưng không phải trước khi gỡ cài đặt nó. Bạn có thể xem phương thức xóa của SFHFKeychainUtils để xóa tên người dùng hoặc mật khẩu khỏi móc khóa.
mờodv

Câu trả lời:


406

Bạn có thể tận dụng thực tế đã NSUserDefaults bị xóa bằng cách gỡ cài đặt ứng dụng. Ví dụ:

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

Việc này sẽ kiểm tra và đặt khóa / giá trị "FirstRun" trong NSUserDefaultslần chạy đầu tiên của ứng dụng nếu nó chưa được đặt. Có một bình luận nơi bạn nên đặt mã để xóa các giá trị khỏi móc khóa. Đồng bộ hóa có thể được gọi để đảm bảo khóa / giá trị "FirstRun" ngay lập tức được duy trì trong trường hợp người dùng giết ứng dụng theo cách thủ công trước khi hệ thống vẫn tồn tại.


2
Tôi đồng ý với Amro rằng bạn có thể xóa / lọc móc khóa của mình ngay lần chạy ứng dụng đầu tiên. Điều này sẽ xóa tất cả mọi thứ đã được đặt trước khi ứng dụng được gỡ cài đặt lần trước. Tôi đã làm điều này cho một trong những ứng dụng của mình lưu trữ thông tin đăng nhập Facebook / Twitter và nó hoạt động khá tốt khi biết rằng chỉ có ứng dụng của bạn có quyền truy cập vào bất kỳ móc khóa nào được đặt.
XCool

Cảm ơn gợi ý này.
iOSAppDev

3
NSUserDefaults không bị xóa khi người dùng thoát khỏi ứng dụng theo cách thủ công. Chỉ các giá trị bạn đã đặt nhưng hệ thống (định kỳ) hoặc bạn chưa được đồng bộ hóa với đĩa (bằng cách gọi synchronize) sẽ bị mất trong trường hợp đó. Nên gọi đồng bộ hóa sau khi cài đặt phím chạy đầu tiên. Và có, NSUserDefaults bị xóa khi thiết bị được đặt lại (và không được khôi phục từ bản sao lưu) và điều đó tốt trong trường hợp này.
Amro

5
Bạn đã sai và có lẽ bạn đang làm điều gì đó khiến mặc định của người dùng bị xóa. Toàn bộ quan điểm của NSUserDefaults là lưu các tùy chọn và duy trì các tùy chọn đó thông qua nhiều lần khởi chạy ứng dụng. Một lần nữa, đặt lại thiết bị hoặc xóa ứng dụng sẽ xóa mặc định của người dùng. Hãy xem có bao nhiêu người đã bỏ phiếu cho câu trả lời này và kiểm tra mã của bạn. Sau đó đi đọc tài liệu. Heck, gửi cho tôi mã liên quan và tôi sẽ cho bạn thấy những gì bạn đang làm sai. Đó là cách này kể từ iOS 2.0. Bỏ phiếu đi nhưng tôi khuyên bạn nên viết một trường hợp thử nghiệm đơn giản, đơn giản trước.
Amro

9
Tôi sẽ không tự tin lắm khi sử dụng NSUserDefault cho việc này. Tại sao? Hãy xem chủ đề đó: stackoverflow.com/questions/20269116/ trên . Nếu bạn khởi động ứng dụng của mình từ nền, có những trường hợp khóa tùy chỉnh của bạn trong NSUserDefaults không được đặt. Áp dụng câu trả lời này sẽ dẫn đến xóa các khóa tùy chỉnh Keychain của bạn mặc dù bạn thực sự không muốn điều đó!
Aurelien Porte

40

Đối với người dùng đang tìm kiếm phiên bản Swift 3.0 của câu trả lời của @ amro:

let userDefaults = UserDefaults.standard

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

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

* lưu ý rằng hàm syncize () không được dùng nữa


2
if !userDefaults.bool(forKey: "hasRunBefore") {Nó chỉ là sạch hơn.
nefarianblack

1
Cuộc gọi đồng bộ hóa nên được loại bỏ.
Pochi

30

Không có kích hoạt để thực hiện mã khi ứng dụng bị xóa khỏi thiết bị. Quyền truy cập vào móc khóa phụ thuộc vào hồ sơ cung cấp được sử dụng để ký ứng dụng. Do đó, không có ứng dụng nào khác có thể truy cập thông tin này trong móc khóa.

Nó không giúp bạn có mục đích xóa mật khẩu trong móc khóa khi người dùng xóa ứng dụng khỏi thiết bị nhưng nó sẽ mang lại cho bạn sự thoải mái khi mật khẩu không thể truy cập được (chỉ từ cài đặt lại ứng dụng gốc).


Vì vậy, nếu chúng tôi thay đổi hồ sơ cung cấp ứng dụng của mình, nó có thể truy cập các giá trị được lưu trữ trước đó trong móc khóa không.
Moaz Saeed

27

Đối với những người tìm kiếm phiên bản Swift của câu trả lời của @ 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

Phiên bản 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();
    }

... Và để xóa hồ sơ khỏi móc khóa (bình luận TODO ở trên)

        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
Bằng cách sử dụng if (VersionTracking.IsFirstLaunchEver) {// remove keychain items}từ Xamarin.Essentials, bạn không cần mã cho userDefaults. Xamarin.Essentials kết thúc tốt đẹp cho bạn .
Christopher Stephan

7

Các tệp sẽ bị xóa khỏi thư mục tài liệu của ứng dụng khi người dùng gỡ cài đặt ứng dụng. Biết điều này, tất cả những gì bạn phải làm là kiểm tra xem một tập tin có tồn tại như là điều đầu tiên xảy ra hay không application:didFinishLaunchingWithOptions:. Sau đó, tạo tập tin vô điều kiện (ngay cả khi đó chỉ là một tập tin giả).

Nếu tệp không tồn tại tại thời điểm kiểm tra, bạn biết đây là lần chạy đầu tiên kể từ lần cài đặt mới nhất. Nếu bạn cần biết sau này trong ứng dụng, hãy lưu kết quả boolean cho thành viên đại biểu ứng dụng của bạn.


7

Câu trả lời của @ amro được dịch sang Swift 4.0:

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

Hoặc thậm chí if !UserDefaults.standard.bool(forKey: "FirstInstall")mặc định là false nếu khóa không tồn tại. Và .synyncize () không cần thiết.
CharlesA

3

Đây dường như là hành vi mặc định trên iOS 10.3 dựa trên hành vi mà mọi người đã chứng kiến trong phiên bản beta # 2. Chưa tìm thấy tài liệu chính thức nào về việc này, vì vậy hãy bình luận nếu bạn có.


7
Cho đến phiên bản beta 5, tôi đoán, bản phát hành công khai iOS 10.3 không chứa thay đổi này.
Jakub Truhlář
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.