您的位置:首页 > 移动开发 > Swift

iOS编程——通过UUID和KeyChain来代替Mac地址实现iOS设备的唯一标示(Swift 优化版)

2015-08-12 18:41 716 查看
之前草草写了一篇OC版本的,再写Swift版本时发现好多可以优化的地方。今天先把Swift版本的和大家共享下,稍后再发一篇OC优化版

关于KeyChain有很多的相关资料,大家去网上看看,需要注意的是:

1). kSecAttrServer可以作为一个搜索的Key来获取App KeyChain的对应Value;根据不同的kSecAttrServer来保存不同的Value,本例只保存了一个UUID;

2).SecItemUpdate()函数,第二个Dictionary只需要传入需要更新的值即可:

var updateDictionary = NSMutableDictionary()
updateDictionary.setObject(NSKeyedArchiver.archivedDataWithRootObject(data), forKey: kSecValueData as String)

var status = SecItemUpdate(mDictionary,updateDictionary)


3)程序删除以后KeyChain还是存在的,代码里面提供了对应的更新和删除方法,直接上代码了。

1.文件组成:



2.MyKeyChainManager.swift 代码,增、删、改、查四个方法:

import Foundation

let _SingLetonKeyChainManager = MyKeyChainManager()

class MyKeyChainManager {

//单例模式
class var sharedInstance: MyKeyChainManager{
return _SingLetonKeyChainManager
}

private init() {

}

//根据不同的service获取不同的Value
func getKeyChainItemDictionary(service: String) -> NSMutableDictionary{
var mDictionary = NSMutableDictionary()

mDictionary.setObject(kSecClassInternetPassword as NSString, forKey: kSecClass as NSString)
mDictionary.setObject(service, forKey:  kSecAttrServer as NSString)
mDictionary.setObject("nodefine", forKey: kSecAttrAccount as NSString)

return mDictionary
}

func add(#service: String, data: AnyObject) -> OSStatus{
var mDictionary = getKeyChainItemDictionary(service)
var status: OSStatus = noErr

let result = get(service)

if result.0 != nil{
let dic = result.1
let createTime = dic?.objectForKey("cdat") as! NSDate
let modifyTime = dic?.objectForKey("mdat") as! NSDate
println("已存在service:\(service), 创建时间:\(createTime.description),最近一次修改时间:\(modifyTime.description)")
status = update(service: service, data: data)
} else {
mDictionary.setObject(NSKeyedArchiver.archivedDataWithRootObject(data), forKey: kSecValueData as String)
status = SecItemAdd(mDictionary, nil)
}

return status
}

func delete(#service: String) -> OSStatus{
var mDictionary = getKeyChainItemDictionary(service)
var status: OSStatus

let result = get(service)

if result.0 != nil{
let dic = result.1
let createTime = dic?.objectForKey("cdat") as! NSDate
let modifyTime = dic?.objectForKey("mdat") as! NSDate
println("要删除的service:\(service), 创建时间:\(createTime.description),最近一次修改时间:\(modifyTime.description)")
status = SecItemDelete(mDictionary)
} else{
status = noErr
}

return status
}

func update(#service: String, data: AnyObject) -> OSStatus{
var mDictionary = getKeyChainItemDictionary(service)
var status: OSStatus = noErr

let result = get(service)

if result.0 != nil{
let dic = result.1
let createTime = dic?.objectForKey("cdat") as! NSDate
let modifyTime = dic?.objectForKey("mdat") as! NSDate
println("要更新的service:\(service), 创建时间:\(createTime.description),最近一次修改时间:\(modifyTime.description)")

var updateDictionary = NSMutableDictionary()
updateDictionary.setObject(NSKeyedArchiver.archivedDataWithRootObject(data), forKey: kSecValueData as String)

var status = SecItemUpdate(mDictionary,updateDictionary)
} else {
status = add(service: service, data: data)
}

return status
}

func get(service: String) -> (AnyObject?, NSDictionary?){
var mDictionary = getKeyChainItemDictionary(service)
mDictionary.setObject(kCFBooleanTrue, forKey: kSecReturnData as String)
mDictionary.setObject(kCFBooleanTrue, forKey: kSecReturnAttributes as String)

var queryResult: Unmanaged<AnyObject>?

let status = SecItemCopyMatching(mDictionary,&queryResult)

let opaque = queryResult?.toOpaque()

var contentsOfKeychain: NSString?

var finallyData: AnyObject?
var returnDic: NSDictionary?
if let op = opaque {
returnDic = Unmanaged<NSDictionary>.fromOpaque(op).takeUnretainedValue()
let valueData = returnDic!.objectForKey(kSecValueData) as! NSData
finallyData = NSKeyedUnarchiver.unarchiveObjectWithData(valueData)
}

return (finallyData, returnDic)
}

}


3.MyUUIDManager.swift文件,同样是对UUID的 删、改、查,注意的是查的结果为空时自动会增加UUID:

import Foundation

class MyUUIDManager {

private let kKeyChainUUIDIdentifier = "com.myuuid.uuid";

private let keychainManager = MyKeyChainManager.sharedInstance

private func getOriginUUID() -> String {
var puuid = CFUUIDCreate( nil );

var uuidString = CFUUIDCreateString(nil, puuid);

return uuidString as String
}

private func addUUID() -> (OSStatus, String) {

let uuidString = getOriginUUID()
var status: OSStatus = noErr

status = keychainManager.add(service: kKeyChainUUIDIdentifier, data: uuidString)

return (status, uuidString)
}

func deleteUUID() -> OSStatus {
return keychainManager.delete(service: kKeyChainUUIDIdentifier)
}

func updateUUID(newUUID: String) -> OSStatus {
return keychainManager.update(service: kKeyChainUUIDIdentifier, data: newUUID)
}

func getUUID() -> String? {

let getData: AnyObject? = keychainManager.get(kKeyChainUUIDIdentifier).0
var uuidString: String?
if let data: AnyObject = getData {
uuidString = data as? String
} else {
let result = addUUID()
println("Keychain 的UUID不存在,首次保存。")
if result.0 == noErr {
uuidString = result.1
}
}

return uuidString
}

}


4.测试,直接真机运行,步骤依次是:获取(没有的话会自动添加保存),更新,获取,删除:

let uuidM = MyUUIDManager()

var uuid = uuidM.getUUID()
println(uuid)

uuidM.updateUUID("updateUDID:xxxxxxx")
uuid = uuidM.getUUID()
println(uuid)

uuidM.deleteUUID()


打印日志:

Keychain 的UUID不存在,首次保存。
Optional("A01A905C-D47F-4E9F-9761-DF8346A1FF08")
要更新的service:com.myuuid.uuid2, 创建时间:2015-08-12 10:47:46 +0000,最近一次修改时间:2015-08-12 10:47:46 +0000
Optional("updateUDID:xxxxxxx")
要删除的service:com.myuuid.uuid2, 创建时间:2015-08-12 10:47:46 +0000,最近一次修改时间:2015-08-12 10:47:46 +0000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: