[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-7033":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":25,"hasPages":23,"topics":26,"createdAt":10,"pushedAt":10,"updatedAt":30,"readmeContent":31,"aiSummary":32,"trendingCount":16,"starSnapshotCount":16,"syncStatus":33,"lastSyncTime":34,"discoverSource":35},7033,"keychain-swift","evgenyneu\u002Fkeychain-swift","evgenyneu","Helper functions for saving text in Keychain securely for iOS, OS X, tvOS and watchOS.","",null,"Swift",3010,367,47,68,0,4,5,10,12,71.2,"MIT License",false,"master",true,[27,28,29],"ios","keychain","swift","2026-06-12 04:00:32","# Helper functions for storing text in Keychain for iOS, macOS, tvOS and WatchOS\n\n[![Carthage compatible](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FCarthage-compatible-4BC51D.svg?style=flat)](https:\u002F\u002Fgithub.com\u002FCarthage\u002FCarthage)\n[![CocoaPods Version](https:\u002F\u002Fimg.shields.io\u002Fcocoapods\u002Fv\u002FKeychainSwift.svg?style=flat)](http:\u002F\u002Fcocoadocs.org\u002Fdocsets\u002FKeychainSwift)\n[![Swift Package Manager compatible](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FSwift%20Package%20Manager-compatible-brightgreen.svg)](https:\u002F\u002Fgithub.com\u002Fapple\u002Fswift-package-manager)\n[![License](https:\u002F\u002Fimg.shields.io\u002Fcocoapods\u002Fl\u002FKeychainSwift.svg?style=flat)](http:\u002F\u002Fcocoadocs.org\u002Fdocsets\u002FKeychainSwift)\n[![Platform](https:\u002F\u002Fimg.shields.io\u002Fcocoapods\u002Fp\u002FKeychainSwift.svg?style=flat)](http:\u002F\u002Fcocoadocs.org\u002Fdocsets\u002FKeychainSwift)\n\nThis is a collection of helper functions for saving text and data in the Keychain.\n 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\u002Fwriting text values for specified keys:\n\n ```Swift\nlet keychain = KeychainSwift()\nkeychain.set(\"hello world\", forKey: \"my key\")\nkeychain.get(\"my key\")\n ```\n\nThe Keychain library includes the following features:\n\n * \u003Ca href=\"#usage\">Get, set and delete string, boolean and Data Keychain items\u003C\u002Fa>\n * \u003Ca href=\"#keychain_item_access\">Specify item access security level\u003C\u002Fa>\n * \u003Ca href=\"#keychain_synchronization\">Synchronize items through iCloud\u003C\u002Fa>\n * \u003Ca href=\"#keychain_access_groups\">Share Keychain items with other apps\u003C\u002Fa>\n\n## What's Keychain?\n\nKeychain is a secure storage. You can store all kind of sensitive data in it: user passwords, credit card numbers, secret tokens etc. Once stored in Keychain this information is only available to your app, other apps can't see it. Besides that, operating system makes sure this information is kept and processed securely. For example, text stored in Keychain can not be extracted from iPhone backup or from its file system. Apple recommends storing only small amount of data in the Keychain. If you need to secure something big you can encrypt it manually, save to a file and store the key in the Keychain.\n\n\n## Setup\n\nThere are four ways you can add KeychainSwift to your project.\n\n#### Add source (iOS 7+)\n\nSimply add [KeychainSwiftDistrib.swift](https:\u002F\u002Fgithub.com\u002Fevgenyneu\u002Fkeychain-swift\u002Fblob\u002Fmaster\u002FDistrib\u002FKeychainSwiftDistrib.swift) file into your Xcode project.\n\n#### Setup with Carthage (iOS 8+)\n\nAlternatively, add `github \"evgenyneu\u002Fkeychain-swift\" ~> 24.0` to your Cartfile and run `carthage update`.\n\n#### Setup with CocoaPods (iOS 8+)\n\nIf you are using CocoaPods add this text to your Podfile and run `pod install`.\n\n```\nuse_frameworks!\ntarget 'Your target name'\npod 'KeychainSwift', '~> 24.0'\n```\n\n\n#### Setup with Swift Package Manager (in project)\n\n* In Xcode select *File > Add Packages*.\n* Enter this project's URL: https:\u002F\u002Fgithub.com\u002Fevgenyneu\u002Fkeychain-swift.git\n\n#### Setup with Swift Package Manager (in Swift Package)\n\nIf you're using KeychainSwift in a Swift package, make sure to specify a `name`. This is because SPM cannot automatically resolve a name for a package that has a different Target name in its `Package.swift` (namely `KeychainSwift`) that differs from the repo link (`keychain-swift`).\n\n```\n.package(name: \"KeychainSwift\", url: \"https:\u002F\u002Fgithub.com\u002Fevgenyneu\u002Fkeychain-swift.git\", from: \"24.0.0\")\n```\n\n## Legacy Swift versions\n\nSetup a [previous version](https:\u002F\u002Fgithub.com\u002Fevgenyneu\u002Fkeychain-swift\u002Fwiki\u002FLegacy-Swift-versions) of the library if you use an older version of Swift.\n\n\n## Usage\n\nAdd `import KeychainSwift` to your source code unless you used the file setup method.\n\n#### String values\n\n```Swift\nlet keychain = KeychainSwift()\nkeychain.set(\"hello world\", forKey: \"my key\")\nkeychain.get(\"my key\")\n```\n\n#### Boolean values\n\n\n```Swift\nlet keychain = KeychainSwift()\nkeychain.set(true, forKey: \"my key\")\nkeychain.getBool(\"my key\")\n```\n\n#### Data values\n\n```Swift\nlet keychain = KeychainSwift()\nkeychain.set(dataObject, forKey: \"my key\")\nkeychain.getData(\"my key\")\n```\n\n#### Removing keys from Keychain\n\n```Swift\nkeychain.delete(\"my key\") \u002F\u002F Remove single key\nkeychain.clear() \u002F\u002F Delete everything from app's Keychain. Does not work on macOS.\n```\n\n#### Return all keys\n\n```Swift\nlet keychain = KeychainSwift()\nkeychain.allKeys \u002F\u002F Returns the names of all keys\n```\n\n## Advanced options\n\n\u003Ch3 id=\"keychain_item_access\">Keychain item access\u003C\u002Fh3>\n\nUse `withAccess` parameter to specify the security level of the keychain storage.\nBy default the `.accessibleWhenUnlocked` option is used. It is one of the most restrictive options and provides good data protection.\n\n```\nlet keychain = KeychainSwift()\nkeychain.set(\"Hello world\", forKey: \"key 1\", withAccess: .accessibleWhenUnlocked)\n```\n\nYou 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.\n\nSee the list of all available [access options](https:\u002F\u002Fgithub.com\u002Fevgenyneu\u002Fkeychain-swift\u002Fblob\u002Fmaster\u002FSources\u002FKeychainSwiftAccessOptions.swift).\n\n\n\u003Ch3 id=\"keychain_synchronization\">Synchronizing keychain items with other devices\u003C\u002Fh3>\n\nSet `synchronizable` property to `true` to enable keychain items synchronization across user's multiple devices. The synchronization will work for users who have the \"Keychain\" enabled in the iCloud settings on their devices.\n\nSetting `synchronizable` property to `true` will add the item to other devices with the `set` method and obtain synchronizable items with the `get` command. Deleting a synchronizable item will remove it from all devices.\n\nNote that you do NOT need to enable iCloud or Keychain Sharing capabilities in your app's target for this feature to work.\n\n\n```Swift\n\u002F\u002F First device\nlet keychain = KeychainSwift()\nkeychain.synchronizable = true\nkeychain.set(\"hello world\", forKey: \"my key\")\n\n\u002F\u002F Second device\nlet keychain = KeychainSwift()\nkeychain.synchronizable = true\nkeychain.get(\"my key\") \u002F\u002F Returns \"hello world\"\n```\n\nWe could not get the Keychain synchronization work on macOS.\n\n\n\u003Ch3 id=\"keychain_access_groups\">Sharing keychain items with other apps\u003C\u002Fh3>\n\nIn order to share keychain items between apps on the same device they need to have common *Keychain Groups* registered in *Capabilities > Keychain Sharing* settings. [This tutorial](http:\u002F\u002Fevgenii.com\u002Fblog\u002Fsharing-keychain-in-ios\u002F) shows how to set it up.\n\nUse `accessGroup` property to access shared keychain items. In the following example we specify an access group \"CS671JRA62.com.myapp.KeychainGroup\" that will be used to set, get and delete an item \"my key\".\n\n```Swift\nlet keychain = KeychainSwift()\nkeychain.accessGroup = \"CS671JRA62.com.myapp.KeychainGroup\" \u002F\u002F Use your own access goup\n\nkeychain.set(\"hello world\", forKey: \"my key\")\nkeychain.get(\"my key\")\nkeychain.delete(\"my key\")\nkeychain.clear()\n```\n\n*Note*: there is no way of sharing a keychain item between the watchOS 2.0 and its paired device: https:\u002F\u002Fforums.developer.apple.com\u002Fthread\u002F5938\n\n### Setting key prefix\n\nOne can pass a `keyPrefix` argument when initializing a `KeychainSwift` object. The string passed in `keyPrefix` argument will be used as a prefix to **all the keys** used in `set`, `get`, `getData` and `delete` methods. Adding a prefix to the keychain keys can be useful in unit tests. This prevents the tests from changing the Keychain keys that are used when the app is launched manually.\n\nNote that `clear` method still clears everything from the Keychain regardless of the prefix used.\n\n\n```Swift\nlet keychain = KeychainSwift(keyPrefix: \"myTestKey_\")\nkeychain.set(\"hello world\", forKey: \"hello\")\n\u002F\u002F Value will be stored under \"myTestKey_hello\" key\n```\n\n### Check if operation was successful\n\nOne can verify if `set`, `delete` and `clear` methods finished successfully by checking their return values. Those methods return `true` on success and `false` on error.\n\n```Swift\nif keychain.set(\"hello world\", forKey: \"my key\") {\n  \u002F\u002F Keychain item is saved successfully\n} else {\n  \u002F\u002F Report error\n}\n```\n\nTo get a specific failure reason use the `lastResultCode` property containing result code for the last operation. See [Keychain Result Codes](https:\u002F\u002Fdeveloper.apple.com\u002Fdocumentation\u002Fsecurity\u002F1542001-security_framework_result_codes).\n\n```Swift\nkeychain.set(\"hello world\", forKey: \"my key\")\nif keychain.lastResultCode != noErr { \u002F* Report error *\u002F }\n```\n\n### Returning data as reference\n\nUse the `asReference: true` parameter to return the data as reference, which is needed for  [NEVPNProtocol](https:\u002F\u002Fdeveloper.apple.com\u002Fdocumentation\u002Fnetworkextension\u002Fnevpnprotocol).\n\n```Swift\nlet keychain = KeychainSwift()\nkeychain.set(dataObject, forKey: \"my key\")\nkeychain.getData(\"my key\", asReference: true)\n```\n\n## Using KeychainSwift from Objective-C\n\n[This manual](https:\u002F\u002Fgithub.com\u002Fevgenyneu\u002Fkeychain-swift\u002Fwiki\u002FUsing-KeychainSwift-in-Objective-C-project) describes how to use KeychainSwift in Objective-C apps.\n\n## ❗️Known critical issue - call to action❗️\n\nIt [has been reported](https:\u002F\u002Fgithub.com\u002Fevgenyneu\u002Fkeychain-swift\u002Fissues\u002F15) that the library sometimes returns `nil`  instead of the stored Keychain value. It may be connected with [the Keychain issue](https:\u002F\u002Fforums.developer.apple.com\u002Fthread\u002F4743) reported on Apple developer forums. The issue is random and hard to reproduce. If you experienced this problem feel free to create an issue and share your story, so we can find solutions.\n\n## Video tutorial\n\nThanks to Alex Nagy from [rebeloper.com](https:\u002F\u002Frebeloper.com\u002F) for creating this two-part [video tutorial](https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=1R-VIzjD4yo&list=PL_csAAO9PQ8bLfPF7JsnF-t4q63WKZ9O9).\n\n\u003Ca href=\"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=1R-VIzjD4yo&list=PL_csAAO9PQ8bLfPF7JsnF-t4q63WKZ9O9\" target=\"_blank\">\u003Cimg src='graphics\u002Fkeychain_swift_video_tutorial.jpg' width='800' alt='Keychain Swift video tutorial'>\u003C\u002Fa>\n\n## Demo app\n\n\u003Cimg src=\"https:\u002F\u002Fraw.githubusercontent.com\u002Fevgenyneu\u002Fkeychain-swift\u002Fmaster\u002Fgraphics\u002Fkeychain-swift-demo-3.png\" alt=\"Keychain Swift demo app\" width=\"320\">\n\n## Alternative solutions\n\nHere are some other Keychain libraries.\n\n* [DanielTomlinson\u002FLatch](https:\u002F\u002Fgithub.com\u002FDanielTomlinson\u002FLatch)\n* [jrendel\u002FSwiftKeychainWrapper](https:\u002F\u002Fgithub.com\u002Fjrendel\u002FSwiftKeychainWrapper)\n* [kishikawakatsumi\u002FKeychainAccess](https:\u002F\u002Fgithub.com\u002Fkishikawakatsumi\u002FKeychainAccess)\n* [matthewpalmer\u002FLocksmith](https:\u002F\u002Fgithub.com\u002Fmatthewpalmer\u002FLocksmith)\n* [s-aska\u002FKeyClip](https:\u002F\u002Fgithub.com\u002Fs-aska\u002FKeyClip)\n* [yankodimitrov\u002FSwiftKeychain](https:\u002F\u002Fgithub.com\u002Fyankodimitrov\u002FSwiftKeychain)\n\n## Thanks 👍\n\n* The code is based on this example: [https:\u002F\u002Fgist.github.com\u002Fs-aska\u002Fe7ad24175fb7b04f78e7](https:\u002F\u002Fgist.github.com\u002Fs-aska\u002Fe7ad24175fb7b04f78e7)\n* Thanks to [diogoguimaraes](https:\u002F\u002Fgithub.com\u002Fdiogoguimaraes) for adding Swift Package Manager setup option.\n* Thanks to [glyuck](https:\u002F\u002Fgithub.com\u002Fglyuck) for taming booleans.\n* Thanks to [pepibumur](https:\u002F\u002Fgithub.com\u002Fpepibumur) for adding macOS, watchOS and tvOS support.\n* Thanks to [ezura](https:\u002F\u002Fgithub.com\u002Fezura) for iOS 7 support.\n* Thanks to [mikaoj](https:\u002F\u002Fgithub.com\u002Fmikaoj) for adding keychain synchronization.\n* Thanks to [tcirwin](https:\u002F\u002Fgithub.com\u002Ftcirwin) for adding Swift 3.0 support.\n* Thanks to [Tulleb](https:\u002F\u002Fgithub.com\u002FTulleb) for adding Xcode 8 beta 6 support.\n* Thanks to [CraigSiemens](https:\u002F\u002Fgithub.com\u002FCraigSiemens) for adding Swift 3.1 support.\n* Thanks to [maxkramerbcgdv](https:\u002F\u002Fgithub.com\u002Fmaxkramerbcgdv) for fixing Package Manager setup in Xcode 8.2.\n* Thanks to [elikohen](https:\u002F\u002Fgithub.com\u002Felikohen) for fixing concurrency issues.\n* Thanks to [beny](https:\u002F\u002Fgithub.com\u002Fbeny) for adding Swift 4.2 support.\n* Thanks to [xuaninbox](https:\u002F\u002Fgithub.com\u002Fxuaninbox) for fixing watchOS deployment target for Xcode 10.\n* Thanks to [schayes04](https:\u002F\u002Fgithub.com\u002Fschayes04) for adding Swift 5.0 support.\n* Thanks to [mediym41](https:\u002F\u002Fgithub.com\u002Fmediym41) for adding ability to return data as reference.\n* Thanks to [AnthonyOliveri](https:\u002F\u002Fgithub.com\u002FAnthonyOliveri) for adding ability to run unit tests from Swift Package Manager.\n* Thanks to [philippec](https:\u002F\u002Fgithub.com\u002Fphilippec) for removing deprecated access options.\n* Thanks to [lucasmpaim](https:\u002F\u002Fgithub.com\u002Flucasmpaim) for adding ability to return the names of all keys.\n\n\n\n## Feedback is welcome\n\nIf you notice any issue, got stuck or just want to chat feel free to create an issue. We will be happy to help you.\n\n## License\n\nKeychain Swift is released under the [MIT License](LICENSE).\n","keychain-swift 是一个用于在 iOS、macOS、tvOS 和 watchOS 上安全存储文本的辅助函数库。它简化了 Apple Keychain API 的使用，提供了简洁的读写接口来处理字符串、布尔值和 Data 类型的数据，并支持设置访问权限级别、通过 iCloud 同步数据以及与其他应用共享 Keychain 项。适用于需要安全保存敏感信息如密码、信用卡号等的应用场景，确保这些信息只能被授权的应用访问且无法从备份或文件系统中提取。",2,"2026-06-11 03:10:13","top_language"]