swift之保存数据到keychain
访问KeyChain
1.在mac上按下 Command+Space 输入Keychain Access
2.在终端输入security find-generic-password -help
读取配置文件授权
cd ~/Desktop
//ios产看应用的授权来发现他需要的访问类型,应用的授权以编码的形式保存在对应的签名的配置文件中,嘉定已经创建一个配置文件,名为KeycahinTest_Dev.mobileprovision并且保存在桌面
security cms -D -i KeychainTest_Dev.mobileprovision | grep -A12 “Entitlements”

keychain-acess-groups 定义同一开发者开发的应用所共享的钥匙串群组标识
在ios应用中使用key-chain
1.引入框架 import Security 修改Build Setting中Capabilities支持
使用Touch ID验证用户
1.引入LocalAuthentication框架
2.创建LAContext类的实例
3.调用LAContext实例的canEvaluatePolicy:(LAPolicyDeviceOwnerAuthenticaitonWithBiometrics)error:方法确认Touch Id是否可用
4.Touchid可用则使用LAContext的evaluatePolicy:localizedReason:reply:方法验证TouchID的用户
import UIKit
import LocalAuthentication
class ViewController: UIViewController {
@IBOutlet weak var buttonCheckTouchId: UIButton!
@IBOutlet weak var buttonUseTouchId: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
//touchId是否可用
func checkTouchIdAvailability(sender: AnyObject) {
let context = LAContext()
var error: NSError?
let isTouchIdAvailable = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)
buttonUseTouchId.isEnabled = isTouchIdAvailable
//Touch ID不可用的
if isTouchIdAvailable == false {
let alertController = UIAlertController(title: "Touch Id", message: "TocuhId is not available", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alertController, animated: true, completion: nil)
}
}
@IBAction func userTouchId(sender: AnyObject) {
let context = LAContext()
var error: NSError?
//localizedReason标识在应用中请求用户提供指纹进行验证的文本提示内容
let reason = "please authenticate with Touch id to access your private information"
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason, reply: { (success: Bool, error: NSError!) in
if success{
//用户已经通过验证
}else{
//用户为通过验证
}
} as! (Bool, Error?) -> Void)
}
}
在钥匙串中存储数据是以键值对方式存储的
kSecCalss 安全存储字符串数据
kSecClassGenericPassword
kSecAttrService 应用bundle标识字符窜
kSecAttrAcount 存储数据的对应键,可以是任意有意义的字符串
kSecValueData 该键的值是一个NSData实例,存放kSecAttrAccount对应的数据
OSStatus类型在xcode中Commond+ shilft + O 输入SecBase 查找errSecSucces,可以看到OSStatus类型
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
//保存到钥匙串
func savetoKeyChain() {
let key = "Full Name"
let value = "Steve Jobs"
let valueData = value.data(using: .utf8, allowLossyConversion: false)
let service = Bundle.main.bundleIdentifier!
let secItem = [
kSecClass as NSString : kSecClassGenericPassword as NSString,
kSecAttrService as NSString : service,
kSecAttrAccount as NSString : key,
kSecValueData as NSString : valueData!
] as NSDictionary
var result:CFTypeRef?
let status = Int(SecItemAdd(secItem, &result))
switch status {
case Int(errSecSuccess):
print("Successfully stored the value")
case Int(errSecDuplicateItem):
print("this item is already saved, Cannot duplicate it")
default:
print("An error occurred with code\(status)")
}
}
//在钥匙串中查找数据
/****查找钥匙串h中的值
SecItemCopyMatching(CFDictionary, UnsafeMutablePointer<CFTypeRef?>?)
1.构建一个字典,天剑kSecClass键,设置键的值来标识查找项的类型。 例如:kSecClassGenericPassword
2.添加kSecAttrService键。取值为查找项服务的字符串,所有应用应采用相同的值,这样任意应用写到钥匙串的数据,其他应用可以访问
3.添加kSecAttrAccount键,取值为钥匙串已存储项对应的键
4.获取特定属性的值:创建修改日期,需要向字典中添加kSecReturnAttributes,并将其值设置为kCFBooleanTrue
如果设置CFDictionary键为 kSecReturnAttributes键,则返回值为nil或CFDictionaryRef隐含类型
如果为kSecReturnData添加到字典,返回类型是CDDataRef
**/
func queryFromKeyChain(){
let keyToSearchfor = "Full Name"
let service = Bundle.main.bundleIdentifier
let query = [kSecClass as NSString : kSecClassGenericPassword as NSString,
kSecAttrAccount as NSString : keyToSearchfor,
kSecAttrService as NSString : service,
kSecReturnAttributes as NSString : kCFBooleanTrue
] as NSDictionary
var valueAttributes : CFTypeRef?
let results = Int(SecItemCopyMatching(query, &valueAttributes))
if results == Int(errSecSuccess) {
let attributes = valueAttributes! as! NSDictionary
let key = attributes[kSecAttrAccount as NSString] as! String
let accessGroup = attributes[kSecAttrAccessGroup as NSString] as! String
let createDate = attributes[kSecAttrCreationDate as NSString] as! NSDate
let modifiedDate = attributes[kSecAttrModificationDate as NSString] as! NSDate
let serviceValue = attributes[kSecAttrService as NSString] as! String
}else{
print("Error happened with code:\(results)")
}
}
func queryDataFromKeyChain(){
let keyToSearchfor = "Full Name"
let service = Bundle.main.bundleIdentifier
let query = [kSecClass as NSString : kSecClassGenericPassword as NSString,
kSecAttrAccount as NSString : keyToSearchfor,
kSecAttrService as NSString : service,
kSecReturnData as NSString : kCFBooleanTrue
] as NSDictionary
var returnedData : CFTypeRef?
let results = Int(SecItemCopyMatching(query, &returnedData))
if results == Int(errSecSuccess) {
let data = returnedData! as! Data
let value = String(data: data, encoding: .utf8)
}else{
print("Error happened with code:\(results)")
}
}
func updateKeyChain() {
let keyToSearchFor = "Full Name"
let service = Bundle.main.bundleIdentifier
let query = [kSecClass as NSString:
kSecClassGenericPassword as NSString,
kSecAttrService as NSString: service,
kSecAttrAccount as NSString : keyToSearchFor,] as NSDictionary
var result: CFTypeRef?
let found = Int(SecItemCopyMatching(query, &result))
if found == Int(errSecSuccess){
let newData = "Mark tremonti".data(using: .utf8, allowLossyConversion: false)
let update = [kSecValueData as NSString: newData!,
kSecAttrComment as NSString : "my comments"] as NSDictionary
let updated = Int(SecItemUpdate(query, update))
if updated == Int(errSecSuccess){
print("Successfully updated the existing value")
readExistingValue();
} else {
print("failed to update the value. error = \(updated)")
}
}else{
print("error happened. Code=\(found)")
}
}
//更新多个值
func readExistingValue() {
}
swift之保存数据到keychain的更多相关文章
- EasyUI使用JSON保存数据
		目前来说,使用JSON保存数据比较方便,前台可以不用Test.aspx 页面,可以直接用Html页面,使用.aspx页面的弊端就不在这里熬述. 具体步骤如下: 1.新建一个Html页面,命名为Test ... 
