Swiftpack.co - andriyslyusar/SwiftyKeychainKit as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by andriyslyusar.
andriyslyusar/SwiftyKeychainKit 1.0.0-beta.2
Modern Swift wrapper for Keychain Services API with the benefits of static typing
⭐️ 22
🕓 1 year ago
iOS
.package(url: "https://github.com/andriyslyusar/SwiftyKeychainKit.git", from: "1.0.0-beta.2")

SwiftyKeychainKit

Platforms Build Status Swift version CocoaPods compatible SPM compatible Carthage compatible

SwiftyKeychainKit is a simple Swift wrapper for Keychain Services API with the benefits of static typing. Define your keys in one place, use value types easily, and get extra safety and convenient compile-time checks for free.

Features

  • Static typing and compile-time checks
  • Support Gereric and Internet passwords
  • Throwing and Result type get methods
  • Easy way to implement support for custom types

Usage

Basic

let keychain = Keychain(service: "com.swifty.keychain")
let accessTokenKey = KeychainKey<String>(key: "accessToken")

// Save or modify value
try? keychain.save("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9", for : accessTokenKey)

// Get value 
let value = try keychain.get(accessTokenKey)

// Remove value 
try keychain.remove(accessTokenKey)

// Remove all values 
try keychain.removeAll()

Instantiation

// Generic password
let keychain = Keychain(service: "com.swifty.keychainkit")

// Internet password
let keychain = Keychain(server: URL(string: "https://www.google.com")!, protocolType: .https)

Define keys

For extra convenience, define your keys by extending KeychainKeys class and adding static properties:

extension KeychainKeys {
    static let username = KeychainKey<String>(key: "username")
    static let age = KeychainKey<Int>(key: "age")
}

and later in the code use shortcut dot syntax:

// save
try? keychain.save("John Snow", for: .username)

// get
let username = try keychain.get(.username)

Geting values

You can use subscripts and dynamicCallable syntax sugar to get value as Result<ValueType, KeychainError>

let username = try keychain[.username].get()

// or 

if case .success(let age) = keychain[.age] {
    ...
}
let username = try keychain(.username).get()

// or 

if case .success(let age) = keychain(.age) {
    ...
}

Both subscripts and dynamicCallable syntaxt available only for geting values. Currently Swift language limitation do not allow implement setter with error handling.

Default values

You can provide default value for get method and it will used than keychain key is nil and no error throw.

try keychain.get(.username, default: "Daenerys Targaryen")

// or

try keychain[.age, default: 18].get() 

Supported types

  • Int
  • String
  • Double
  • Float
  • Bool
  • Data

Codable

struct MyStruct: Codable, KeychainSerializable { ... }

NSCoding

class MyClass: NSObject, NSCoding, KeychainSerializable { ... }

Custom types

In order to save/get your own custom type that we don't support, you need to confirm it KeychainSerializable and implement KeychainBridge for this type.

As an example saving Array<String> using JSONSerialization:

extension Array: KeychainSerializable where Element == String  {
    public static var bridge: KeychainBridge<[String]> { return KeychainBridgeStringArray() }
}
class KeychainBridgeStringArray: KeychainBridge<[String]> {
    public override func set(_ value: [String], forKey key: String, in keychain: Keychain) throws {
        guard let data = try? JSONSerialization.data(withJSONObject: value, options: []) else {
            fatalError()
        }
        try? persist(value: data, key: key, keychain: keychain)
    }

    public override func get(key: String, from keychain: Keychain) throws -> [String]? {
        guard let data = try? find(key: key, keychain: keychain) else {
            return nil
        }

        return (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String]
    }
}

Supported attributes

Common

  • ☑ kSecAttrAccessGroup
  • ☑ kSecAttrAccessible
  • ☑ kSecAttrDescription
  • ☑ kSecAttrComment
  • ☐ kSecAttrCreator
  • ☐ kSecAttrType
  • ☑ kSecAttrLabel
  • ☑ kSecAttrIsInvisible
  • ☑ kSecAttrIsNegative
  • ☑ kSecAttrAccount
  • ☑ kSecAttrSynchronizable

Generic password

  • ☐ kSecAttrAccessControl
  • ☑ kSecAttrService
  • ☐ kSecAttrGeneric

Internet password

  • ☑ kSecAttrSecurityDomain
  • ☑ kSecAttrServer
  • ☑ kSecAttrProtocol
  • ☑ kSecAttrAuthenticationType
  • ☑ kSecAttrPort
  • ☑ kSecAttrPath

Requirement

Swift version 5.0

Platform Availability
iOS >= 8.0
macOS -
tvOS -
watchOS -

Installation

CocoaPods

pod 'SwiftyKeychainKit', '1.0.0-beta.2'

Swift Package Manager

let package = Package(
    dependencies: [
        .Package(url: "https://github.com/andriyslyusar/SwiftyKeychainKit.git", .exact("1.0.0-beta.2"))
    ]
)

Carthage

github "andriyslyusar/SwiftyKeychainKit" "1.0.0-beta.2"

Acknowledgement

Author

Andriy Slyusar

License

SwiftyKeychainKit is available under the MIT license. See the LICENSE file for more info.

GitHub

link
Stars: 22
Last commit: 1 year ago
Advertisement: IndiePitcher.com - Cold Email Software for Startups

Release Notes

4 years ago
  • Support for Swift Package Manager, CocoaPods and Carthage

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics