浏览代码

Merge branch 'tcirwin-master'

Evgenii Neumerzhitckii 9 年之前
父节点
当前提交
3ffe876015

+ 6 - 6
Demo/AppDelegate.swift

@@ -7,30 +7,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
   var window: UIWindow?
 
 
-  func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
+  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
     // Override point for customization after application launch.
     return true
   }
 
-  func applicationWillResignActive(application: UIApplication) {
+  func applicationWillResignActive(_ application: UIApplication) {
     // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
   }
 
-  func applicationDidEnterBackground(application: UIApplication) {
+  func applicationDidEnterBackground(_ application: UIApplication) {
     // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
     // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
   }
 
-  func applicationWillEnterForeground(application: UIApplication) {
+  func applicationWillEnterForeground(_ application: UIApplication) {
     // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
   }
 
-  func applicationDidBecomeActive(application: UIApplication) {
+  func applicationDidBecomeActive(_ application: UIApplication) {
     // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
   }
 
-  func applicationWillTerminate(application: UIApplication) {
+  func applicationWillTerminate(_ application: UIApplication) {
     // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
   }
 

+ 7 - 7
Demo/ViewController.swift

@@ -19,32 +19,32 @@ class ViewController: UIViewController {
     updateValueLabel()
   }
   
-  @IBAction func onSaveTapped(sender: AnyObject) {
+  @IBAction func onSaveTapped(_ sender: AnyObject) {
     closeKeyboard()
     
     if let text = textField.text {
-      keychain.synchronizable = synchronizableSwitch.on
+      keychain.synchronizable = synchronizableSwitch.isOn
       keychain.set(text, forKey: TegKeychainDemo_keyName)
       updateValueLabel()
     }
   }
   
-  @IBAction func onDeleteTapped(sender: AnyObject) {
+  @IBAction func onDeleteTapped(_ sender: AnyObject) {
     closeKeyboard()
 
-    keychain.synchronizable = synchronizableSwitch.on
+    keychain.synchronizable = synchronizableSwitch.isOn
     keychain.delete(TegKeychainDemo_keyName)
     updateValueLabel()
   }
   
-  @IBAction func onGetTapped(sender: AnyObject) {
+  @IBAction func onGetTapped(_ sender: AnyObject) {
     closeKeyboard()
 
     updateValueLabel()
   }
   
   private func updateValueLabel() {
-    keychain.synchronizable = synchronizableSwitch.on
+    keychain.synchronizable = synchronizableSwitch.isOn
     
     if let value = keychain.get(TegKeychainDemo_keyName) {
       valueLabel.text = "In Keychain: \(value)"
@@ -57,7 +57,7 @@ class ViewController: UIViewController {
     textField.resignFirstResponder()
   }
   
-  @IBAction func didTapView(sender: AnyObject) {
+  @IBAction func didTapView(_ sender: AnyObject) {
     closeKeyboard()
   }
 }

+ 45 - 39
Distrib/KeychainSwiftDistrib.swift

@@ -69,10 +69,11 @@ public class KeychainSwift {
    - returns: True if the text was successfully written to the keychain.
 
   */
-  public func set(value: String, forKey key: String,
+  @discardableResult
+  public func set(_ value: String, forKey key: String,
                   withAccess access: KeychainSwiftAccessOptions? = nil) -> Bool {
     
-    if let value = value.dataUsingEncoding(NSUTF8StringEncoding) {
+    if let value = value.data(using: String.Encoding.utf8) {
       return set(value, forKey: key, withAccess: access)
     }
     
@@ -90,7 +91,8 @@ public class KeychainSwift {
   - returns: True if the text was successfully written to the keychain.
   
   */
-  public func set(value: NSData, forKey key: String,
+  @discardableResult
+  public func set(_ value: Data, forKey key: String,
     withAccess access: KeychainSwiftAccessOptions? = nil) -> Bool {
     
     delete(key) // Delete any existing key before saving it
@@ -99,7 +101,7 @@ public class KeychainSwift {
       
     let prefixedKey = keyWithPrefix(key)
       
-    var query = [
+    var query: [String : NSObject] = [
       KeychainSwiftConstants.klass       : kSecClassGenericPassword,
       KeychainSwiftConstants.attrAccount : prefixedKey,
       KeychainSwiftConstants.valueData   : value,
@@ -110,7 +112,7 @@ public class KeychainSwift {
     query = addSynchronizableIfRequired(query, addingItems: true)
     lastQueryParameters = query
     
-    lastResultCode = SecItemAdd(query as CFDictionaryRef, nil)
+    lastResultCode = SecItemAdd(query as CFDictionary, nil)
     
     return lastResultCode == noErr
   }
@@ -126,11 +128,13 @@ public class KeychainSwift {
   - returns: True if the value was successfully written to the keychain.
 
   */
-  public func set(value: Bool, forKey key: String,
+  @discardableResult
+  public func set(_ value: Bool, forKey key: String,
     withAccess access: KeychainSwiftAccessOptions? = nil) -> Bool {
+  
+    let bytes: [UInt8] = value ? [1] : [0]
+    let data = Data(bytes: bytes)
 
-    var localValue = value
-    let data = NSData(bytes: &localValue, length: sizeof(Bool))
     return set(data, forKey: key, withAccess: access)
   }
 
@@ -142,9 +146,10 @@ public class KeychainSwift {
   - returns: The text value from the keychain. Returns nil if unable to read the item.
   
   */
-  public func get(key: String) -> String? {
+  public func get(_ key: String) -> String? {
     if let data = getData(key) {
-      if let currentString = NSString(data: data, encoding: NSUTF8StringEncoding) as? String {
+      
+      if let currentString = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as? String {
         return currentString
       }
       
@@ -162,7 +167,7 @@ public class KeychainSwift {
   - returns: The text value from the keychain. Returns nil if unable to read the item.
   
   */
-  public func getData(key: String) -> NSData? {
+  public func getData(_ key: String) -> Data? {
     let prefixedKey = keyWithPrefix(key)
     
     var query: [String: NSObject] = [
@@ -182,7 +187,7 @@ public class KeychainSwift {
       SecItemCopyMatching(query, UnsafeMutablePointer($0))
     }
     
-    if lastResultCode == noErr { return result as? NSData }
+    if lastResultCode == noErr { return result as? Data }
     
     return nil
   }
@@ -195,11 +200,10 @@ public class KeychainSwift {
   - returns: The boolean value from the keychain. Returns nil if unable to read the item.
 
   */
-  public func getBool(key: String) -> Bool? {
+  public func getBool(_ key: String) -> Bool? {
     guard let data = getData(key) else { return nil }
-    var boolValue = false
-    data.getBytes(&boolValue, length: sizeof(Bool))
-    return boolValue
+    guard let firstBit = data.first else { return nil }
+    return firstBit == 1
   }
 
   /**
@@ -210,7 +214,8 @@ public class KeychainSwift {
   - returns: True if the item was successfully deleted.
   
   */
-  public func delete(key: String) -> Bool {
+  @discardableResult
+  public func delete(_ key: String) -> Bool {
     let prefixedKey = keyWithPrefix(key)
 
     var query: [String: NSObject] = [
@@ -222,7 +227,7 @@ public class KeychainSwift {
     query = addSynchronizableIfRequired(query, addingItems: false)
     lastQueryParameters = query
     
-    lastResultCode = SecItemDelete(query as CFDictionaryRef)
+    lastResultCode = SecItemDelete(query as CFDictionary)
     
     return lastResultCode == noErr
   }
@@ -234,23 +239,24 @@ public class KeychainSwift {
   - returns: True if the keychain items were successfully deleted.
   
   */
+  @discardableResult
   public func clear() -> Bool {
     var query: [String: NSObject] = [ kSecClass as String : kSecClassGenericPassword ]
     query = addAccessGroupWhenPresent(query)
     query = addSynchronizableIfRequired(query, addingItems: false)
     lastQueryParameters = query
     
-    lastResultCode = SecItemDelete(query as CFDictionaryRef)
+    lastResultCode = SecItemDelete(query as CFDictionary)
     
     return lastResultCode == noErr
   }
   
   /// Returns the key with currently set prefix.
-  func keyWithPrefix(key: String) -> String {
+  func keyWithPrefix(_ key: String) -> String {
     return "\(keyPrefix)\(key)"
   }
   
-  func addAccessGroupWhenPresent(items: [String: NSObject]) -> [String: NSObject] {
+  func addAccessGroupWhenPresent(_ items: [String: NSObject]) -> [String: NSObject] {
     guard let accessGroup = accessGroup else { return items }
     
     var result: [String: NSObject] = items
@@ -268,7 +274,7 @@ public class KeychainSwift {
    - returns: the dictionary with kSecAttrSynchronizable item added if it was requested. Otherwise, it returns the original dictionary.
  
   */
-  func addSynchronizableIfRequired(items: [String: NSObject], addingItems: Bool) -> [String: NSObject] {
+  func addSynchronizableIfRequired(_ items: [String: NSObject], addingItems: Bool) -> [String: NSObject] {
     if !synchronizable { return items }
     var result: [String: NSObject] = items
     result[KeychainSwiftConstants.attrSynchronizable] = addingItems == true ? true : kSecAttrSynchronizableAny
@@ -301,7 +307,7 @@ public enum KeychainSwiftAccessOptions {
   This is the default value for keychain items added without explicitly setting an accessibility constant.
   
   */
-  case AccessibleWhenUnlocked
+  case accessibleWhenUnlocked
   
   /**
   
@@ -310,7 +316,7 @@ public enum KeychainSwiftAccessOptions {
   This is recommended for items that need to be accessible only while the application is in the foreground. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
   
   */
-  case AccessibleWhenUnlockedThisDeviceOnly
+  case accessibleWhenUnlockedThisDeviceOnly
   
   /**
   
@@ -319,7 +325,7 @@ public enum KeychainSwiftAccessOptions {
   After the first unlock, the data remains accessible until the next restart. This is recommended for items that need to be accessed by background applications. Items with this attribute migrate to a new device when using encrypted backups.
   
   */
-  case AccessibleAfterFirstUnlock
+  case accessibleAfterFirstUnlock
   
   /**
   
@@ -328,7 +334,7 @@ public enum KeychainSwiftAccessOptions {
   After the first unlock, the data remains accessible until the next restart. This is recommended for items that need to be accessed by background applications. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
   
   */
-  case AccessibleAfterFirstUnlockThisDeviceOnly
+  case accessibleAfterFirstUnlockThisDeviceOnly
   
   /**
   
@@ -337,7 +343,7 @@ public enum KeychainSwiftAccessOptions {
   This is not recommended for application use. Items with this attribute migrate to a new device when using encrypted backups.
   
   */
-  case AccessibleAlways
+  case accessibleAlways
   
   /**
   
@@ -346,7 +352,7 @@ public enum KeychainSwiftAccessOptions {
   This is recommended for items that only need to be accessible while the application is in the foreground. Items with this attribute never migrate to a new device. After a backup is restored to a new device, these items are missing. No items can be stored in this class on devices without a passcode. Disabling the device passcode causes all items in this class to be deleted.
   
   */
-  case AccessibleWhenPasscodeSetThisDeviceOnly
+  case accessibleWhenPasscodeSetThisDeviceOnly
   
   /**
   
@@ -355,38 +361,38 @@ public enum KeychainSwiftAccessOptions {
   This is not recommended for application use. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
   
   */
-  case AccessibleAlwaysThisDeviceOnly
+  case accessibleAlwaysThisDeviceOnly
   
   static var defaultOption: KeychainSwiftAccessOptions {
-    return .AccessibleWhenUnlocked
+    return .accessibleWhenUnlocked
   }
   
   var value: String {
     switch self {
-    case .AccessibleWhenUnlocked:
+    case .accessibleWhenUnlocked:
       return toString(kSecAttrAccessibleWhenUnlocked)
       
-    case .AccessibleWhenUnlockedThisDeviceOnly:
+    case .accessibleWhenUnlockedThisDeviceOnly:
       return toString(kSecAttrAccessibleWhenUnlockedThisDeviceOnly)
       
-    case .AccessibleAfterFirstUnlock:
+    case .accessibleAfterFirstUnlock:
       return toString(kSecAttrAccessibleAfterFirstUnlock)
       
-    case .AccessibleAfterFirstUnlockThisDeviceOnly:
+    case .accessibleAfterFirstUnlockThisDeviceOnly:
       return toString(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly)
       
-    case .AccessibleAlways:
+    case .accessibleAlways:
       return toString(kSecAttrAccessibleAlways)
       
-    case .AccessibleWhenPasscodeSetThisDeviceOnly:
+    case .accessibleWhenPasscodeSetThisDeviceOnly:
       return toString(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly)
       
-    case .AccessibleAlwaysThisDeviceOnly:
+    case .accessibleAlwaysThisDeviceOnly:
       return toString(kSecAttrAccessibleAlwaysThisDeviceOnly)
     }
   }
   
-  func toString(value: CFStringRef) -> String {
+  func toString(_ value: CFString) -> String {
     return KeychainSwiftConstants.toString(value)
   }
 }
@@ -431,7 +437,7 @@ public struct KeychainSwiftConstants {
   /// Used for specifying a value when setting a Keychain value.
   public static var valueData: String { return toString(kSecValueData) }
   
-  static func toString(value: CFStringRef) -> String {
+  static func toString(_ value: CFString) -> String {
     return value as String
   }
 }

+ 2 - 2
KeychainSwift.podspec

@@ -1,13 +1,13 @@
 Pod::Spec.new do |s|
   s.name        = "KeychainSwift"
-  s.version     = "3.0.16"
+  s.version     = "4.0.0"
   s.license     = { :type => "MIT" }
   s.homepage    = "https://github.com/marketplacer/keychain-swift"
   s.summary     = "A library for saving text and data in the Keychain with Swift."
   s.description = <<-DESC
                 This is a collection of helper functions for saving text and data in the Keychain.
 
-                * Write and read text and NSData with simple functions.
+                * Write and read text and Data with simple functions.
                 * Specify optional access rule for the keychain item.
                 * Limit operations to a specific access group.
                 DESC

+ 26 - 8
KeychainSwift.xcodeproj/project.pbxproj

@@ -311,9 +311,9 @@
 /* End PBXLegacyTarget section */
 
 /* Begin PBXNativeTarget section */
-		232B4C791BC29950001F2B7A /* KeychainSwift-OSX */ = {
+		232B4C791BC29950001F2B7A /* KeychainSwift-macOS */ = {
 			isa = PBXNativeTarget;
-			buildConfigurationList = 232B4C7F1BC29950001F2B7A /* Build configuration list for PBXNativeTarget "KeychainSwift-OSX" */;
+			buildConfigurationList = 232B4C7F1BC29950001F2B7A /* Build configuration list for PBXNativeTarget "KeychainSwift-macOS" */;
 			buildPhases = (
 				232B4C751BC29950001F2B7A /* Sources */,
 				232B4C761BC29950001F2B7A /* Frameworks */,
@@ -324,7 +324,7 @@
 			);
 			dependencies = (
 			);
-			name = "KeychainSwift-OSX";
+			name = "KeychainSwift-macOS";
 			productName = "KeychainSwift-OSX";
 			productReference = 232B4C7A1BC29950001F2B7A /* KeychainSwift.framework */;
 			productType = "com.apple.product-type.framework";
@@ -427,7 +427,7 @@
 			isa = PBXProject;
 			attributes = {
 				LastSwiftUpdateCheck = 0700;
-				LastUpgradeCheck = 0700;
+				LastUpgradeCheck = 0800;
 				ORGANIZATIONNAME = Marketplacer;
 				TargetAttributes = {
 					232B4C791BC29950001F2B7A = {
@@ -444,12 +444,14 @@
 					};
 					7ED6C96B1B1C118F00FE8090 = {
 						CreatedOnToolsVersion = 6.4;
+						LastSwiftMigration = 0800;
 					};
 					7ED6C9761B1C118F00FE8090 = {
 						CreatedOnToolsVersion = 6.4;
 					};
 					7ED6C99C1B1C133500FE8090 = {
 						CreatedOnToolsVersion = 6.4;
+						LastSwiftMigration = 0800;
 					};
 				};
 			};
@@ -467,7 +469,7 @@
 			projectRoot = "";
 			targets = (
 				7ED6C96B1B1C118F00FE8090 /* KeychainSwift */,
-				232B4C791BC29950001F2B7A /* KeychainSwift-OSX */,
+				232B4C791BC29950001F2B7A /* KeychainSwift-macOS */,
 				232B4C891BC29984001F2B7A /* KeychainSwift-watchOS */,
 				23E7855F1BDA410C00B7564A /* KeychainSwift-tvOS */,
 				7ED6C9761B1C118F00FE8090 /* KeychainSwiftTests */,
@@ -639,10 +641,11 @@
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
 				MACOSX_DEPLOYMENT_TARGET = 10.10;
-				PRODUCT_BUNDLE_IDENTIFIER = "com.marketplacer.KeychainSwift-OSX";
+				PRODUCT_BUNDLE_IDENTIFIER = "com.marketplacer.KeychainSwift-macOS";
 				PRODUCT_NAME = KeychainSwift;
 				SDKROOT = macosx;
 				SKIP_INSTALL = YES;
+				SWIFT_VERSION = 3.0;
 			};
 			name = Debug;
 		};
@@ -660,10 +663,12 @@
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
 				MACOSX_DEPLOYMENT_TARGET = 10.10;
-				PRODUCT_BUNDLE_IDENTIFIER = "com.marketplacer.KeychainSwift-OSX";
+				PRODUCT_BUNDLE_IDENTIFIER = "com.marketplacer.KeychainSwift-macOS";
 				PRODUCT_NAME = KeychainSwift;
 				SDKROOT = macosx;
 				SKIP_INSTALL = YES;
+				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+				SWIFT_VERSION = 3.0;
 			};
 			name = Release;
 		};
@@ -683,6 +688,7 @@
 				PRODUCT_NAME = KeychainSwift;
 				SDKROOT = watchos;
 				SKIP_INSTALL = YES;
+				SWIFT_VERSION = 3.0;
 				TARGETED_DEVICE_FAMILY = 4;
 				WATCHOS_DEPLOYMENT_TARGET = 2.0;
 			};
@@ -703,6 +709,8 @@
 				PRODUCT_NAME = KeychainSwift;
 				SDKROOT = watchos;
 				SKIP_INSTALL = YES;
+				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+				SWIFT_VERSION = 3.0;
 				TARGETED_DEVICE_FAMILY = 4;
 				WATCHOS_DEPLOYMENT_TARGET = 2.0;
 			};
@@ -724,6 +732,7 @@
 				PRODUCT_NAME = KeychainSwift;
 				SDKROOT = appletvos;
 				SKIP_INSTALL = YES;
+				SWIFT_VERSION = 3.0;
 				TARGETED_DEVICE_FAMILY = 3;
 				TVOS_DEPLOYMENT_TARGET = 9.0;
 			};
@@ -744,6 +753,8 @@
 				PRODUCT_NAME = KeychainSwift;
 				SDKROOT = appletvos;
 				SKIP_INSTALL = YES;
+				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+				SWIFT_VERSION = 3.0;
 				TARGETED_DEVICE_FAMILY = 3;
 				TVOS_DEPLOYMENT_TARGET = 9.0;
 			};
@@ -876,6 +887,7 @@
 				PRODUCT_BUNDLE_IDENTIFIER = "com.marketplacer.$(PRODUCT_NAME:rfc1034identifier)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
+				SWIFT_VERSION = 3.0;
 			};
 			name = Debug;
 		};
@@ -893,6 +905,8 @@
 				PRODUCT_BUNDLE_IDENTIFIER = "com.marketplacer.$(PRODUCT_NAME:rfc1034identifier)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
+				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+				SWIFT_VERSION = 3.0;
 			};
 			name = Release;
 		};
@@ -924,6 +938,7 @@
 				PRODUCT_BUNDLE_IDENTIFIER = "com.marketplacer.$(PRODUCT_NAME:rfc1034identifier)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "KeychainSwiftTests/KeychainSwiftTests-Bridging-Header.h";
+				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
 			};
 			name = Release;
 		};
@@ -939,6 +954,7 @@
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = com.marketplacer.KeychainSwiftDemo;
 				PRODUCT_NAME = "Keychain Swift";
+				SWIFT_VERSION = 3.0;
 			};
 			name = Debug;
 		};
@@ -950,13 +966,15 @@
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = com.marketplacer.KeychainSwiftDemo;
 				PRODUCT_NAME = "Keychain Swift";
+				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+				SWIFT_VERSION = 3.0;
 			};
 			name = Release;
 		};
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
-		232B4C7F1BC29950001F2B7A /* Build configuration list for PBXNativeTarget "KeychainSwift-OSX" */ = {
+		232B4C7F1BC29950001F2B7A /* Build configuration list for PBXNativeTarget "KeychainSwift-macOS" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				232B4C801BC29950001F2B7A /* Debug */,

+ 1 - 1
KeychainSwift.xcodeproj/xcshareddata/xcschemes/ConcatenateSwiftFiles.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "0700"
+   LastUpgradeVersion = "0800"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"

+ 1 - 1
KeychainSwift.xcodeproj/xcshareddata/xcschemes/Demo.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "0640"
+   LastUpgradeVersion = "0800"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"

+ 4 - 4
KeychainSwift.xcodeproj/xcshareddata/xcschemes/KeychainSwift-OSX.xcscheme → KeychainSwift.xcodeproj/xcshareddata/xcschemes/KeychainSwift-macOS.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "0700"
+   LastUpgradeVersion = "0800"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
@@ -16,7 +16,7 @@
                BuildableIdentifier = "primary"
                BlueprintIdentifier = "232B4C791BC29950001F2B7A"
                BuildableName = "KeychainSwift.framework"
-               BlueprintName = "KeychainSwift-OSX"
+               BlueprintName = "KeychainSwift-macOS"
                ReferencedContainer = "container:KeychainSwift.xcodeproj">
             </BuildableReference>
          </BuildActionEntry>
@@ -47,7 +47,7 @@
             BuildableIdentifier = "primary"
             BlueprintIdentifier = "232B4C791BC29950001F2B7A"
             BuildableName = "KeychainSwift.framework"
-            BlueprintName = "KeychainSwift-OSX"
+            BlueprintName = "KeychainSwift-macOS"
             ReferencedContainer = "container:KeychainSwift.xcodeproj">
          </BuildableReference>
       </MacroExpansion>
@@ -65,7 +65,7 @@
             BuildableIdentifier = "primary"
             BlueprintIdentifier = "232B4C791BC29950001F2B7A"
             BuildableName = "KeychainSwift.framework"
-            BlueprintName = "KeychainSwift-OSX"
+            BlueprintName = "KeychainSwift-macOS"
             ReferencedContainer = "container:KeychainSwift.xcodeproj">
          </BuildableReference>
       </MacroExpansion>

+ 1 - 1
KeychainSwift.xcodeproj/xcshareddata/xcschemes/KeychainSwift-tvOS.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "0710"
+   LastUpgradeVersion = "0800"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"

+ 1 - 1
KeychainSwift.xcodeproj/xcshareddata/xcschemes/KeychainSwift-watchOS.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "0700"
+   LastUpgradeVersion = "0800"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"

+ 15 - 1
KeychainSwift.xcodeproj/xcshareddata/xcschemes/KeychainSwift.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "0700"
+   LastUpgradeVersion = "0800"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
@@ -20,6 +20,20 @@
                ReferencedContainer = "container:KeychainSwift.xcodeproj">
             </BuildableReference>
          </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "NO"
+            buildForRunning = "YES"
+            buildForProfiling = "NO"
+            buildForArchiving = "NO"
+            buildForAnalyzing = "NO">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "7ED51A751B7734AF005B39C2"
+               BuildableName = "ConcatenateSwiftFiles"
+               BlueprintName = "ConcatenateSwiftFiles"
+               ReferencedContainer = "container:KeychainSwift.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
       </BuildActionEntries>
    </BuildAction>
    <TestAction

+ 29 - 23
KeychainSwift/KeychainSwift.swift

@@ -54,10 +54,11 @@ public class KeychainSwift {
    - returns: True if the text was successfully written to the keychain.
 
   */
-  public func set(value: String, forKey key: String,
+  @discardableResult
+  public func set(_ value: String, forKey key: String,
                   withAccess access: KeychainSwiftAccessOptions? = nil) -> Bool {
     
-    if let value = value.dataUsingEncoding(NSUTF8StringEncoding) {
+    if let value = value.data(using: String.Encoding.utf8) {
       return set(value, forKey: key, withAccess: access)
     }
     
@@ -75,7 +76,8 @@ public class KeychainSwift {
   - returns: True if the text was successfully written to the keychain.
   
   */
-  public func set(value: NSData, forKey key: String,
+  @discardableResult
+  public func set(_ value: Data, forKey key: String,
     withAccess access: KeychainSwiftAccessOptions? = nil) -> Bool {
     
     delete(key) // Delete any existing key before saving it
@@ -84,7 +86,7 @@ public class KeychainSwift {
       
     let prefixedKey = keyWithPrefix(key)
       
-    var query = [
+    var query: [String : NSObject] = [
       KeychainSwiftConstants.klass       : kSecClassGenericPassword,
       KeychainSwiftConstants.attrAccount : prefixedKey,
       KeychainSwiftConstants.valueData   : value,
@@ -95,7 +97,7 @@ public class KeychainSwift {
     query = addSynchronizableIfRequired(query, addingItems: true)
     lastQueryParameters = query
     
-    lastResultCode = SecItemAdd(query as CFDictionaryRef, nil)
+    lastResultCode = SecItemAdd(query as CFDictionary, nil)
     
     return lastResultCode == noErr
   }
@@ -111,11 +113,13 @@ public class KeychainSwift {
   - returns: True if the value was successfully written to the keychain.
 
   */
-  public func set(value: Bool, forKey key: String,
+  @discardableResult
+  public func set(_ value: Bool, forKey key: String,
     withAccess access: KeychainSwiftAccessOptions? = nil) -> Bool {
+  
+    let bytes: [UInt8] = value ? [1] : [0]
+    let data = Data(bytes: bytes)
 
-    var localValue = value
-    let data = NSData(bytes: &localValue, length: sizeof(Bool))
     return set(data, forKey: key, withAccess: access)
   }
 
@@ -127,9 +131,10 @@ public class KeychainSwift {
   - returns: The text value from the keychain. Returns nil if unable to read the item.
   
   */
-  public func get(key: String) -> String? {
+  public func get(_ key: String) -> String? {
     if let data = getData(key) {
-      if let currentString = NSString(data: data, encoding: NSUTF8StringEncoding) as? String {
+      
+      if let currentString = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as? String {
         return currentString
       }
       
@@ -147,7 +152,7 @@ public class KeychainSwift {
   - returns: The text value from the keychain. Returns nil if unable to read the item.
   
   */
-  public func getData(key: String) -> NSData? {
+  public func getData(_ key: String) -> Data? {
     let prefixedKey = keyWithPrefix(key)
     
     var query: [String: NSObject] = [
@@ -167,7 +172,7 @@ public class KeychainSwift {
       SecItemCopyMatching(query, UnsafeMutablePointer($0))
     }
     
-    if lastResultCode == noErr { return result as? NSData }
+    if lastResultCode == noErr { return result as? Data }
     
     return nil
   }
@@ -180,11 +185,10 @@ public class KeychainSwift {
   - returns: The boolean value from the keychain. Returns nil if unable to read the item.
 
   */
-  public func getBool(key: String) -> Bool? {
+  public func getBool(_ key: String) -> Bool? {
     guard let data = getData(key) else { return nil }
-    var boolValue = false
-    data.getBytes(&boolValue, length: sizeof(Bool))
-    return boolValue
+    guard let firstBit = data.first else { return nil }
+    return firstBit == 1
   }
 
   /**
@@ -195,7 +199,8 @@ public class KeychainSwift {
   - returns: True if the item was successfully deleted.
   
   */
-  public func delete(key: String) -> Bool {
+  @discardableResult
+  public func delete(_ key: String) -> Bool {
     let prefixedKey = keyWithPrefix(key)
 
     var query: [String: NSObject] = [
@@ -207,7 +212,7 @@ public class KeychainSwift {
     query = addSynchronizableIfRequired(query, addingItems: false)
     lastQueryParameters = query
     
-    lastResultCode = SecItemDelete(query as CFDictionaryRef)
+    lastResultCode = SecItemDelete(query as CFDictionary)
     
     return lastResultCode == noErr
   }
@@ -219,23 +224,24 @@ public class KeychainSwift {
   - returns: True if the keychain items were successfully deleted.
   
   */
+  @discardableResult
   public func clear() -> Bool {
     var query: [String: NSObject] = [ kSecClass as String : kSecClassGenericPassword ]
     query = addAccessGroupWhenPresent(query)
     query = addSynchronizableIfRequired(query, addingItems: false)
     lastQueryParameters = query
     
-    lastResultCode = SecItemDelete(query as CFDictionaryRef)
+    lastResultCode = SecItemDelete(query as CFDictionary)
     
     return lastResultCode == noErr
   }
   
   /// Returns the key with currently set prefix.
-  func keyWithPrefix(key: String) -> String {
+  func keyWithPrefix(_ key: String) -> String {
     return "\(keyPrefix)\(key)"
   }
   
-  func addAccessGroupWhenPresent(items: [String: NSObject]) -> [String: NSObject] {
+  func addAccessGroupWhenPresent(_ items: [String: NSObject]) -> [String: NSObject] {
     guard let accessGroup = accessGroup else { return items }
     
     var result: [String: NSObject] = items
@@ -253,10 +259,10 @@ public class KeychainSwift {
    - returns: the dictionary with kSecAttrSynchronizable item added if it was requested. Otherwise, it returns the original dictionary.
  
   */
-  func addSynchronizableIfRequired(items: [String: NSObject], addingItems: Bool) -> [String: NSObject] {
+  func addSynchronizableIfRequired(_ items: [String: NSObject], addingItems: Bool) -> [String: NSObject] {
     if !synchronizable { return items }
     var result: [String: NSObject] = items
     result[KeychainSwiftConstants.attrSynchronizable] = addingItems == true ? true : kSecAttrSynchronizableAny
     return result
   }
-}
+}

+ 17 - 17
KeychainSwift/KeychainSwiftAccessOptions.swift

@@ -16,7 +16,7 @@ public enum KeychainSwiftAccessOptions {
   This is the default value for keychain items added without explicitly setting an accessibility constant.
   
   */
-  case AccessibleWhenUnlocked
+  case accessibleWhenUnlocked
   
   /**
   
@@ -25,7 +25,7 @@ public enum KeychainSwiftAccessOptions {
   This is recommended for items that need to be accessible only while the application is in the foreground. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
   
   */
-  case AccessibleWhenUnlockedThisDeviceOnly
+  case accessibleWhenUnlockedThisDeviceOnly
   
   /**
   
@@ -34,7 +34,7 @@ public enum KeychainSwiftAccessOptions {
   After the first unlock, the data remains accessible until the next restart. This is recommended for items that need to be accessed by background applications. Items with this attribute migrate to a new device when using encrypted backups.
   
   */
-  case AccessibleAfterFirstUnlock
+  case accessibleAfterFirstUnlock
   
   /**
   
@@ -43,7 +43,7 @@ public enum KeychainSwiftAccessOptions {
   After the first unlock, the data remains accessible until the next restart. This is recommended for items that need to be accessed by background applications. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
   
   */
-  case AccessibleAfterFirstUnlockThisDeviceOnly
+  case accessibleAfterFirstUnlockThisDeviceOnly
   
   /**
   
@@ -52,7 +52,7 @@ public enum KeychainSwiftAccessOptions {
   This is not recommended for application use. Items with this attribute migrate to a new device when using encrypted backups.
   
   */
-  case AccessibleAlways
+  case accessibleAlways
   
   /**
   
@@ -61,7 +61,7 @@ public enum KeychainSwiftAccessOptions {
   This is recommended for items that only need to be accessible while the application is in the foreground. Items with this attribute never migrate to a new device. After a backup is restored to a new device, these items are missing. No items can be stored in this class on devices without a passcode. Disabling the device passcode causes all items in this class to be deleted.
   
   */
-  case AccessibleWhenPasscodeSetThisDeviceOnly
+  case accessibleWhenPasscodeSetThisDeviceOnly
   
   /**
   
@@ -70,38 +70,38 @@ public enum KeychainSwiftAccessOptions {
   This is not recommended for application use. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
   
   */
-  case AccessibleAlwaysThisDeviceOnly
+  case accessibleAlwaysThisDeviceOnly
   
   static var defaultOption: KeychainSwiftAccessOptions {
-    return .AccessibleWhenUnlocked
+    return .accessibleWhenUnlocked
   }
   
   var value: String {
     switch self {
-    case .AccessibleWhenUnlocked:
+    case .accessibleWhenUnlocked:
       return toString(kSecAttrAccessibleWhenUnlocked)
       
-    case .AccessibleWhenUnlockedThisDeviceOnly:
+    case .accessibleWhenUnlockedThisDeviceOnly:
       return toString(kSecAttrAccessibleWhenUnlockedThisDeviceOnly)
       
-    case .AccessibleAfterFirstUnlock:
+    case .accessibleAfterFirstUnlock:
       return toString(kSecAttrAccessibleAfterFirstUnlock)
       
-    case .AccessibleAfterFirstUnlockThisDeviceOnly:
+    case .accessibleAfterFirstUnlockThisDeviceOnly:
       return toString(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly)
       
-    case .AccessibleAlways:
+    case .accessibleAlways:
       return toString(kSecAttrAccessibleAlways)
       
-    case .AccessibleWhenPasscodeSetThisDeviceOnly:
+    case .accessibleWhenPasscodeSetThisDeviceOnly:
       return toString(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly)
       
-    case .AccessibleAlwaysThisDeviceOnly:
+    case .accessibleAlwaysThisDeviceOnly:
       return toString(kSecAttrAccessibleAlwaysThisDeviceOnly)
     }
   }
   
-  func toString(value: CFStringRef) -> String {
+  func toString(_ value: CFString) -> String {
     return KeychainSwiftConstants.toString(value)
   }
-}
+}

+ 1 - 1
KeychainSwift/TegKeychainConstants.swift

@@ -31,7 +31,7 @@ public struct KeychainSwiftConstants {
   /// Used for specifying a value when setting a Keychain value.
   public static var valueData: String { return toString(kSecValueData) }
   
-  static func toString(value: CFStringRef) -> String {
+  static func toString(_ value: CFString) -> String {
     return value as String
   }
 }

+ 2 - 2
KeychainSwiftTests/AccessGroupTests.swift

@@ -48,7 +48,7 @@ class AccessGroupTests: XCTestCase {
   
   func testGet() {
     obj.accessGroup = "123.my.test.group"
-    obj.get("key 1")
+    _ = obj.get("key 1")
     XCTAssertEqual("123.my.test.group", obj.lastQueryParameters?["agrp"])
   }
   
@@ -63,4 +63,4 @@ class AccessGroupTests: XCTestCase {
     obj.clear()
     XCTAssertEqual("123.my.test.group", obj.lastQueryParameters?["agrp"])
   }
-}
+}

+ 4 - 4
KeychainSwiftTests/KeychainSwiftPrefixedTests.swift

@@ -43,19 +43,19 @@ class KeychainWithPrefixTests: XCTestCase {
   func testSetData() {
     let key = "key 123"
     
-    let dataPrefixed = "prefixed".dataUsingEncoding(NSUTF8StringEncoding)!
-    let dataNonPrefixed = "non prefixed".dataUsingEncoding(NSUTF8StringEncoding)!
+    let dataPrefixed = "prefixed".data(using: String.Encoding.utf8)!
+    let dataNonPrefixed = "non prefixed".data(using: String.Encoding.utf8)!
     
     XCTAssertTrue(prefixed.set(dataPrefixed, forKey: key))
     XCTAssertTrue(nonPrefixed.set(dataNonPrefixed, forKey: key))
 
     
     let dataFromKeychainPrefixed = prefixed.getData(key)!
-    let textFromKeychainPrefixed = NSString(data: dataFromKeychainPrefixed, encoding:NSUTF8StringEncoding) as! String
+    let textFromKeychainPrefixed = String(data: dataFromKeychainPrefixed, encoding: .utf8)!
     XCTAssertEqual("prefixed", textFromKeychainPrefixed)
     
     let dataFromKeychainNonPrefixed = nonPrefixed.getData(key)!
-    let textFromKeychainNonPrefixed = NSString(data: dataFromKeychainNonPrefixed, encoding:NSUTF8StringEncoding) as! String
+    let textFromKeychainNonPrefixed = String(data: dataFromKeychainNonPrefixed, encoding: .utf8)!
     XCTAssertEqual("non prefixed", textFromKeychainNonPrefixed)
   }
   

+ 8 - 8
KeychainSwiftTests/KeychainSwiftTests.swift

@@ -25,35 +25,35 @@ class keychainTests: XCTestCase {
     XCTAssertTrue(obj.set("hello :)", forKey: "key 1"))
     
     let accessValue = obj.lastQueryParameters?[KeychainSwiftConstants.accessible] as? String
-    XCTAssertEqual(KeychainSwiftAccessOptions.AccessibleWhenUnlocked.value, accessValue!)
+    XCTAssertEqual(KeychainSwiftAccessOptions.accessibleWhenUnlocked.value, accessValue!)
   }
   
   func testSetWithAccessOption() {
-    obj.set("hello :)", forKey: "key 1", withAccess: .AccessibleAfterFirstUnlock)
+    obj.set("hello :)", forKey: "key 1", withAccess: .accessibleAfterFirstUnlock)
     let accessValue = obj.lastQueryParameters?[KeychainSwiftConstants.accessible] as? String
-    XCTAssertEqual(KeychainSwiftAccessOptions.AccessibleAfterFirstUnlock.value, accessValue!)
+    XCTAssertEqual(KeychainSwiftAccessOptions.accessibleAfterFirstUnlock.value, accessValue!)
   }
   
   // MARK: - Set data
   // -----------------------
   
   func testSetData() {
-    let data = "hello world".dataUsingEncoding(NSUTF8StringEncoding)!
+    let data = "hello world".data(using: String.Encoding.utf8)!
     
     XCTAssertTrue(obj.set(data, forKey: "key 123"))
     
     let dataFromKeychain = obj.getData("key 123")!
-    let textFromKeychain = NSString(data: dataFromKeychain, encoding:NSUTF8StringEncoding) as! String
+    let textFromKeychain = String(data: dataFromKeychain, encoding:String.Encoding.utf8)!
     XCTAssertEqual("hello world", textFromKeychain)
   }
   
   func testSetData_usesAccessibleWhenUnlockedByDefault() {
-    let data = "hello world".dataUsingEncoding(NSUTF8StringEncoding)!
+    let data = "hello world".data(using: String.Encoding.utf8)!
     
     obj.set(data, forKey: "key 123")
     
     let accessValue = obj.lastQueryParameters?[KeychainSwiftConstants.accessible] as? String
-    XCTAssertEqual(KeychainSwiftAccessOptions.AccessibleWhenUnlocked.value, accessValue!)
+    XCTAssertEqual(KeychainSwiftAccessOptions.accessibleWhenUnlocked.value, accessValue!)
   }
 
   // MARK: - Set bool
@@ -69,7 +69,7 @@ class keychainTests: XCTestCase {
   func testSetBool_usesAccessibleWhenUnlockedByDefault() {
     XCTAssertTrue(obj.set(false, forKey: "key bool"))
     let accessValue = obj.lastQueryParameters?[KeychainSwiftConstants.accessible] as? String
-    XCTAssertEqual(KeychainSwiftAccessOptions.AccessibleWhenUnlocked.value, accessValue!)
+    XCTAssertEqual(KeychainSwiftAccessOptions.accessibleWhenUnlocked.value, accessValue!)
   }
 
   // MARK: - Get

+ 3 - 3
KeychainSwiftTests/SynchronizableTests.swift

@@ -70,12 +70,12 @@ class SynchronizableTests: XCTestCase {
   
   func testGet() {
     obj.synchronizable = true
-    obj.get("key 1")
+    _ = obj.get("key 1")
     XCTAssertEqual(kSecAttrSynchronizableAny, obj.lastQueryParameters?["sync"])
   }
   
   func testGet_doNotSetSynchronizable() {
-    obj.get("key 1")
+    _ = obj.get("key 1")
     XCTAssertNil(obj.lastQueryParameters?["sync"])
   }
   
@@ -104,4 +104,4 @@ class SynchronizableTests: XCTestCase {
     obj.clear()
     XCTAssertNil(obj.lastQueryParameters?["sync"])
   }
-}
+}

+ 23 - 28
README.md

@@ -1,4 +1,4 @@
-# Helper functions for storing text in Keychain for iOS, OS X, tvOS and WatchOS
+# Helper functions for storing text in Keychain for iOS, macOS, tvOS and WatchOS
 
 [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)][carthage]
 [![CocoaPods Version](https://img.shields.io/cocoapods/v/KeychainSwift.svg?style=flat)][cocoadocs]
@@ -9,16 +9,16 @@
 
 This is a collection of helper functions for saving text and data in the Keychain.
  As you probably noticed Apple's keychain API is a bit verbose. This library was designed to provide shorter syntax for accomplishing a simple task: reading/writing text values for specified keys:
- 
+
  ```Swift
 let keychain = KeychainSwift()
 keychain.set("hello world", forKey: "my key")
 keychain.get("my key")
  ```
- 
- The Keychain library includes the following features: 
- 
- * <a href="#usage">Get, set and delete string, boolean and NSData Keychain items</a>
+
+ The Keychain library includes the following features:
+
+ * <a href="#usage">Get, set and delete string, boolean and Data Keychain items</a>
  * <a href="#keychain_item_access">Specify item access security level</a>
  * <a href="#keychain_synchronization">Synchronize items through iCloud</a>
  * <a href="#keychain_access_groups">Share Keychain items with other apps</a>
@@ -32,35 +32,27 @@ Keychain is a secure storage. You can store all kind of sensitive data in it: us
 
 There are three ways you can add KeychainSwift to your Xcode project.
 
-**Add source (iOS 7+)**
+#### Add source (iOS 7+)
 
 Simply add [KeychainSwiftDistrib.swift](https://github.com/marketplacer/keychain-swift/blob/master/Distrib/KeychainSwiftDistrib.swift) file into your Xcode project.
 
-**Setup with Carthage (iOS 8+)**
+#### Setup with Carthage (iOS 8+)
 
-Alternatively, add `github "marketplacer/keychain-swift" ~> 3.0` to your Cartfile and run `carthage update`.
+Alternatively, add `github "marketplacer/keychain-swift" ~> 4.0` to your Cartfile and run `carthage update`.
 
-**Setup with CocoaPods (iOS 8+)**
+#### Setup with CocoaPods (iOS 8+)
 
 If you are using CocoaPods add this text to your Podfile and run `pod install`.
 
     use_frameworks!
     target 'Your target name'
-    pod 'KeychainSwift', '~> 3.0'
-
-Here is how to use KeychainSwift in a *WatchKit extension* with CocoaPods.
+    pod 'KeychainSwift', '~> 4.0'
 
-    use_frameworks!
-
-    target 'YourWatchApp Extension Target Name' do
-      platform :watchos, '2.0'
-      pod 'KeychainSwift', '~> 3.0'
-    end
 
+#### Legacy Swift versions
 
-**Setup in Swift 1.2 project**
+Setup a [previous version](https://github.com/marketplacer/keychain-swift/wiki/Legacy-Swift-versions) of the library if you use an older version of Swift.
 
-Use the [previous version of the library](https://github.com/marketplacer/keychain-swift/wiki/Swift-1.2-setup).
 
 **iOS 7 support**
 
@@ -91,12 +83,12 @@ keychain.set(true, forKey: "my key")
 keychain.getBool("my key")
 ```
 
-#### NSData values
+#### Data values
 
 ```Swift
 let keychain = KeychainSwift()
 
-keychain.set(nsDataObject, forKey: "my key")
+keychain.set(dataObject, forKey: "my key")
 
 keychain.getData("my key")
 ```
@@ -106,7 +98,7 @@ keychain.getData("my key")
 ```Swift
 keychain.delete("my key") // Remove single key
 
-keychain.clear() // Delete everything from app's Keychain. Does not work on OS X.
+keychain.clear() // Delete everything from app's Keychain. Does not work on macOS.
 ```
 
 ## Advanced options
@@ -115,13 +107,13 @@ keychain.clear() // Delete everything from app's Keychain. Does not work on OS X
 <h3 id="keychain_item_access">Keychain item access</h3>
 
 Use `withAccess` parameter to specify the security level of the keychain storage.
-By default the `.AccessibleWhenUnlocked` option is used. It is one of the most restrictive options and provides good data protection.
+By default the `.accessibleWhenUnlocked` option is used. It is one of the most restrictive options and provides good data protection.
 
 ```
-KeychainSwift().set("Hello world", forKey: "key 1", withAccess: .AccessibleWhenUnlocked)
+KeychainSwift().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. Note that it is less secure than the `.AccessibleWhenUnlocked` option.
+You can use `.accessibleAfterFirstUnlock` if you need your app to access the keychain item while in the background. Note that it is less secure than the `.accessibleWhenUnlocked` option.
 
 See the list of all available [access options](https://github.com/marketplacer/keychain-swift/blob/master/KeychainSwift/KeychainSwiftAccessOptions.swift).
 
@@ -221,9 +213,12 @@ Here are some other Keychain libraries.
 
 * The code is based on this example: [https://gist.github.com/s-aska/e7ad24175fb7b04f78e7](https://gist.github.com/s-aska/e7ad24175fb7b04f78e7)
 * Thanks to [glyuck](https://github.com/glyuck) for taming booleans.
-* Thanks to [pepibumur](https://github.com/pepibumur) for adding OS X, watchOS and tvOS support.
+* Thanks to [pepibumur](https://github.com/pepibumur) for adding macOS, watchOS and tvOS support.
 * Thanks to [ezura](https://github.com/ezura) for iOS 7 support.
 * Thanks to [mikaoj](https://github.com/mikaoj) for adding keychain synchronization.
+* Thanks to [tcirwin](https://github.com/tcirwin) for adding Swift 3.0 support.
+
+
 
 ## License