- AC中保存数据与查询数据
		//保存数据 hui.ajax(function (ret, err) { }, url, {values: {t:"test",m:"Search",c:&q ... 
- SpringMVC保存数据到mysql乱码问题
		SpringMVC保存数据到mysql乱码问题 乱码问题常见配置 一.web.xml配置过滤器 <filter> <filter-name>encoding-filter< ... 
- Android开发学习---android下的数据持久化,保存数据到rom文件,android_data目录下文件访问的权限控制
		一.需求 做一个类似QQ登录似的app,将数据写到ROM文件里,并对数据进行回显. 二.截图 登录界面: 文件浏览器,查看文件的保存路径:/data/data/com.amos.datasave/fi ... 
- android fragment 的用法以及与activity的交互和保存数据的方法,包括屏幕切换(转载)!
		转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37992017 1.管理Fragment回退栈 类似与Android系统为Acti ... 
- Post model至Web Api创建或是保存数据
		前一篇<Post model至Web Api>http://www.cnblogs.com/insus/p/4343538.html中,使用Post来从Web Api获取数据.由于Post ... 
- SharedPreferences保存数据
		1.使用SharedPreferences保存数据方法如下: //实例化SharedPreferences对象(第一步) SharedPreferences mySharedPreferences= ... 
- Android 分享一个SharedPreferences的工具类,方便保存数据
		我们平常保存一些数据,都会用到SharedPreferences,他是保存在手机里面的,具体路径是data/data/你的包名/shared_prefs/保存的文件名.xml, SharedPrefe ... 
