SecItemAdd zawsze zwraca błąd -34018 w Xcode 8 w symulatorze iOS 10

103

Aktualizacja : ten problem został rozwiązany w Xcode 8.2. Pęk kluczy działa w symulatorze bez włączania udostępniania pęku kluczy.

Dlaczego zawsze otrzymuję błąd -34018 podczas wywoływania SecItemAddfunkcji w symulatorze Xcode 8 / iOS 10 ?

Kroki ku reprodukcji

Utwórz nowy projekt aplikacji dla systemu iOS z pojedynczą stroną w Xcode 8. Uruchom następujący kod w viewDidLoad(lub otwórz ten projekt Xcode).

let itemKey = "My key"
let itemValue = "My secretive bee 🐝"

// Remove from Keychain
// ----------------

let queryDelete: [String: AnyObject] = [
  kSecClass as String: kSecClassGenericPassword,
  kSecAttrAccount as String: itemKey as AnyObject
]

let resultCodeDelete = SecItemDelete(queryDelete as CFDictionary)

if resultCodeDelete != noErr {
  print("Error deleting from Keychain: \(resultCodeDelete)")
}


// Add to keychain
// ----------------

guard let valueData = itemValue.data(using: String.Encoding.utf8) else {
  print("🐣🐣🐣🐣🐣🐣🐣🐣🐣🐣 Error saving text to Keychain")
  return
}

let queryAdd: [String: AnyObject] = [
  kSecClass as String: kSecClassGenericPassword,
  kSecAttrAccount as String: itemKey as AnyObject,
  kSecValueData as String: valueData as AnyObject,
  kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
]

let resultCode = SecItemAdd(queryAdd as CFDictionary, nil)

if resultCode != noErr {
  print("🐝🐝🐝🐝🐝🐝🐝🐝🐝 Error saving to Keychain: \(resultCode).")
} else {
  print("🍀🍀🍀🍀🍀🍀🍀🍀🍀 Saved to keychain successfully.")
}

oczekiwane rezultaty

Przedmiot został dodany do pęku kluczy.

Aktualne wyniki

Funkcja SecItemAdd zwraca następujący kod błędu: -34018.

Wersja

Xcode w wersji 8.1 (8B62), macOS Sierra 10.12.1.

Konfiguracja

Zawsze występuje w Xcode 8 od wersji Beta 2 podczas testowania w symulatorze iOS 10.

NIE występuje w Xcode 8 podczas testowania w symulatorze iOS 9.3.

Próbny

https://dl.dropboxusercontent.com/u/11143285/2016/07/KeychainBugDemo.zip

Bibliografia

Radar: https://openradar.appspot.com/27422249

Fora deweloperów Apple: https://forums.developer.apple.com/message/179846

Ten problem różni się od następującego postu, ponieważ występuje konsekwentnie w Xcode 8. SecItemAdd i SecItemCopyMatching zwraca kod błędu -34018 (errSecMissingEntitlement)

Evgenii
źródło
8
Wydaje się, że nadal jest to problem w Xcode 8 GM. Miło widzieć, że Apple wciąż jest na szczycie swojej gry ...
Nicholas Harlen
1
dla mnie to samo, nadal ten błąd
Kostiantyn Koval
Naprawdę kopie logi z konsoli :-)
Nicolas Miari,
Problem został rozwiązany w Xcode 8.2, ale powrócił w Xcode 9.0!
Adil Hussain

Odpowiedzi:

183

Udało mi się obejść ten problem w mojej aplikacji, dodając grupy dostępu do pęku kluczy do pliku uprawnień. Włączyłem przełącznik Udostępnianie pęku kluczy w sekcji Możliwości w aplikacji testowej i u mnie też działa.

Zrzut ekranu przedstawiający włączanie przełącznika

Pozycja do dodania do uprawnień:

<key>keychain-access-groups</key>
<array>
    <string>$(AppIdentifierPrefix)com.evgenii.KeychainBugDemo</string>
</array>

Próbowałem tego tylko na macOS Sierra (10.12), więc nie jestem pewien, czy zadziała to na 10.11.5.

