jrendel / swiftkeychainwrapper Goto Github PK
View Code? Open in Web Editor NEWA simple wrapper for the iOS Keychain to allow you to use it in a similar fashion to User Defaults. Written in Swift.
License: MIT License
A simple wrapper for the iOS Keychain to allow you to use it in a similar fashion to User Defaults. Written in Swift.
License: MIT License
In this app I'm working on we are using Apple's KeychainItemWrapper to interact with the keychain, but we would like to move from that implementation to SwiftKeychainWrapper. Is it possible to access the existing keychain data with SwiftKeychainWrapper?
Please can you integrate this project in cocoa pods for tvOS. This helper works flawlessly on tvOS but without the cocoaPod integration its a bit of a hassle when having a universal iOS and tvOS project.
Thanks for the quick swift 3 update. Could you please do the following syntax changes for the next update to make it even more swift 3 like and closer to NSUserDefaults.
Change the singleton access to either default, standard or shared. So instead of
KeychainWrapper.defaultKeychainWrapper.set(...)
it reads
KeychainWrapper.default.set(...)
or
KeychainWrapper.standard.set(...)
or
KeychainWrapper.shared.set(...)
Change the remove method from
...remove(key: ....)
to
...removeObject(forKey: ...)
Flexibility could be provided by supporting the other possible values (internet password, certificate, key, identity). An enum could be used to wrap the CFString constant values and the KeychainWrapper public methods could either be overloaded or take an optional parameter.
To take this even further, an "options" type could be used as a parameter to wrap the SecClass and any other useful options, such as whether the device must be unlocked for access and whether TouchID is needed to retrieve the item.
I've begun implementation of these features in my own fork and can provide samples (or a pull request) if you're open to these ideas.
I'm getting some strange behavior when accessing data. I have a static method that I use to retrieve a stored auth token for an API call. This static method is called a couple times and returns the data I expect. From one of my view controllers though it's returning nil.
I make the exact same call for the exact same keys. Two calls return data and the last one does not. I'm getting a return status of -34018. I'm not sure what that error code is.
If I do the following code:
KeychainWrapper.serviceName = "com.yaddayadda.whatever"
if KeychainWrapper.setString(tokenField.stringValue, forKey: "apiKey") {
println("Saved \(tokenField.stringValue) to apiKey")
} else {
println("Failed to save apiKey: \(tokenField.stringValue)")
}
if KeychainWrapper.setString(urlField.stringValue, forKey: "apiURL") {
println("Saved \(urlField.stringValue) to apiURL")
} else {
println("Failed to save apiURL: \(urlField.stringValue)")
}
The apiURL
will always fail no matter what. Is it just that this lib only allows saving of a single item?
Hello, after last update - i realized that code is not compiling for iOS7
It seems it has converted properly on XCode 8 for Swift 3.
However there are some warnings as XCode issues them for unused results from function calls now.
e.g. "Result of call to 'deleteKeychainSecClass' is unused"
Cheers
Currently, the KeychainWrapper.swift
uses Data
type as a "key" to store records. We got our head scratching for quite some time and we could not find any actual benefit of the current code.
// Uniquely identify the account who will be accessing the keychain
let encodedIdentifier: Data? = key.data(using: String.Encoding.utf8)
// ...
keychainQueryDictionary[SecAttrAccount] = encodedIdentifier
Why don't you simply use String
, like Apple does?
You use String
everywhere up until that point, then you convert it to Data
just before storing the record...
When I try 'pod install'
[!] Unable to satisfy the following requirements:
SwiftKeychainWrapper (~> 2.0)
required by Podfile
None of your spec sources contain a spec satisfying the dependency: SwiftKeychainWrapper (~> 2.0)
.
I of course tried 'pod repo update'.
Hi there,
My code has been working fine until now, suddenly these lines returns false:
let ops: Bool = KeychainWrapper.defaultKeychainWrapper.set(ops, forKey: "ops")
let jop: Bool = KeychainWrapper.defaultKeychainWrapper.set(jop, forKey: "jop")
I use cocoapods, and this in the Podfile:
pod 'SwiftKeychainWrapper', :git => 'https://github.com/jrendel/SwiftKeychainWrapper.git', :branch => 'master'
Any ideas?
When trying to add SwiftKeychainWrapper to a WatchKit Extension target using Cocoapods an error occurs stating the following:
[!] The platform of the target
cosy WatchKit Extension
(watchOS 2.0) is not compatible withSwiftKeychainWrapper (1.0.11)
, which does not supportwatchos
.
Definition used in the Podfile
target 'cosy WatchKit Extension' do
platform :watchos, '2.0'
pod 'SwiftKeychainWrapper'
end
I have installed branch Swift2.3 via cocoa pods.
I am calling the following code:
let saveSuccessful: Bool = KeychainWrapper.standard.set("username123", forKey: "username")
But saveSuccesful
is always returning false. I have tried with different strings. I have also tried calling:
let retrievedString: String? = KeychainWrapper.standard.string(forKey: "username")
To double check it's not just the wrong value being returned but retrievedString
is always nil.
Am I doing something wrong? Any help would be appreciated.
MIT copyright
My understanding is that the MIT copyright statement included in the project needs to be included in the code to be in effect, as it stands the code is copyrighted by yourself with no mention of the MIT copyright.
Can you add support for saving to a specific keychain access group? This way we can share the keychain between multiple apps and/or extensions.
Also, it's very inconvenient that accessGroup
is a class property - what if you need to access several keychains (for several access groups)?
When used:
KeychainWrapper.accessGroup = "..."
let c1 = KeychainWrapper.dataForKey("CustomerToken")
nil
is stored in c1
But when I use
func getFromKeychain(itemKey: String) -> NSData? {
let keychainAccessGroupName = "..."
let queryLoad: [String: AnyObject] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: itemKey,
kSecReturnData as String: kCFBooleanTrue,
kSecMatchLimit as String: kSecMatchLimitOne,
kSecAttrAccessGroup as String: keychainAccessGroupName
]
var result: AnyObject?
let resultCodeLoad = withUnsafeMutablePointer(&result) {
SecItemCopyMatching(queryLoad, UnsafeMutablePointer($0))
}
if resultCodeLoad == noErr {
if let result = result as? NSData {
return result
}
} else {
print("Error loading from Keychain: \(resultCodeLoad)")
}
return nil
}
Correct data is returned from method.
Hi @jrendel ,
I have a problem with saving values to Keychain, below is the line I'm using, and it always returns false in xCode8 and Swift2.3 (I can't use Swift 3 at the moment because some other frameworks are not updated)
Just to mention, it all worked with xCode7 and Swift2.2 on iOS9.3 simulator, but now I'm using iOS10 simulator, maybe this could be the issue? (downloading 9.3 simulators at the moment)
let isSaveSuccessfulToken: Bool = KeychainWrapper.defaultKeychainWrapper().setString(token, forKey: "token")
I'm using Carthage and I tried with the following
github "jrendel/SwiftKeychainWrapper"
github "jrendel/SwiftKeychainWrapper" "master"
github "jrendel/SwiftKeychainWrapper" == 2.1.0
github "jrendel/SwiftKeychainWrapper" "Swift2.3"
all compiled to Swift2.3 using
carthage update --platform iOS --toolchain com.apple.dt.toolchain.Swift_2_3 SwiftKeychainWrapper
which builds successfully (also used with some other frameworks that work now)
Tnx
I'm running Xcode 8.0 (8A218a)
I downloaded the devel branch and opened up the xcodeproj file
Everything builds fine, but when I run the tests I get 34 failures. Basically, it looks like nothing is getting set.
Thanks!
When application in background state, hasValueForKey
return nil
therefore it is not possible to query for existing value when app is in background state.
Is there any workaround for this or am I doing something wrong?
Getting OSStatus error -34018 on unit tests while trying to finalize the Swift 3.0 version of the library, so I'm opening this to track what I find.
So far some info here at the end: https://forums.developer.apple.com/thread/4743
Suggested workaround: https://forums.developer.apple.com/message/170381#170381
KeychainWrapper.defaultKeychainWrapper.set("ads", forKey: "boh")
print(KeychainWrapper.defaultKeychainWrapper.string(forKey: "boh"))
That code actually prints nil.
Thanks for your great helper, been using it for ages now and it works great
Installing SwiftKeychainWrapper 2.2.1 (was 2.0.0)
Why is a minor update breaking our build by changing the library's interface?
Shouldn't changes like this result to major number changing?
The process is described here: http://guides.cocoapods.org/making/getting-setup-with-trunk.html
Hey, your library is really interesting.
The only problem I found was the README.md
, which lacks an Installation Section
I created this iOS Open source Readme Template so you can take a look on how to easily create an Installation Section
If you want, I can help you to organize the lib.
What are your thoughts? ๐
I'm seeing an odd, intermittent error every once in a while. I'll try to retrieve a value as the app is launching (in application(_:... didFinishLaunchingWithOptions)
) and just as it fails to retrieve the value I'll consistently get an error printed out to the console that I don't see otherwise making me believe the two are related. Here is the error:
2016-11-25 12:07:01.600167 (MY_APP_IDENTIFIER)[7172:1224012] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2016-11-25 12:07:01.609110 (MY_APP_IDENTIFIER)[7172:1224012] [MC] Reading from public effective user settings.
And sometimes (I can't seem to find a pattern) this one is printed as well:
2016-11-25 12:40:37.032139 (MY_APP_IDENTIFIER)[7195:1232649] [MC] Invalidating cache
I've been looking into this and people are attributing this message to either user permissions settings or app groups (neither of which I am using.) Have you seen this happening at all? Ideas? Like I said, it's intermittent and extremely difficult to try to debug and is causing my users quite a bit of a headache as it automatically logs them out of my app.
Please upgrade this project to swift 3 ASAP, it only will take a few minutes. Currently this breaks CocoaPod integration with Swift 3 and xCode 8.
As you know errno provides error code of the latest system code failed. So in the following method:
public class func dataForKey(keyName: String) -> NSData? { ...
probably this was meant here:
return status == errSecSuccess ? result as? NSData : nil
instead of this:
return status == noErr ? result as? NSData : nil
My understanding is convention dictates this should be in the form XXXKeyChainWrapper where XXX is a unique prefix associated with the developer. While the name as it stands is descriptive it is not conventional. Really nice piece of code and would like to be able to use it but site naming conventions preclude this, any chance you will consider renaming it?
Haven't fully investigated but there is a rather odd bug with this Wrapper. Some phones will save to keychain using SwiftKeychainWrapper, others will not. There is no correlation between phones or versions, some iPhones 5s's the wrapper works, other it does not. This applies to all devices - 6, 6 plus, 4s.
To further describe - Saving to keychain in our test group worked for an iPhone 5s on 8.1.3 - on another 5s on 8.1.3 it did not. One iPhone 6 it did not work for (also on 8.1.3), on an iPhone 5 on 8.1.2 it did work.
Bug is also not related to settings or anything related to settings within said app, it is isolated to SwiftKeychainWrapper.
Is there a reason to restrict this to iOS? Can't it pretty easily support macOS as well?
Hello there,
following some tutorial videos I copied the KeychainWrapper.swift file to my project and started using the provided functions to store some strings. Everything works fine but now I wonder about the need for the security framework which I didn't import manually. Is this something I still need to do in swift? I can Cmd+click those kSec keys in the wrapper and it sends me to the security framework - does this mean it's "built in" into swift now or something like that?
If I do need that framework why does it work right now "without" it? Are my strings saved but not encrypted or something like that?
Btw: I asked that on SO as well but the answers weren't completely satisfying thats why I ask here now.
Thanks a lot in advance
Is it possible to set object in Keychain with Swift 3, this is how I used it before:
KeychainWrapper.defaultKeychainWrapper().setObject(expiresIn, forKey: "expiresInDate")
is there something like:
KeychainWrapper.standard.set(expiresIn, forKey: "expiresInDate")
How can this be a Swift rewrite when you're still using the main ObjC method inside of it.
return KeychainObjcWrapper.dataForDictionary(keychainQueryDictionary)
Hey,
just wanted to notify you that your podspec is broken for latest commits.
Cocoapods: 0.36.3
XCode: 6.3
Swift: 1.2
This project support cocoapod and it's good.
And then why not adding carthage support?
When packaging up a release IPA (IE: for testflight) KeychainWrapper.stringForKey() returns a nil value. It passes without error, but the value is blank.
For instance:
KeychainWrapper.setString("APPLE", forKey: "FRUIT")
var fruit = KeychainWrapper.stringForKey("FRUIT")
var alert:UIAlertView = UIAlertView(title: "FRUIT", message: "\(fruit)", delegate: self, cancelButtonTitle: "Ok")
alert.show()
Took a lot of searching, but I stumbled across: http://stackoverflow.com/questions/26355630/swift-keychain-and-provisioning-profiles
Disabling the optimizations for the release target remedied the problem, but I am wondering if there is something that can be done to fix whatever is breaking when optimized away. (Might just have to wait for an apple fix?)
When I open the app, In App Delegate
I can see that there is a value in Keychain
and KeychainWrapper
is successfully fetching it.
But when I try to remove it [ Using that specific key ] it always return false. So I tried removeAllKeys
method that also returns nil. I have tried re-booting my system, tried in different computers. Don't know what's happening in here.
It's a Cocoa App
. Deployment Target : 10.10
if let _ = KeychainWrapper.defaultKeychainWrapper().stringForKey(UserDefaults.TokenSet_Secret.rawValue)
{
// Always here - Value is there
}
else
{
//
}
let success = KeychainWrapper.defaultKeychainWrapper().removeObjectForKey(UserDefaults.TokenSet_Secret.rawValue)
if success {
// Dismiss
self.delegate?.clickedOnDismiss()
dismissController(self)
}
else {
// Always comes here :(
// Show Alert
self.presentAlertController(UserConstants.alertTitle_Oops, message: UserConstants.WritingTweets.CoultNotGetToken.rawValue)
}
Please guide me, and let me know if I miss anything.
There is no pod spec for SwiftKeychainWrapper 2.1.0 (https://github.com/CocoaPods/Specs/tree/master/Specs/SwiftKeychainWrapper) in CocoaPods.
Trying to get pod 'SwiftKeychainWrapper', '~> 2.1'"
(or explicitly '2.1.0') with CP 1.0 or 1.1.0.rc2 fails with:
[!] Unable to satisfy the following requirements:
- SwiftKeychainWrapper (~> 2.1)
required by Podfile
None of your spec sources contain a spec satisfying the dependency: SwiftKeychainWrapper (~> 2.1)
.
Hey,
So I have done some more testing with your updated version and its not saving data anymore.
It returns a successful bool on the set method but on next launch all data is gone again. So ...object(forKey: ...) doesnt work anymore.
Have you made any changes because when I upgraded the project to swift 3 myself I did not have that problem.
Whats going on?
the usage in current docs is all depreciated...
what's the correct current usage?
i'm not sure what you mean by "access via keychainWrapper.standardKeychainAccess()"
First, congrats for the wrapper. Simple and efficient.
I just missed out one function: a removeAllKeys() function that would erase all Keychain items. That is very useful to clean the Keychain on the app first run.
it still reads:
remove(key: )
should read:
removeObject(forKey: )
I am using Xcode8.0 . When I run code on simulator, the key doesn't store. On rum iPhone it works fine.
I want to save a JSON object in Keychain with DataType JSON without changing it to string.
Please help how to save a json object in keychain using this library?
The current version (2.2.0) has not been updated on cocoapods (https://cocoapods.org/pods/SwiftKeychainWrapper) and cannot be installed using pods for now. Please update the version from 2.0 to 2.2 over there.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.