Browse Source

Set data with access options

Evgenii Neumerzhitckii 10 years ago
parent
commit
dbddf6f989
4 changed files with 50 additions and 6 deletions
  1. 2 0
      README.md
  2. 6 0
      keychain.xcodeproj/project.pbxproj
  3. 6 2
      keychain/TegKeychain.swift
  4. 36 4
      keychainTests/keychainTests.swift

+ 2 - 0
README.md

@@ -42,6 +42,8 @@ By default the `.AccessibleWhenUnlocked` option is used. It is recommended to us
 TegKeychain.set("Hello world", forKey: "key 1", withAccess: .AccessibleWhenUnlocked)
 ```
 
+You can use `.AccessibleAfterFirstUnlock` if you need your app to access the keychain item while in the background. It may be needed for the Apple Watch apps.
+
 See the list of all available [access options](https://github.com/exchangegroup/keychain-swift/blob/master/keychain/TegKeychainAccessOptions.swift).
 
 ## Demo app

+ 6 - 0
keychain.xcodeproj/project.pbxproj

@@ -17,6 +17,9 @@
 		2BCB00B21A8335740022C93A /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2BCB00B11A8335740022C93A /* Default-568h@2x.png */; };
 		2BCB00B51A8335AF0022C93A /* TegKeychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BCB00B41A8335AF0022C93A /* TegKeychain.swift */; };
 		7E49F5361B1BE41B00FBC3FF /* TegKeychainAccessOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E49F5351B1BE41B00FBC3FF /* TegKeychainAccessOptions.swift */; };
+		7E49F5371B1BEE0B00FBC3FF /* TegKeychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BCB00B41A8335AF0022C93A /* TegKeychain.swift */; };
+		7E49F5381B1BEE0D00FBC3FF /* TegKeychainAccessOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E49F5351B1BE41B00FBC3FF /* TegKeychainAccessOptions.swift */; };
+		7E49F5391B1BEE0F00FBC3FF /* TegKeychainConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B48E3391A92F47800456D2F /* TegKeychainConstants.swift */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -245,6 +248,9 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				7E49F5381B1BEE0D00FBC3FF /* TegKeychainAccessOptions.swift in Sources */,
+				7E49F5371B1BEE0B00FBC3FF /* TegKeychain.swift in Sources */,
+				7E49F5391B1BEE0F00FBC3FF /* TegKeychainConstants.swift in Sources */,
 				2BCB00A81A83354D0022C93A /* keychainTests.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;

+ 6 - 2
keychain/TegKeychain.swift

@@ -9,6 +9,8 @@ A collection of helper functions for saving text and data in the keychain.
 */
 public class TegKeychain {
   
+  static var lastQueryParameters: [String: NSObject]? // Used by unit tests
+  
   /**
   
   Stores the text value in the keychain item under the given key.
@@ -22,7 +24,7 @@ public class TegKeychain {
     withAccess access: TegKeychainAccessOptions? = nil) -> Bool {
     
     if let value = value.dataUsingEncoding(NSUTF8StringEncoding) {
-      return set(value, forKey: key)
+      return set(value, forKey: key, withAccess: access)
     }
     
     return false
@@ -50,7 +52,9 @@ public class TegKeychain {
       TegKeychainConstants.valueData   : value,
       TegKeychainConstants.accessible  : accessible
     ]
-    
+      
+    lastQueryParameters = query
+          
     SecItemDelete(query as CFDictionaryRef)
     
     let status: OSStatus = SecItemAdd(query as CFDictionaryRef, nil)

+ 36 - 4
keychainTests/keychainTests.swift

@@ -7,9 +7,10 @@ class keychainTests: XCTestCase {
     super.setUp()
     
     TegKeychain.clear()
+    TegKeychain.lastQueryParameters = nil
   }
 
-  // Set
+  // MARK: - Set text
   // -----------------------
 
   func testSet() {
@@ -17,18 +18,49 @@ class keychainTests: XCTestCase {
     XCTAssertEqual("hello :)", TegKeychain.get("key 1")!)
   }
   
+  func testSet_usesAccessibleWhenUnlockedByDefault() {
+    XCTAssertTrue(TegKeychain.set("hello :)", forKey: "key 1"))
+    
+    let accessValue = TegKeychain.lastQueryParameters?[TegKeychainConstants.accessible] as? String
+    XCTAssertEqual(TegKeychainAccessOptions.AccessibleWhenUnlocked.value, accessValue!)
+  }
+  
   func testSetWithAccessOption() {
     TegKeychain.set("hello :)", forKey: "key 1", withAccess: .AccessibleAfterFirstUnlock)
+    let accessValue = TegKeychain.lastQueryParameters?[TegKeychainConstants.accessible] as? String
+    XCTAssertEqual(TegKeychainAccessOptions.AccessibleAfterFirstUnlock.value, accessValue!)
+  }
+  
+  // MARK: - Set data
+  // -----------------------
+  
+  func testSetData() {
+    let data = "hello world".dataUsingEncoding(NSUTF8StringEncoding)!
+    
+    XCTAssertTrue(TegKeychain.set(data, forKey: "key 123"))
+    
+    let dataFromKeychain = TegKeychain.getData("key 123")!
+    let textFromKeychain = NSString(data: dataFromKeychain, encoding:NSUTF8StringEncoding) as! String
+    XCTAssertEqual("hello world", textFromKeychain)
+  }
+  
+  func testSetData_usesAccessibleWhenUnlockedByDefault() {
+    let data = "hello world".dataUsingEncoding(NSUTF8StringEncoding)!
+    
+    TegKeychain.set(data, forKey: "key 123")
+    
+    let accessValue = TegKeychain.lastQueryParameters?[TegKeychainConstants.accessible] as? String
+    XCTAssertEqual(TegKeychainAccessOptions.AccessibleWhenUnlocked.value, accessValue!)
   }
 
-  // Get
+  // MARK: - Get
   // -----------------------
 
   func testGet_returnNilWhenValueNotSet() {
     XCTAssert(TegKeychain.get("key 1") == nil)
   }
 
-  // Delete
+  // MARK: - Delete
   // -----------------------
 
   func testDelete() {
@@ -47,7 +79,7 @@ class keychainTests: XCTestCase {
     XCTAssertEqual("hello two", TegKeychain.get("key 2")!)
   }
 
-  // Clear
+  // MARK: - Clear
   // -----------------------
 
   func testClear() {