创建一个高效的文件管理类

2018-12-29  本文已影响0人  啧啧同学

基于NSFileManager和CryptoSwift封装一个简便的文件管理器,包含文件的操作及AES加解密

1.iOS的沙盒机制:

每个iOS应用都有自己的应用沙盒,应用沙盒就是文件系统目录。sandbox对应用程序执行各种操作的权限限制,是一种独立、安全、封闭的空间,非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文本文件等。其特点有:

沙盒的文件目录:

沙盒内部文件.jpg
对应文件夹
       - Caches:一般存储的是缓存文件,例如图片视频等,此目录下的文件不会再应用程序退出时删除。在手机备份的时候,iTunes不会备份该目录。例如音频,视频等文件存放其中
       -Preferences:保存应用程序的所有偏好设置iOS的Settings(设置),我们不应该直接在这里创建文件,而是需要通过NSUserDefault这个类来访问应用程序的偏好设置。iTunes会自动备份该文件目录下的内容。比如说:是否允许访问图片,是否允许访问地理位置......

2.CryptoSwift:

CryptoSwift是一个使用 Swift 编写的加密工具包,支持多种加密算法,如:MD5、SHA1、AES-128 等等。

管理类的基本框架设计

文件管理类框架.png

基本方法

/* 获取沙盒路径方法 */

    public func sandboxCachePath() -> String {
        let array = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)
        return array.first ?? ""
    }

/* 判断文件是否存在,如果有同名文件夹存在,依然会返回false */

    public func isFileExist(at path: String) -> Bool {
        var isDir: ObjCBool = false
        let isExist = FileManager.default.fileExists(atPath: path, isDirectory: &isDir)
        return isExist && !isDir.boolValue
    }

/** 判断文件夹是否存在,如果有同名的文件存在,依然会返回false */

    public func isDirectoryExist(at path: String) -> Bool {
        var isDir: ObjCBool = false
        let isExist = FileManager.default.fileExists(atPath: path, isDirectory: &isDir)
        return isExist && isDir.boolValue
    }

/** 创建一个文件夹目录,如果Path中包含不存在的目录,会自动创建这些目录。如果目录已存在则会忽略该操作。返回创建是否成功。 */

    @discardableResult
    public func createDirectory(_ dirPath: String) -> Bool {
        guard isDirectoryExist(at: dirPath) == false else { return true }
        
        do {
            try FileManager.default.createDirectory(atPath: dirPath, withIntermediateDirectories: true, attributes: nil)
            return true
        } catch {
            RLog.error("Create directory \(dirPath) throw an error")
        }
        return false
    }

/** 删除文件夹或文件 */

    @discardableResult
    public func removeItem(at path: String) -> Bool {
        do {
            try FileManager.default.removeItem(atPath: path)
            return true
        } catch {
            RLog.error("Remove item at \(path) throw an error")
        }
        return false
    }

AES加/解密

AES加/解密模式

密钥的长度

在进行 AES 加密时,CryptoSwift 会根据密钥的长度自动选择对应的加密算法(AES128, AES192, AES256)

这里以CBC的方式进行加密

    /** 返回是否加密成功 */
    @discardableResult
    public func aesEncryptFile(at path: URL, key: Array<UInt8>, iv: Array<UInt8>) -> Bool {
        do {
            let originData = try Data(contentsOf: path)
            
            let aes = try AES(key: key, blockMode: CBC(iv: iv))
            let encryptBytes = try aes.encrypt(originData.bytes)
            let encryptData = Data(bytes: encryptBytes)
            try encryptData.write(to: path)
            
            return true
            
        } catch {
            RLog.error("Encrypt file at path = \(path) throw an error")
        }
        return false
    }

/** 返回是否解密成功 */

    public func aesDecryptFile(at path: URL, key: Array<UInt8>, iv: Array<UInt8>) -> Data? {
        do {
            let originData = try Data(contentsOf: path)
            
            let aes = try AES( key: key, blockMode: CBC(iv: iv))
            let decryptBytes = try aes.decrypt(originData.bytes)
            return Data(bytes: decryptBytes)
            
        } catch {
            RLog.error("Decrypt file at path = \(path) throw an error")
        }
        return nil
    }
上一篇下一篇

猜你喜欢

热点阅读