KeychainAccess

所属分类:iPhone/iOS
开发工具:Swift
文件大小:0KB
下载次数:0
上传日期:2023-05-12 09:51:18
上 传 者sh-1993
说明:  Keychain的简单Swift包装器,适用于iOS、watchOS、tvOS和macOS。
(Simple Swift wrapper for Keychain that works on iOS, watchOS, tvOS and macOS.)

文件列表:
.swiftpm/ (0, 2023-11-12)
.swiftpm/xcode/ (0, 2023-11-12)
.swiftpm/xcode/package.xcworkspace/ (0, 2023-11-12)
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata (135, 2023-11-12)
Examples/ (0, 2023-11-12)
Examples/Example-iOS/ (0, 2023-11-12)
Examples/Example-iOS/Example-iOS.xcodeproj/ (0, 2023-11-12)
Examples/Example-iOS/Example-iOS.xcodeproj/project.pbxproj (16719, 2023-11-12)
Examples/Example-iOS/Example-iOS.xcodeproj/xcshareddata/ (0, 2023-11-12)
Examples/Example-iOS/Example-iOS.xcodeproj/xcshareddata/xcschemes/ (0, 2023-11-12)
Examples/Example-iOS/Example-iOS.xcodeproj/xcshareddata/xcschemes/Example-iOS.xcscheme (4284, 2023-11-12)
Examples/Example-iOS/Example-iOS/ (0, 2023-11-12)
Examples/Example-iOS/Example-iOS/AccountsViewController.swift (5060, 2023-11-12)
Examples/Example-iOS/Example-iOS/AppDelegate.swift (1744, 2023-11-12)
Examples/Example-iOS/Example-iOS/Base.lproj/ (0, 2023-11-12)
Examples/Example-iOS/Example-iOS/Base.lproj/LaunchScreen.xib (1362, 2023-11-12)
Examples/Example-iOS/Example-iOS/Base.lproj/Main.storyboard (19062, 2023-11-12)
Examples/Example-iOS/Example-iOS/Example-iOS.entitlements (316, 2023-11-12)
Examples/Example-iOS/Example-iOS/Images.xcassets/ (0, 2023-11-12)
Examples/Example-iOS/Example-iOS/Images.xcassets/AppIcon.appiconset/ (0, 2023-11-12)
Examples/Example-iOS/Example-iOS/Images.xcassets/AppIcon.appiconset/Contents.json (848, 2023-11-12)
Examples/Example-iOS/Example-iOS/Info.plist (1205, 2023-11-12)
Examples/Example-iOS/Example-iOS/InputViewController.swift (2777, 2023-11-12)
KeychainAccess.podspec (1701, 2023-11-12)
KeychainAccess.xcworkspace/ (0, 2023-11-12)
KeychainAccess.xcworkspace/contents.xcworkspacedata (367, 2023-11-12)
KeychainAccess.xcworkspace/xcshareddata/ (0, 2023-11-12)
KeychainAccess.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (238, 2023-11-12)
LICENSE (1085, 2023-11-12)
Lib/ (0, 2023-11-12)
Lib/Configurations/ (0, 2023-11-12)
Lib/Configurations/Base.xcconfig (1635, 2023-11-12)
Lib/Configurations/Debug.xcconfig (279, 2023-11-12)
Lib/Configurations/KeychainAccess.xcconfig (1171, 2023-11-12)
Lib/Configurations/Release.xcconfig (266, 2023-11-12)
Lib/Configurations/TestHost.xcconfig (1398, 2023-11-12)
... ...

