Skip to content

Instantly share code, notes, and snippets.

@Ilesh
Last active March 14, 2021 14:34
Show Gist options
  • Save Ilesh/63f6ca0acde8923514529c9e0022d97f to your computer and use it in GitHub Desktop.
Save Ilesh/63f6ca0acde8923514529c9e0022d97f to your computer and use it in GitHub Desktop.
For save, load , and delete Keychain value from the iOS and Make apps. If you find helpful this class please share and give star so others can find it πŸ‘πŸ‘πŸ‘πŸ‘πŸ‘ !!!!
//
// IPKeyChain.swift
//
//
// Created by Ilesh's 2020 on 25/05/20.
// Copyright Β© 2020 Ilesh-Panchal All rights reserved.
//
//HOW TO USE?
//
//For save values
// IPKeyChain.saveValue(service: IPKeyChain.services, account: IPKeyChain.apple_Id, data: "xyzId")
//
//For retrive or load
// IPKeyChain.loadPassword(service: IPKeyChain.services, account: IPKeyChain.apple_Id)
//
//For remove or delete
// IPKeyChain.removeValue(service: IPKeyChain.services, account: IPKeyChain.apple_Id)
//
//Thank you!
import UIKit
class IPKeyChain: NSObject {
//SERVICE
static let services : String = "com.app.your-bundle-id" // Just for make it more unique.
//SAMPLE KEY
static let apple_Id : String = "APPLE_ID"
static let apple_account_name : String = "APPLE_NAME"
static let apple_account_email : String = "APPLE_EMAIL"
class func updateValue(service: String, account: String, data: String) {
guard let dataFromString = data.data(using: .utf8, allowLossyConversion: false) else {
return
}
let status = SecItemUpdate(modifierQuery(service: service, account: account), [kSecValueData: dataFromString] as CFDictionary)
checkError(status)
}
class func removeValue(service: String, account: String) {
let status = SecItemDelete(modifierQuery(service: service, account: account))
checkError(status)
}
class func saveValue(service: String, account: String, data: String) {
guard let dataFromString = data.data(using: .utf8, allowLossyConversion: false) else {
return
}
let keychainQuery: [CFString: Any] = [kSecClass: kSecClassGenericPassword,
kSecAttrService: service,
kSecAttrAccount: account,
kSecValueData: dataFromString]
let status = SecItemAdd(keychainQuery as CFDictionary, nil)
checkError(status)
}
class func loadPassword(service: String, account: String) -> String? {
var dataTypeRef: CFTypeRef?
let status = SecItemCopyMatching(modifierQuery(service: service, account: account), &dataTypeRef)
if status == errSecSuccess,
let retrievedData = dataTypeRef as? Data {
return String(data: retrievedData, encoding: .utf8)
} else {
checkError(status)
return nil
}
}
fileprivate static func modifierQuery(service: String, account: String) -> CFDictionary {
let keychainQuery: [CFString: Any] = [kSecClass: kSecClassGenericPassword,
kSecAttrService: service,
kSecAttrAccount: account,
kSecReturnData: kCFBooleanTrue]
return keychainQuery as CFDictionary
}
fileprivate static func checkError(_ status: OSStatus) {
if status != errSecSuccess {
if #available(iOS 11.3, *),
let err = SecCopyErrorMessageString(status, nil) {
print("Operation failed: \(err)")
} else {
print("Operation failed: \(status). Check the error message through https://osstatus.com.")
}
}
}
}
extension Data {
init<T>(from value: T) {
var value = value
self.init(buffer: UnsafeBufferPointer(start: &value, count: 1))
}
func to<T>(type: T.Type) -> T {
return self.withUnsafeBytes { $0.load(as: T.self) }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment