@@ -31,16 +31,43 @@ func getKeychainQueryTemplate(forService service: String) -> [String: String] {
3131struct KeychainStore : SecureStorage {
3232 let synchronizationQueue : DispatchQueue
3333 private let keychainQueryTemplate : [ String : String ]
34-
35- public static var shared = KeychainStore ( service: " shared " )
36-
37- init ( service: String ) {
38- synchronizationQueue = DispatchQueue ( label: " com.parse.keychain. \( service) " ,
34+ static var shared = KeychainStore ( )
35+ // This Keychain was used by SDK <= 1.9.7
36+ static var old = KeychainStore ( service: " shared " )
37+
38+ init ( service: String ? = nil ) {
39+ var keychainService = " .parseSwift.sdk "
40+ if let service = service {
41+ keychainService = service
42+ } else if let identifier = Bundle . main. bundleIdentifier {
43+ keychainService = " \( identifier) \( keychainService) "
44+ } else {
45+ keychainService = " com \( keychainService) "
46+ }
47+ synchronizationQueue = DispatchQueue ( label: " \( keychainService) .keychain " ,
3948 qos: . default,
4049 attributes: . concurrent,
4150 autoreleaseFrequency: . inherit,
4251 target: nil )
43- keychainQueryTemplate = getKeychainQueryTemplate ( forService: service)
52+ keychainQueryTemplate = getKeychainQueryTemplate ( forService: keychainService)
53+ }
54+
55+ func copy( keychain: KeychainStore ) {
56+ if let user = keychain. data ( forKey: ParseStorage . Keys. currentUser) {
57+ _ = try ? set ( user, forKey: ParseStorage . Keys. currentUser)
58+ }
59+ if let installation = keychain. data ( forKey: ParseStorage . Keys. currentInstallation) {
60+ _ = try ? set ( installation, forKey: ParseStorage . Keys. currentInstallation)
61+ }
62+ if let version = keychain. data ( forKey: ParseStorage . Keys. currentVersion) {
63+ _ = try ? set ( version, forKey: ParseStorage . Keys. currentVersion)
64+ }
65+ if let config = keychain. data ( forKey: ParseStorage . Keys. currentConfig) {
66+ _ = try ? set ( config, forKey: ParseStorage . Keys. currentConfig)
67+ }
68+ if let acl = keychain. data ( forKey: ParseStorage . Keys. defaultACL) {
69+ _ = try ? set ( acl, forKey: ParseStorage . Keys. defaultACL)
70+ }
4471 }
4572
4673 private func keychainQuery( forKey key: String ) -> [ String : Any ] {
@@ -69,20 +96,7 @@ struct KeychainStore: SecureStorage {
6996 }
7097 do {
7198 let data = try ParseCoding . jsonEncoder ( ) . encode ( object)
72- let query = keychainQuery ( forKey: key)
73- let update = [
74- kSecValueData as String : data
75- ]
76-
77- let status = synchronizationQueue. sync ( flags: . barrier) { ( ) -> OSStatus in
78- if self . data ( forKey: key) != nil {
79- return SecItemUpdate ( query as CFDictionary , update as CFDictionary )
80- }
81- let mergedQuery = query. merging ( update) { ( _, otherValue) -> Any in otherValue }
82- return SecItemAdd ( mergedQuery as CFDictionary , nil )
83- }
84-
85- return status == errSecSuccess
99+ return try set ( data, forKey: key)
86100 } catch {
87101 return false
88102 }
@@ -145,13 +159,31 @@ struct KeychainStore: SecureStorage {
145159 return data
146160 }
147161
162+ private func set( _ data: Data , forKey key: String ) throws -> Bool {
163+ let query = keychainQuery ( forKey: key)
164+ let update = [
165+ kSecValueData as String : data
166+ ]
167+
168+ let status = synchronizationQueue. sync ( flags: . barrier) { ( ) -> OSStatus in
169+ if self . data ( forKey: key) != nil {
170+ return SecItemUpdate ( query as CFDictionary , update as CFDictionary )
171+ }
172+ let mergedQuery = query. merging ( update) { ( _, otherValue) -> Any in otherValue }
173+ return SecItemAdd ( mergedQuery as CFDictionary , nil )
174+ }
175+
176+ return status == errSecSuccess
177+ }
178+
148179 private func removeObject( forKeyUnsafe key: String ) -> Bool {
149180 dispatchPrecondition ( condition: . onQueue( synchronizationQueue) )
150181 return SecItemDelete ( keychainQuery ( forKey: key) as CFDictionary ) == errSecSuccess
151182 }
152183}
153184
154- extension KeychainStore /* TypedSubscript */ {
185+ // MARK: TypedSubscript
186+ extension KeychainStore {
155187 subscript( string key: String ) -> String ? {
156188 get {
157189 return object ( forKey: key)
0 commit comments