- mysql保存数据提示1366 Incorrect string value: ‘\xF0\x9F\x98\x8A\xF0\x9F…’ 解决
		在保存数据时我们如果页面编辑与数据库字段编码不一样或字符集超出你了mysql数据库中的字符类型就有可能出一\\xF0\\x9F\\x98\\x8A\\xF0\\x9F提示了,下面我来简单的解决方法. ... 
随机推荐
- 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:继承的应用
			class Array{ // 表示数组 private int temp[] ; // 整型数组 private int foot ; // 定义添加位置 public Array(int len) ... 
- QQ企业通---DllImport
			1.DllImport 是什么? DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL(托管/非托管是微软的.net fr ... 
- 题解 hdu4624 Endless Spin
			题目链接 题目大意: 有长度为\(n\)的区间,每次随机选择一段(左右端点都是整数)染黑,问期望多少次全部染黑. \(n\leq 50\) 设\(n\)个随机变量\(t_1,...,t_n\).\(t ... 
- ubuntu 系统分配固定 ip--
			由于Ubuntu重启之后,ip很容易改变,可以用以下方式固定ip地址 1.设置ip地址 vi /etc/network/interface # The loopback network interfa ... 
- HihoCoder第一周与POJ3974:最长回文字串
			这个题目是hihoCoder第一周的题目,自己打算从第一周开始做起,不知道能追上多少,更不知道这一篇写完,下一篇会是什么时候... 题意很简单. 输入: abababa aaaabaa acacdas ... 
- iOS大V博客
			王巍的博客:王巍目前在日本横滨任职于LINE.工作内容主要进行Unity3D开发,8小时之外经常进行iOS/Mac开发.他的陈列柜中已有多款应用,其中番茄工作法工具非常棒. http://onevca ... 
- 013、Java中int类型转换byte
			01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ... 
- 中兴将用“加减乘除”建立理想 5G 网络
			6 月 28 日,MWC 2019 上海展期间,中兴通讯执行董事.总裁徐子阳发表演讲表示,面对 5G 建网大势,要看破大势,不破不立.为此中兴将用“加减乘除”建立理想 5G 网络. 何为“加减乘除 ... 
- Postman配置Pre-request scripts预请求对请求进行AES加密
			1.首先,Postman的Pre-request scripts页面右边已经提供了一些模板,这些模板可以设置变量与环境变量,并使用双大括号对变量进行引用 {{info}} 2.对所有POST请求都进行 ... 
- netty权威指南学习笔记七——编解码技术之GoogleProtobuf
			首先我们来看一下protobuf的优点: 谷歌长期使用成熟度高: 跨语言支持多种语言如:C++,java,Python: 编码后消息更小,更利于存储传输: 编解码性能高: 支持不同协议版本的兼容性: ... 
