@@ -10,34 +10,34 @@ import Foundation
10
10
11
11
public extension KeyClip {
12
12
public class Ring {
13
-
13
+
14
14
let accessGroup : String ?
15
15
let service : String
16
16
let accessible : String
17
-
17
+
18
18
// MARK: Initializer
19
-
19
+
20
20
init ( accessGroup: String ? , service: String , accessible: String ) {
21
21
self . accessGroup = accessGroup
22
22
self . service = service
23
23
self . accessible = accessible
24
24
}
25
-
25
+
26
26
// MARK: Public Methods
27
-
27
+
28
28
public func exists( key: String , failure: ( ( NSError ) -> Void ) ? = nil ) -> Bool {
29
29
var query : [ String : AnyObject ] = [
30
30
kSecAttrService as String : self . service,
31
31
kSecClass as String : kSecClassGenericPassword,
32
32
kSecAttrAccount as String : key,
33
33
kSecAttrGeneric as String : key ]
34
-
34
+
35
35
if let accessGroup = self . accessGroup {
36
36
query [ kSecAttrAccessGroup as String ] = accessGroup
37
37
}
38
-
38
+
39
39
let status = SecItemCopyMatching ( query, nil )
40
-
40
+
41
41
switch status {
42
42
case errSecSuccess:
43
43
return true
@@ -48,43 +48,43 @@ public extension KeyClip {
48
48
return false
49
49
}
50
50
}
51
-
51
+
52
52
public func save( key: String , data: NSData , failure: ( ( NSError ) -> Void ) ? = nil ) -> Bool {
53
53
var query : [ String : AnyObject ] = [
54
54
kSecAttrService as String : self . service,
55
55
kSecClass as String : kSecClassGenericPassword,
56
56
kSecAttrAccount as String : key,
57
57
kSecAttrGeneric as String : key ]
58
-
58
+
59
59
if let accessGroup = self . accessGroup {
60
60
query [ kSecAttrAccessGroup as String ] = accessGroup
61
61
}
62
-
62
+
63
63
var status : OSStatus
64
-
64
+
65
65
if self . exists ( key, failure: failure) {
66
66
status = SecItemUpdate ( query, [ kSecValueData as String : data] )
67
67
} else {
68
68
query [ kSecAttrAccessible as String ] = self . accessible
69
69
query [ kSecValueData as String ] = data
70
70
status = SecItemAdd ( query as CFDictionaryRef , nil )
71
71
}
72
-
72
+
73
73
if status == errSecSuccess {
74
74
return true
75
75
} else {
76
76
self . failure ( status: status, failure: failure)
77
77
}
78
78
return false
79
79
}
80
-
80
+
81
81
public func save( key: String , string: String , failure: ( ( NSError ) -> Void ) ? = nil ) -> Bool {
82
82
if let data = string. dataUsingEncoding ( NSUTF8StringEncoding, allowLossyConversion: false ) {
83
83
return self . save ( key, data: data, failure: failure)
84
84
}
85
85
return false
86
86
}
87
-
87
+
88
88
public func save( key: String , dictionary: NSDictionary , failure: ( ( NSError ) -> Void ) ? = nil ) -> Bool {
89
89
var error : NSError ?
90
90
do {
@@ -98,7 +98,7 @@ public extension KeyClip {
98
98
}
99
99
return false
100
100
}
101
-
101
+
102
102
public func load( key: String , failure: ( ( NSError ) -> Void ) ? = nil ) -> NSData ? {
103
103
var query : [ String : AnyObject ] = [
104
104
kSecAttrService as String : self . service,
@@ -107,14 +107,14 @@ public extension KeyClip {
107
107
kSecAttrGeneric as String : key,
108
108
kSecReturnData as String : kCFBooleanTrue,
109
109
kSecMatchLimit as String : kSecMatchLimitOne ]
110
-
110
+
111
111
if let accessGroup = self . accessGroup {
112
112
query [ kSecAttrAccessGroup as String ] = accessGroup
113
113
}
114
-
114
+
115
115
var result : AnyObject ?
116
116
let status = withUnsafeMutablePointer ( & result) { SecItemCopyMatching ( query, UnsafeMutablePointer ( $0) ) }
117
-
117
+
118
118
if status == errSecSuccess {
119
119
if let data = result as? NSData {
120
120
return data
@@ -124,7 +124,7 @@ public extension KeyClip {
124
124
}
125
125
return nil
126
126
}
127
-
127
+
128
128
public func load( key: String , failure: ( ( NSError ) -> Void ) ? = nil ) -> NSDictionary ? {
129
129
var error : NSError ?
130
130
if let data: NSData = self . load ( key, failure: failure) {
@@ -140,7 +140,7 @@ public extension KeyClip {
140
140
}
141
141
return nil
142
142
}
143
-
143
+
144
144
public func load( key: String , failure: ( ( NSError ) -> Void ) ? = nil ) -> String ? {
145
145
if let data: NSData = self . load ( key, failure: failure) {
146
146
if let string = NSString ( data: data, encoding: NSUTF8StringEncoding) {
@@ -149,74 +149,75 @@ public extension KeyClip {
149
149
}
150
150
return nil
151
151
}
152
-
152
+
153
153
public func load< T> ( key: String , success: ( NSDictionary ) -> T , failure: ( ( NSError ) -> Void ) ? ) -> T ? {
154
154
if let dictionary: NSDictionary = self . load ( key) {
155
155
return success ( dictionary)
156
156
}
157
157
return nil
158
158
}
159
-
159
+
160
160
public func load< T> ( key: String , success: ( NSDictionary ) -> T ) -> T ? {
161
161
return self . load ( key, success: success, failure: nil )
162
162
}
163
-
163
+
164
164
public func delete( key: String , failure: ( ( NSError ) -> Void ) ? = nil ) -> Bool {
165
165
var query : [ String : AnyObject ] = [
166
166
kSecAttrService as String : self . service,
167
167
kSecClass as String : kSecClassGenericPassword,
168
168
kSecAttrAccount as String : key,
169
169
kSecAttrGeneric as String : key ]
170
-
170
+
171
171
if let accessGroup = self . accessGroup {
172
172
query [ kSecAttrAccessGroup as String ] = accessGroup
173
173
}
174
-
174
+
175
175
let status = SecItemDelete ( query as CFDictionaryRef )
176
-
176
+
177
177
if status == errSecSuccess {
178
178
return true
179
179
} else if status != errSecItemNotFound {
180
180
self . failure ( status: status, failure: failure)
181
181
}
182
182
return false
183
183
}
184
-
184
+
185
185
public func clear( failure failure: ( ( NSError ) -> Void ) ? = nil ) -> Bool {
186
186
var query : [ String : AnyObject ] = [
187
187
kSecAttrService as String : self . service,
188
188
kSecClass as String : kSecClassGenericPassword ]
189
-
189
+
190
190
if let accessGroup = self . accessGroup {
191
191
query [ kSecAttrAccessGroup as String ] = accessGroup
192
192
}
193
-
193
+
194
194
let status = SecItemDelete ( query as CFDictionaryRef )
195
-
195
+
196
196
if status == errSecSuccess {
197
197
return true
198
198
} else if status != errSecItemNotFound {
199
199
self . failure ( status: status, failure: failure)
200
200
}
201
201
return false
202
202
}
203
-
203
+
204
204
// MARK: Private Methods
205
-
206
- private func failure( status status: OSStatus , function: String = __FUNCTION__ , line: Int = __LINE__ , failure: ( ( NSError ) -> Void ) ? ) {
205
+
206
+ private func failure( status status: OSStatus , function: String = #function , line: Int = #line , failure: ( ( NSError ) -> Void ) ? ) {
207
207
let userInfo = [ NSLocalizedDescriptionKey : statusMessage ( status) ]
208
208
self . failure ( error: NSError ( domain: " pw.aska.KeyClip " , code: Int ( status) , userInfo: userInfo) , function: function, line: line, failure: failure)
209
209
}
210
-
211
- private func failure( error error: NSError , function: String = __FUNCTION__ , line: Int = __LINE__ , failure: ( ( NSError ) -> Void ) ? ) {
210
+
211
+ private func failure( error error: NSError , function: String = #function , line: Int = #line , failure: ( ( NSError ) -> Void ) ? ) {
212
212
failure ? ( error)
213
-
213
+
214
214
if KeyClip . printError {
215
215
NSLog ( " [KeyClip] function: \( function) line: \( line) \( error. debugDescription) " )
216
216
}
217
217
}
218
-
218
+
219
219
// /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/Security.framework/Headers/SecBase.h
220
+ // swiftlint:disable:next cyclomatic_complexity
220
221
private func statusMessage( status: OSStatus ) -> String {
221
222
#if os(iOS)
222
223
switch status {
0 commit comments