Stworzyliśmy aplikację w Swift, która używa pęku kluczy. Aplikacja działa poprawnie, gdy działa na urządzeniu lub w symulatorze, ale nie może uzyskać dostępu do pęku kluczy po udostępnieniu za pośrednictwem aplikacji Testflight, chyba że zostanie udostępniona nowemu urządzeniu, które nigdy wcześniej nie miało zainstalowanej aplikacji za pośrednictwem Xcode 6.1.Błyskawiczne pęki kluczy i profile udostępniania
Poniżej znajduje się fragment kodu keychain:
import UIKit
import Security
let serviceIdentifier = "com.ourdomain"
let kSecClassValue = kSecClass as NSString
let kSecAttrAccountValue = kSecAttrAccount as NSString
let kSecValueDataValue = kSecValueData as NSString
let kSecClassGenericPasswordValue = kSecClassGenericPassword as NSString
let kSecAttrServiceValue = kSecAttrService as NSString
let kSecMatchLimitValue = kSecMatchLimit as NSString
let kSecReturnDataValue = kSecReturnData as NSString
let kSecMatchLimitOneValue = kSecMatchLimitOne as NSString
class KeychainManager {
class func setString(value: NSString, forKey: String) {
self.save(serviceIdentifier, key: forKey, data: value)
}
class func stringForKey(key: String) -> NSString? {
var token = self.load(serviceIdentifier, key: key)
return token
}
class func removeItemForKey(key: String) {
self.save(serviceIdentifier, key: key, data: "")
}
class func save(service: NSString, key: String, data: NSString) {
var dataFromString: NSData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
// Instantiate a new default keychain query
var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue, service, key, dataFromString], forKeys: [kSecClassValue, kSecAttrServiceValue, kSecAttrAccountValue, kSecValueDataValue])
// Delete any existing items
SecItemDelete(keychainQuery as CFDictionaryRef)
if data == "" { return }
// Add the new keychain item
var status: OSStatus = SecItemAdd(keychainQuery as CFDictionaryRef, nil)
}
class func load(service: NSString, key: String) -> NSString? {
// Instantiate a new default keychain query
// Tell the query to return a result
// Limit our results to one item
var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue, service, key, kCFBooleanTrue, kSecMatchLimitOneValue], forKeys: [kSecClassValue, kSecAttrServiceValue, kSecAttrAccountValue, kSecReturnDataValue, kSecMatchLimitValue])
var dataTypeRef :Unmanaged<AnyObject>?
// Search for the keychain items
let status: OSStatus = SecItemCopyMatching(keychainQuery, &dataTypeRef)
let opaque = dataTypeRef?.toOpaque()
var contentsOfKeychain: NSString?
if let op = opaque? {
let retrievedData = Unmanaged<NSData>.fromOpaque(op).takeUnretainedValue()
// Convert the data retrieved from the keychain into a string
contentsOfKeychain = NSString(data: retrievedData, encoding: NSUTF8StringEncoding)
} else {
return nil
}
return contentsOfKeychain
}
}
Po aplikacja została zainstalowana na urządzeniu poprzez Xcode 6.1 zauważyłem, że „serviceIdentifier” - „com.ourdomain” był Niepoprawny i nie pasuje do identyfikatora pakietu aplikacji zgodnie z wymaganiami dotyczącymi udostępniania.
Potem zmienił „serviceIdentifier” wartość pasujące do identyfikatora bundle - „com.ourdomain.appname” Jednak aplikacja po prostu nie będzie działać na urządzeniu, gdy zabezpieczony poprzez Testflight. Jestem pewien, że to dlatego, że urządzenie ma już pęku kluczy do identyfikatora pakunku zainstalowanego z niepoprawnym identyfikatorem, ale nie mam pojęcia, jak to obejść, aby usunąć pęk kluczy po usunięciu aplikacji lub użyć profilu udostępniania istniejący pęku kluczy (z niepoprawnym identyfikatorem)
Każda pomoc zostanie bardzo doceniona. Z góry dziękuję
To jest rzeczywiste rozwiązanie problemu! Przyjęta odpowiedź na wyłączenie optymalizacji kompilatora w wielu przypadkach nie do zaakceptowania. Co jest warte, widzę tylko oryginalny błąd na 64-bitowych urządzeniach. – alexkent
To zadziałało dla mnie po wielu godzinach uderzania głową o ścianę. Dzięki. – Nick
Nie działa, iPhone 6, 6+ i iPad Air 2 nadal wykazują problem podczas używania 'withUnsafeMutablePointer'. '-Onone' jest nadal jedyną realną opcją dla wszystkich urządzeń, dopóki Swift 1.2 nie będzie stabilny –