利用KeychainAccess存储用户信息

本文章包含以下几个知识点,
一,KeychainAccess存,读,删
二,model序列化和反序列化的实现

注意事项
model序列化需要添加@objcMembers,否则class_copyPropertyList遍历的属性数组为空

以下为相关代码:

XLUserInfoTool

import UIKit
import KeychainAccess

let user_path = "user.db"

class XLUserInfoTool: NSObject {

    var userPath = FileManager.getCurrentStoreagePath(user_path)
    static let shareUserInfoTool = XLUserInfoTool()
    var  userInfo: userInfoModel!

    override init() {
        super.init()
        if FileManager.checkFileIsExist(userPath) == true {
            userInfo = NSKeyedUnarchiver.unarchiveObject(withFile: userPath) as? userInfoModel
            loginStatus = (userInfo?.id != nil)
        }
    }
    var loginStatus: Bool? {
        didSet {
            if loginStatus == false {
                XLLogout()
                userInfo = UserInfoModel()
            }
            loginStatusChange()
        }
    }
    /// 保存用户
    public func saveUser() {
        guard let user = userInfo else { return }
        DispatchQueue.global().async {
            let suc = NSKeyedArchiver.archiveRootObject(user, toFile: self.userPath)
            if suc == false {
                NSLog(message:"保存user失败")
            }
        }
    }
    ///清除用户
    fileprivate func clearUser() {
        guard userInfo != nil else { return }
        let suc = FileManager.removePath(self.userPath)
        if suc == false {
            NSLog(message:"用户清除失败")
        }
    }
    ///退出登录
    func XLLogout() {
        RootVCApplicationService.init().switchToRootViewControllerByDestinationType(type: .homeLogin)
    }
    ///登录状态变更
    func loginStatusChange() {

    }
}

userInfoModel

@objcMembers class userInfoModel: : NSObject,HandyJSON,NSCoding,CodeArchive {
    var username : String?
    var token : String?
    var id : String?
    required override init() {
        super.init()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init()
        codeDecoder(coder: aDecoder)
    }
    func encode(with aCoder: NSCoder) {
        codeEncoder(with: aCoder)
    }
}

NSObject+Extension.swift

import Foundation
extension NSObject {
protocol CodeArchive {
    func codeDecoder(coder aDecoder: NSCoder)
    func codeEncoder(with aCoder: NSCoder)
}
extension CodeArchive where Self: NSObject {
    func codeDecoder(coder aDecoder: NSCoder) {
        // 这个类型可以使用CUnsignedInt,对应Swift中的UInt32
        var count: UInt32 = 0
        let properties = class_copyPropertyList(self.classForCoder, &count)
        var propertyNames: [String] = []
        // Swift中类型是严格检查的,必须转换成同一类型
        for i in 0 ..< Int(count) {
            // UnsafeMutablePointer是
            // 可变指针,因此properties就是类似数组一样,可以
            // 通过下标获取
            let property = properties![i]
            let name = property_getName(property)
            // 这里还得转换成字符串
            let propertyName = String(cString: name)
            propertyNames.append(propertyName)
            if let value = aDecoder.decodeObject(forKey: propertyName) {
                setValue(value, forKey: propertyName)
            }
        }
        // 释放内存,否则C语言的指针很容易成野指针的
        free(properties)
    }
    func codeEncoder(with aCoder: NSCoder) {
        // 这个类型可以使用CUnsignedInt,对应Swift中的UInt32
        var count: UInt32 = 0
        NSLog(message:self.classForCoder)
        let properties = class_copyPropertyList(self.classForCoder, &count)
        for i in 0 ..< Int(count) {
            // 获取属性名称
            let property = properties![i]
            let name = property_getName(property)
            let propertyName = String(cString: name)
            if (!propertyName.isEmpty) {
                // 获取Value数据
                let propertyValue = self.value(forKey: propertyName)
                if let value = propertyValue {
                    aCoder.encode(value, forKey: propertyName)
                }
            }
        }
    }
}

你可能感兴趣的:(利用KeychainAccess存储用户信息)