Deyton
źródło
To samo tutaj, tyle że obecnie używam Xcode 8 beta 5 (z symulatorem iOS 10. Problem nie pojawił się w poprzedniej wersji beta. Nie występuje również podczas testowania z 8b5 na prawdziwym iPhonie z iOS 9). Zauważyłem, że powiadomienia push w możliwościach wymagały naprawy (tj. Naciśnięcia przycisku), a także włączyłem udostępnianie pęku kluczy, niestety w tym samym czasie. Wtedy aplikacja nie otrzymywała już błędu. Po ponownym wyłączeniu udostępniania pęku kluczy nadal działa!
Stefan
2
Używam pęku kluczy jako celu testowego i kończy się niepowodzeniem - jak mam to obejść? (Ponieważ nie ma możliwości w celach testowych)
Sam Jarman
1
@SamJarman Ja też miałem ten problem. Właśnie wszedłem do ustawień kompilacji dla celu testowego i cofnąłem pole uprawnień. Po tym działało dobrze.
Jordan Bondo,
3
To rozwiązanie działa dobrze w przypadku obiektów docelowych aplikacji. Niestety, pracuję nad frameworkiem Swift, który używa KeychainSwift, który już się nie kompiluje z powodu błędu. W celu frameworka nie mogę dodać pliku uprawnień afaik. Czy ktoś zna obejście tego przypadku?
Jan Nash
5
@JanNash, tutaj jest jak udało mi się uczynić pracę testowania evgenii.com/blog/testing-a-keychain-library-in-xcode
Evgenii
17

W informacjach o wydaniu Xcode 8.1 GM firma Apple przyznała się do problemu i zasugerowała bardziej przejrzyste obejście:

Interfejsy API pęku kluczy mogą nie działać w symulatorze, jeśli plik uprawnień nie zawiera wartości uprawnienia z identyfikatorem aplikacji. (28338972) Obejście problemu: Dodaj ustawienie kompilacji zdefiniowane przez użytkownika do celu o nazwie ENTITLEMENTS_REQUIRED i ustaw wartość na YES. Spowoduje to, że Xcode automatycznie wstawi uprawnienie do identyfikatora aplikacji podczas budowania.

Zauważ, że z tego, co próbowałem, działa tylko w Xcode 8.1. Chociaż tekst może wprowadzić Cię w błąd w ustawieniach kompilacji, musisz dodać to do zmiennych środowiskowych w swoim schemacie.

wprowadź opis obrazu tutaj

Xcode 8.2 rozwiąże ten problem:

Rozwiązane w Xcode 8.2 beta - interfejsy API pęku kluczy IDE działają poprawnie w symulatorze. (28338972)

Tiago Almeida
źródło
1
@Tiago Czy to obejście z informacji o wersji nadal działa w Xcode 8.1 na symulatorze iOS 10.1? Próbowałem dodać to ustawienie (zarówno jako ustawienie zdefiniowane przez użytkownika w miejscu docelowym, jak i jako zmienną środowiskową w schemacie) i nadal otrzymuję wartość zwracaną -34018 podczas pracy na symulatorach iOS 10.1.
guywithmazda
3
@guywithmazda, to samo tutaj. Nadal pobieram -34018 i próbowałem zarówno ustawień kompilacji, jak i zmiennych środowiskowych.
keithbhunter
Nie działa dla mnie, ani w ustawieniach kompilacji, ani jako zmienna środowiskowa schematu w Xcode 8.1 (8B62) na Sierra. Czy coś mi brakuje?
Evgenii,
4
Używam Xcode 8.2.1 i ten problem jest nadal odtwarzalny. Moje pytanie brzmi również, jeśli nie mam aplikacji hosta i tworzę docelowy Framework, to jak rozwiązać ten problem?
DShah,
2
Ten problem nadal wpływa na testy jednostkowe dla celów Framework, ponieważ w tym przypadku byłby to kod pośredniczący hosta testowego, który potrzebuje uprawnień. Zdajemy sobie sprawę z tego problemu, ale jeśli jest to dla Ciebie bloker, zgłoś zduplikowany błąd.
Russbishop
10

