且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

【iOS开发】两个函数搞定本地存储

更新时间:2021-12-03 22:52:56

平时我们经常会采用 NSUserDefaults 或者 Plist 来存储数据到设备,这样即使 App 被关闭,下次再打开的时候数据还在。这里我写了两个函数来供大家使用,一个用来存数据,一个用来读数据。

// MARK: - Store
enum StoreType {
    case userDefaults
    case plist
}

func setContentToDevice (content:AnyObject, key:String, type:StoreType) {
    if type == .userDefaults {
        let defaults = NSUserDefaults.standardUserDefaults()
        defaults.setObject(content, forKey: key)
        print("Set - UserDefaults")
    }else if type == .plist {
        let pathPrefix = NSSearchPathForDirectoriesInDomains(
            NSSearchPathDirectory.DocumentDirectory,
            NSSearchPathDomainMask.AllDomainsMask, true).first
        let pathSuffix = "/" + key + ".plist"
        if let path = pathPrefix?.stringByAppendingString(pathSuffix) {
            NSKeyedArchiver.archiveRootObject(content, toFile: path)
            print("Set - Plist")
        }
    }
}

func getContentFromDevice (key:String, type:StoreType) -> AnyObject? {
    var returnObject :AnyObject?
    
    if type == .userDefaults {
        let defaults = NSUserDefaults.standardUserDefaults()
        let content = defaults.objectForKey(key)
        returnObject = content
        print("Get - UserDefaults")
    }else if type == .plist {
        let pathPrefix = NSSearchPathForDirectoriesInDomains(
            NSSearchPathDirectory.DocumentDirectory,
            NSSearchPathDomainMask.AllDomainsMask, true).first
        let pathSuffix = "/" + key + ".plist"
        if let path = pathPrefix?.stringByAppendingString(pathSuffix) {
            if let content = NSKeyedUnarchiver.unarchiveObjectWithFile(path) {
                returnObject = content
                print("Get - Plist")
            }
        }
    }
    
    return returnObject
}

函数名和参数名都一看便知是什么意思,只要你存取数据都用的是同一个 Key,就可以操作同一份数据。

这里多提供了一个 type 选项来选择通过 NSUserDefaults 或者 Plist 来存储数据。但是要注意,在这里 NSUserDefaults 只支持存储 NSArray、NSString 等基本类型,如果你要存储自定义类型的实例,必须使用 StoreType.plist 进行存储。此外,这个类还必须进行微小的改动,这部分可以参考我之前写的一篇文章

下面给出使用这个函数的范例:(其中 Hero 是我自定义的类)

let arr = [1,2,3,4,5]
setContentToDevice(arr, key: "testArr", type: .userDefaults)

let ironMan = Hero(name: "Tony Stark")
setContentToDevice(ironMan, key: "testHero", type: .plist)

if let result = getContentFromDevice("testArr", type: .userDefaults) {
    print(result)
}

if let result = getContentFromDevice("testHero", type: .plist) as? Hero {
    print(result.name)
}
控制台输出

防止有人懒得看我之前写的那篇文章,把 Hero Class 这部分代码也贴出来

import UIKit

class Hero: NSObject {
    
    var name:String
    
    init(name:String) {
        self.name = name
        super.init()
    }
    
    func encodeWithCoder(aCoder: NSCoder!) {
        aCoder.encodeObject(name, forKey: "name")
    }
    
    init(coder aDecoder: NSCoder!) {
        self.name = aDecoder.decodeObjectForKey("name") as! String
    }
}

这是完整项目 Github 地址