2014-10-16 3 views
5

시작하려면 : 우리는 개발을 위해 현재 Swift/Xcode 6.1 GM 2를 사용하는 iOS 응용 프로그램을 개발 중입니다.키 체인 + adhoc 배포

임시로 응용 프로그램을 배포 할 때 키 체인 액세스에 약간의 혼란스러운 문제가 있으며 이유를 추적하는 데 문제가 있습니다. 모든 프로비저닝 프로파일은 앱의 번들 이름과 일치합니다. 우리는 그것이 문제라고 생각하지 않지만 배포를 위해 TestFlight를 사용합니다.

이전에 앱을 설치하지 않은 iOS 7 기기에서만 작동하도록했습니다. 단일 iOS 8 장치가 특별하게 작동하지 않았습니다. 우리가 처음에 얻은 오류는 25300 (errSecItemNotFound)이었고 이제는 프로비저닝 프로파일을 재설정 한 후 로딩시 절약하고 데이터를 검색 할 수있는 일반 0을 얻게되었습니다. Xcode에서 dev 빌드를 배포 할 때 모든 것이 완벽하게 작동합니다. 우리가 놓친 것 아무것도

import UIKit 
import Security 

let serviceIdentifier = "com.Test.KeychainTest" 

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) 
    var alertView = UIAlertView(); 
    alertView.addButtonWithTitle("Ok"); 
    alertView.title = "Status"; 
    alertView.message = "Saving \(status)"; 
    alertView.show(); 
} 

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) 
    var alertView = UIAlertView(); 
    alertView.addButtonWithTitle("Ok"); 
    alertView.title = "Status"; 
    alertView.message = "Loading \(status)"; 
    alertView.show(); 

    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 
} 


} 
  1. 있습니까 :

    나는 우리가 사용하는 키 체인 래퍼의 코드를 분리 한?

  2. 이 문제를 해결하는 가장 좋은 방법은 무엇입니까? 로그/iPhone 구성 유틸리티의 키 체인에서 오류가 발생하지 않습니다. 지금은 코드의 간단한 경고를 입력하여 작업 상태를 확인합니다.

답변

3

프로비저닝 프로파일 및 키 체인 코드의 모든 항목이 정상적으로 나타납니다. 문제는 "없음"에서 "가장 빠른"에서 "릴리스"에 대한 최적화 레벨을 변경 ... 스위프트 컴파일러의 설정이며이

enter image description here

+0

스위프트 최적화없이 얼마나 느린 감안할 때 문제를 해결하는 것 , 이것은 끔찍한 해결책입니다. 아마도 단일 파일에 대한 최적화를 해제하는 것이 더 좋을 것입니다. –

+0

@jshier 당신은 하나의 파일에 대해 어떻게하는지 설명 할 수 있습니까? – Turowicz

+0

"Build Phases"-> "Compile Sources"에서 "Compiler Flags"열을 두 번 클릭하고 -Onone 설정을 추가하십시오. 귀하의 의견에 대해 –

1

kSecAttrAccessible의 값도 지정해야합니다. 어쩌면 kSecAttrAccessControl의 값을 added in iOS8으로 지정할 수도 있습니다.