Może się tak zdarzyć, jeśli masz cel testowy, który nie ma aplikacji hosta. Naprawić

  1. dodaj fałszywą aplikację hosta: wprowadź opis obrazu tutaj

  2. Włącz automatyczne podpisywanie kodu i dodaj zespół:

wprowadź opis obrazu tutaj

  1. Włącz udostępnianie pęku kluczy w możliwościach

wprowadź opis obrazu tutaj

Mustafa
źródło
5

Wystąpił błąd podczas logowania za pomocą poczty e-mail, tworzenia nowego użytkownika lub wylogowywania się przy użyciu Firebase.

Błąd:

kod domeny błędu firauth 17995

Włączyłem przełącznik Udostępnianie pęku kluczy w sekcji Możliwości w aplikacji testowej i u mnie też działa.

kavita patel
źródło
4

Szukałem rozwiązania, które nie korzystało z udostępniania pęku kluczy, ponieważ nie była to funkcja, której szukałem. Wydaje się, że forum programistów ma dobre obejście z EvergreenCoder, które można ograniczyć tylko do symulatora iOS 10 (ponieważ wydaje się, że jest to jedyny symulator, którego dotyczy problem). Z postu:

Wydaje się, że problem polega na tym, że musi istnieć co najmniej jedno uprawnienie, aby Xcode mógł poprawnie dodać uprawnienie „identyfikator aplikacji” do zbudowanej aplikacji. Dlatego udostępnianie pęku kluczy wydaje się rozwiązaniem, ale jest tak tylko pośrednio: każde inne uprawnienie wydaje się działać dobrze.

Możesz stworzyć coś .plistpodobnego:

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE plist PUBLIC "-/  
<plist version="1.0">  
    <dict>  
        <key>get-task-allow</key>  
        <true/>  
    </dict>  
</plist>

i podaj ścieżkę do tego pliku w Ustawieniach kompilacji w

Code Signing->Debug->Simulater iOS 10 SDK->($SRCROOT)/your-path-to-file

Jak stwierdzono w poście, to uprawnienie pozwala tylko na dołączenie debugera.

ahtierney
źródło
1

Miałem podobny problem, chociaż otrzymywałem błąd -34018 podczas próby uruchomienia na urządzeniu. Używam XCode 8.1 na Sierra z iOS 10.1. Pracuję w zespole i nagle wystąpił ten problem, gdy w ustawieniach projektu przełączyliśmy się na opcję „Automatycznie zarządzaj podpisywaniem”. Kiedy to wyłączam i ręcznie wybieram mój profil, wszystko działa dobrze. Skończyło się na tym, że musiałem usunąć certyfikat programisty z pęku kluczy, a następnie ponownie wybrać opcję „Automatycznie zarządzaj podpisywaniem”. Przy następnej kompilacji wygenerował dla mnie nowy certyfikat podpisywania i teraz wszystko działa dobrze. Nadal nie jestem pewien, co spowodowało problem, ponieważ drugi certyfikat działał dobrze po ręcznym wybraniu, ale nie w przypadku zarządzania przez XCode. Mam nadzieję, że to pomoże komuś innemu powstrzymać wielogodzinny ból głowy.

johnrechd
źródło
1

Udało mi się rozwiązać ten problem w Xcode 11 bez żadnych korekt uprawnień.

Po prostu dodałem nowy cel aplikacji do projektu mojej platformy o nazwie MyFrameworkTestsHostApp.

Następnie wybrałem cel MyFrameworkTests i wybrałem jego aplikację hosta jako MyFrameworkTestsHostApp.

Adam Johns
źródło
0

Działa po włączeniu możliwości udostępniania pęku kluczy.

Vid
źródło
0

Istnieją 3 kroki, które należy wykonać, aby szybko rozwiązać ten problem.

  1. Włącz udostępnianie pęku kluczy w możliwościach projektu.
  2. Wybierz automatyczną obsługę administracyjną za pomocą profilu
  3. Upewnij się, że opcja niestandardowych uprawnień jest ustawiona na Entitlement.plist.

To zrobi magię

Uchenna Nnodim
źródło