# KeychainAccess [![Build Status](https://travis-ci.com/kishikawakatsumi/KeychainAccess.svg?branch=master)](https://travis-ci.com/kishikawakatsumi/KeychainAccess) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![SPM supported](https://img.shields.io/badge/SPM-supported-DE5C43.svg?style=flat)](https://swift.org/package-manager) [![Version](https://img.shields.io/cocoapods/v/KeychainAccess.svg)](http://cocoadocs.org/docsets/KeychainAccess) [![Platform](https://img.shields.io/cocoapods/p/KeychainAccess.svg)](http://cocoadocs.org/docsets/KeychainAccess) KeychainAccess is a simple Swift wrapper for Keychain that works on iOS and macOS. Makes using Keychain APIs extremely easy and much more palatable to use in Swift. ## :bulb: Features - Simple interface - Support access group - [Support accessibility](#accessibility) - [Support iCloud sharing](#icloud_sharing) - **[Support TouchID and Keychain integration (iOS 8+)](#touch_id_integration)** - **[Support Shared Web Credentials (iOS 8+)](#shared_web_credentials)** - [Works on both iOS & macOS](#requirements) - [watchOS and tvOS are supported](#requirements) - **[Mac Catalyst is supported](#requirements)** - **[Swift 3, 4 and 5 compatible](#requirements)** ## :book: Usage ##### :eyes: See also: - [:link: iOS Example Project](https://github.com/kishikawakatsumi/KeychainAccess/tree/master/Examples/Example-iOS) ### :key: Basics #### Saving Application Password ```swift let keychain = Keychain(service: "com.example.github-token") keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef" ``` #### Saving Internet Password ```swift let keychain = Keychain(server: "https://github.com", protocolType: .https) keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef" ``` ### :key: Instantiation #### Create Keychain for Application Password ```swift let keychain = Keychain(service: "com.example.github-token") ``` ```swift let keychain = Keychain(service: "com.example.github-token", accessGroup: "12ABCD3E4F.shared") ``` #### Create Keychain for Internet Password ```swift let keychain = Keychain(server: "https://github.com", protocolType: .https) ``` ```swift let keychain = Keychain(server: "https://github.com", protocolType: .https, authenticationType: .htmlForm) ``` ### :key: Adding an item #### subscripting ##### for String ```swift keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef" ``` ```swift keychain[string: "kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef" ``` ##### for NSData ```swift keychain[data: "secret"] = NSData(contentsOfFile: "secret.bin") ``` #### set method ```swift keychain.set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") ``` #### error handling ```swift do { try keychain.set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") } catch let error { print(error) } ``` ### :key: Obtaining an item #### subscripting ##### for String (If the value is NSData, attempt to convert to String) ```swift let token = keychain["kishikawakatsumi"] ``` ```swift let token = keychain[string: "kishikawakatsumi"] ``` ##### for NSData ```swift let secretData = keychain[data: "secret"] ``` #### get methods ##### as String ```swift let token = try? keychain.get("kishikawakatsumi") ``` ```swift let token = try? keychain.getString("kishikawakatsumi") ``` ##### as NSData ```swift let data = try? keychain.getData("kishikawakatsumi") ``` ### :key: Removing an item #### subscripting ```swift keychain["kishikawakatsumi"] = nil ``` #### remove method ```swift do { try keychain.remove("kishikawakatsumi") } catch let error { print("error: \(error)") } ``` ### :key: Set Label and Comment ```swift let keychain = Keychain(server: "https://github.com", protocolType: .https) do { try keychain .label("github.com (kishikawakatsumi)") .comment("github access token") .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") } catch let error { print("error: \(error)") } ``` ### :key: Obtaining Other Attributes #### PersistentRef ```swift let keychain = Keychain() let persistentRef = keychain[attributes: "kishikawakatsumi"]?.persistentRef ... ``` #### Creation Date ```swift let keychain = Keychain() let creationDate = keychain[attributes: "kishikawakatsumi"]?.creationDate ... ``` #### All Attributes ```swift let keychain = Keychain() do { let attributes = try keychain.get("kishikawakatsumi") { $0 } print(attributes?.comment) print(attributes?.label) print(attributes?.creator) ... } catch let error { print("error: \(error)") } ``` ##### subscripting ```swift let keychain = Keychain() if let attributes = keychain[attributes: "kishikawakatsumi"] { print(attributes.comment) print(attributes.label) print(attributes.creator) } ``` ### :key: Configuration (Accessibility, Sharing, iCloud Sync) **Provides fluent interfaces** ```swift let keychain = Keychain(service: "com.example.github-token") .label("github.com (kishikawakatsumi)") .synchronizable(true) .accessibility(.afterFirstUnlock) ``` #### Accessibility ##### Default accessibility matches background application (=kSecAttrAccessibleAfterFirstUnlock) ```swift let keychain = Keychain(service: "com.example.github-token") ``` ##### For background application ###### Creating instance ```swift let keychain = Keychain(service: "com.example.github-token") .accessibility(.afterFirstUnlock) keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef" ``` ###### One-shot ```swift let keychain = Keychain(service: "com.example.github-token") do { try keychain .accessibility(.afterFirstUnlock) .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") } catch let error { print("error: \(error)") } ``` ##### For foreground application ###### Creating instance ```swift let keychain = Keychain(service: "com.example.github-token") .accessibility(.whenUnlocked) keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef" ``` ###### One-shot ```swift let keychain = Keychain(service: "com.example.github-token") do { try keychain .accessibility(.whenUnlocked) .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") } catch let error { print("error: \(error)") } ``` #### :couple: Sharing Keychain items ```swift let keychain = Keychain(service: "com.example.github-token", accessGroup: "12ABCD3E4F.shared") ``` #### :arrows_counterclockwise: Synchronizing Keychain items with iCloud ###### Creating instance ```swift let keychain = Keychain(service: "com.example.github-token") .synchronizable(true) keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef" ``` ###### One-shot ```swift let keychain = Keychain(service: "com.example.github-token") do { try keychain .synchronizable(true) .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") } catch let error { print("error: \(error)") } ``` ### :cyclone: Touch ID (Face ID) integration **Any Operation that require authentication must be run in the background thread.** **If you run in the main thread, UI thread will lock for the system to try to display the authentication dialog.** **To use Face ID, add `NSFaceIDUsageDescription` key to your `Info.plist`** #### :closed_lock_with_key: Adding a Touch ID (Face ID) protected item If you want to store the Touch ID protected Keychain item, specify `accessibility` and `authenticationPolicy` attributes. ```swift let keychain = Keychain(service: "com.example.github-token") DispatchQueue.global().async { do { // Should be the secret invalidated when passcode is removed? If not then use `.WhenUnlocked` try keychain .accessibility(.whenPasscodeSetThisDeviceOnly, authenticationPolicy: [.biometryAny]) .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") } catch let error { // Error handling if needed... } } ``` #### :closed_lock_with_key: Updating a Touch ID (Face ID) protected item The same way as when adding. **Do not run in the main thread if there is a possibility that the item you are trying to add already exists, and protected.** **Because updating protected items requires authentication.** Additionally, you want to show custom authentication prompt message when updating, specify an `authenticationPrompt` attribute. If the item not protected, the `authenticationPrompt` parameter just be ignored. ```swift let keychain = Keychain(service: "com.example.github-token") DispatchQueue.global().async { do { // Should be the secret invalidated when passcode is removed? If not then use `.WhenUnlocked` try keychain .accessibility(.whenPasscodeSetThisDeviceOnly, authenticationPolicy: [.biometryAny]) .authenticationPrompt("Authenticate to update your access token") .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") } catch let error { // Error handling if needed... } } ``` #### :closed_lock_with_key: Obtaining a Touch ID (Face ID) protected item The same way as when you get a normal item. It will be displayed automatically Touch ID or passcode authentication If the item you try to get is protected. If you want to show custom authentication prompt message, specify an `authenticationPrompt` attribute. If the item not protected, the `authenticationPrompt` parameter just be ignored. ```swift let keychain = Keychain(service: "com.example.github-token") DispatchQueue.global().async { do { let password = try keychain .authenticationPrompt("Authenticate to login to server") .get("kishikawakatsumi") print("password: \(password)") } catch let error { // Error handling if needed... } } ``` #### :closed_lock_with_key: Removing a Touch ID (Face ID) protected item The same way as when you remove a normal item. There is no way to show Touch ID or passcode authentication when removing Keychain items. ```swift let keychain = Keychain(service: "com.example.github-token") do { try keychain.remove("kishikawakatsumi") } catch let error { // Error handling if needed... } ``` ### :key: Shared Web Credentials > Shared web credentials is a programming interface that enables native iOS apps to share credentials with their website counterparts. For example, a user may log in to a website in Safari, entering a user name and password, and save those credentials using the iCloud Keychain. Later, the user may run a native app from the same developer, and instead of the app requiring the user to reenter a user name and password, shared web credentials gives it access to the credentials that were entered earlier in Safari. The user can also create new accounts, update passwords, or delete her account from within the app. These changes are then saved and used by Safari. > ```swift let keychain = Keychain(server: "https://www.kishikawakatsumi.com", protocolType: .HTTPS) let username = "kishikawakatsumi@mac.com" // First, check the credential in the app's Keychain if let password = try? keychain.get(username) { // If found password in the Keychain, // then log into the server } else { // If not found password in the Keychain, // try to read from Shared Web Credentials keychain.getSharedPassword(username) { (password, error) -> () in if password != nil { // If found password in the Shared Web Credentials, // then log into the server // and save the password to the Keychain keychain[username] = password } else { // If not found password either in the Keychain also Shared Web Credentials, // prompt for username and password // Log into server // If the login is successful, // save the credentials to both the Keychain and the Shared Web Credentials. keychain[username] = inputPassword keychain.setSharedPassword(inputPassword, account: username) } } } ``` #### Request all associated domain's credentials ```swift Keychain.requestSharedWebCredential { (credentials, error) -> () in } ``` #### Generate strong random password Generate strong random password that is in the same format used by Safari autofill (xxx-xxx-xxx-xxx). ```swift let password = Keychain.generatePassword() // => Nhu-GKm-s3n-pMx ``` #### How to set up Shared Web Credentials > 1. Add a com.apple.developer.associated-domains entitlement to your app. This entitlement must include all the domains with which you want to share credentials. > > 2. Add an apple-app-site-association file to your website. This file must include application identifiers for all the apps with which the site wants to share credentials, and it must be properly signed. > > 3. When the app is installed, the system downloads and verifies the site association file for each of its associated domains. If the verification is successful, the app is associated with the domain. **More details:** ### :mag: Debugging #### Display all stored items if print keychain object ```swift let keychain = Keychain(server: "https://github.com", protocolType: .https) print("\(keychain)") ``` ``` => [ [authenticationType: default, key: kishikawakatsumi, server: github.com, class: internetPassword, protocol: https] [authenticationType: default, key: hirohamada, server: github.com, class: internetPassword, protocol: https] [authenticationType: default, key: honeylemon, server: github.com, class: internetPassword, protocol: https] ] ``` #### Obtaining all stored keys ```swift let keychain = Keychain(server: "https://github.com", protocolType: .https) let keys = keychain.allKeys() for key in keys { print("key: \(key)") } ``` ``` => key: kishikawakatsumi key: hirohamada key: honeylemon ``` #### Obtaining all stored items ```swift let keychain = Keychain(server: "https://github.com", protocolType: .https) let items = keychain.allItems() for item in items { print("item: \(item)") } ``` ``` => item: [authenticationType: Default, key: kishikawakatsumi, server: github.com, class: InternetPassword, protocol: https] item: [authenticationType: Default, key: hirohamada, server: github.com, class: InternetPassword, protocol: https] item: [authenticationType: Default, key: honeylemon, server: github.com, class: InternetPassword, protocol: https] ``` ## Keychain sharing capability If you encounter the error below, you need to add an `Keychain.entitlements`. ``` OSStatus error:[-34018] Internal error when a required entitlement isn't present, client has neither application-identifier nor keychain-access-groups entitlements. ``` Screen Shot 2019-10-27 at 8 08 50 ## Requirements | | OS | Swift | | ---------- | ---------------------------------------------------------- | ------------------ | | **v1.1.x** | iOS 7+, macOS 10.9+ | 1.1 | | **v1.2.x** | iOS 7+, macOS 10.9+ | 1.2 | | **v2.0.x** | iOS 7+, macOS 10.9+, watchOS 2+ | 2.0 | | **v2.1.x** | iOS 7+, macOS 10.9+, watchOS 2+ | 2.0 | | **v2.2.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 2.0, 2.1 | | **v2.3.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 2.0, 2.1, 2.2 | | **v2.4.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 2.2, 2.3 | | **v3.0.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 3.x | | **v3.1.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 4.0, 4.1, 4.2 | | **v3.2.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 4.0, 4.1, 4.2, 5.0 | | **v4.0.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 4.0, 4.1, 4.2, 5.1 | | **v4.1.x** | iOS 8+, macOS 10.9+, watchOS 3+, tvOS 9+, Mac Catalyst 13+ | 4.0, 4.1, 4.2, 5.1 | ## Installation ### CocoaPods KeychainAccess is available through [CocoaPods](http://cocoapods.org). To install it, simply add the following lines to your Podfile: ```ruby use_frameworks! pod 'KeychainAccess' ``` ### Carthage KeychainAccess is available through [Carthage](https://github.com/Carthage/Carthage). To install it, simply add the following line to your Cartfile: `github "kishikawakatsumi/KeychainAccess"` ### Swift Package Manager KeychainAccess is also available through [Swift Package Manager](https://github.com/apple/swift-package-manager/). #### Xcode Select `File > Add Packages... > Add Package Dependency...`, #### CLI First, create `Package.swift` that its package declaration includes: ```swift // swift-tools-version:5.0 import PackageDescription let package = Package( name: "MyLibrary", products: [ .library(name: "MyLibrary", targets: ["MyLibrary"]), ], dependencies: [ .package(url: "https://github.com/kishikawakatsumi/KeychainAccess.git", from: "3.0.0"), ], targets: [ .target(name: "MyLibrary", dependencies: ["KeychainAccess"]), ] ) ``` Then, type ```shell $ swift build ``` ### To manually add to your project 1. Add `Lib/KeychainAccess.xcodeproj` to your project 2. Link `KeychainAccess.framework` with your target 3. Add `Copy Files Build Phase` to include the framework to your application bundle _See [iOS Example Project](https://github.com/kishikawakatsumi/KeychainAccess/tree/master/Examples/Example-iOS) as reference._ ## Author kishikawa katsumi, kishikawakatsumi@mac.com ## License KeychainAccess is available under the MIT license. See the LICENSE file for more info.

近期下载者

相关文件


收藏者