Pamiętaj o tym przypadku, gdy Twoja aplikacja działa w tle i nie możesz uzyskać dostępu do przechowywanych wartości w NSUserDefaults:
Było wiele wątków i błędów na ten temat, ale to się dzieje ponownie w iOS 9. Mam aplikację, która uruchamia się w tle w odpowiedzi na zadania NSURLSession i wypychania dostępnych treści. Powtarzalnie, jeśli ponownie uruchomię telefon i zaczekam na uruchomienie aplikacji w tle, po otwarciu aplikacji stwierdzam, że [[NSUserDefaults standardUserDefaults] DictionaryRepresentation] zawiera wszystkie wartości systemowe, np. AppleITunesStoreItemKinds itp., Ale nie zawiera dowolna z ustawionych przeze mnie wartości. Jeśli wymuszę zamknięcie i ponowne uruchomienie aplikacji, wrócą wszystkie moje wartości. Czy jest jakiś sposób, aby uniknąć buforowania „pustych” standardUserDefaults przed odblokowaniem telefonu lub przynajmniej określić, kiedy są pomieszane i naprawić je bez konieczności wymuszania zamykania aplikacji?
Problem polega na tym, że NSUserDefaults jest ostatecznie obsługiwany przez plik w kontenerze aplikacji, a kontener aplikacji podlega ochronie danych. Jeśli nie zrobisz nic specjalnego, w systemie iOS 7 i nowszych kontener używa NSFileProtectionCompleteUntilFirstUserAuthentication, wartości dziedziczonej przez magazyn zapasowy NSUserDefaults, więc nie możesz uzyskać do niego dostępu przed pierwszym odblokowaniem.
IMO najlepszym sposobem obejścia tego jest unikanie NSUserDefaults dla rzeczy, na których polegasz w ścieżkach kodu, które mogą być wykonywane w tle. Zamiast tego przechowuj te ustawienia w swoim własnym pliku preferencji, takim, którego ochroną danych możesz jawnie zarządzać (w tym przypadku oznacza to „ustaw na NSFileProtectionNone”).
W kontekście ochrony danych występują dwa problemy z NSUserDefaults:
Jest to w pełni abstrakcyjny interfejs API: obecność i lokalizacja jego magazynu zapasowego nie jest uważana za część tego interfejsu API, więc nie można jawnie zarządzać jego ochroną danych.
Uwaga W najnowszych wersjach OS X NSUserDefaults jest zarządzany przez demona, a ludzie, którzy próbują bezpośrednio manipulować jego magazynem zapasowym, napotykają problemy. Łatwo sobie wyobrazić, że coś takiego pojawi się w pewnym momencie na iOS.
Nawet jeśli zmiana ochrony danych byłaby możliwa, NSUserDefaults nie ma mechanizmu klasyfikowania danych na podstawie kontekstu, w którym ich używasz; jest to API typu „wszystko albo nic”. W Twoim przypadku nie chcesz usuwać ochrony ze wszystkich domyślnych ustawień użytkownika, tylko te, do których potrzebujesz dostępu w tle przed pierwszym odblokowaniem.
Wreszcie, jeśli którekolwiek z tych danych są naprawdę wrażliwe, należy umieścić je w pęku kluczy. Warto zauważyć, że pęku kluczy można ustawić ochronę danych na podstawie poszczególnych pozycji.