blogger

skytoup's blog

分享经验, 共同进步; RSS: http://blog.skytoup.com/feed

文章44

分类0

评论0

便捷存储简单数据 - SimpleStoreData

便捷存储简单数据 - SimpleStoreData

为啥不叫SimpleStore??? 因为Cocoapods已有同名, 临时在后面加个Data?, 实际使用还是SimpleStore
下文SimpleStoreSimpleStoreData指的为同一样东西

两三年前, 公司需要Swift开发App, 从那时刚开始接触学习, 发现struct的一些特性可以结合UserDefault简化一些业务数据存储和读写, 于是就写出了SimpleStore的雏形.

随着Swift 5.1的发布, 发布了一个PropertyWrapper的新特性, 尝试把这个特性加到SimpleStore的雏形里面, 发现使用起来还是更方便. 顺便还升级了功能, 一个StoreItem由原本只支持单一类型存储, 改为支持多类型.

最近对SimpleStore的雏形进行了一番思考, 对其再次升级, 最后整理开源了SimpleStore.

设计思路

  • 核心
    SimpleStoreItem修改后, 触发SimpleStore进行对数据存储
  • 基本结构

    • SimpleStore: 管理和存储SimpleStoreItem
    • SimpleStoreItem: 存放数据
    • Mapper: 辅助数据间转换(非必须)
  • 扩展性

    • 可实现SimpleStore协议可配合SimpleStoreItem扩展更多存储方式(目前只有UserDefault)
    • SimpleStoreDictItem实现了SimpleStoreItem协议, 通过Mapper提供Itemdict的转换, 为中间转存提供方便, 易于扩展更多存储方式

用法

场景: 存储登录用户的数据(存储到UserDefault)

定义一个用户性别的枚举, 因为UserDefault不支持直接存储enum, 所以需要实现UDCoding

UserDefault支持的存储类型:

  • String
  • Int
  • Float
  • Double
  • Bool
  • Data
  • Date
  • URL
enum Gender: Int {
    case unknown = 0
    case male
    case female
}
/// 对于`UserDefault`不支持的存储类型提供数据转换
extension Gender: UDCoding {
    func toUDAny() -> Any {
        rawValue
    }
    
    static func fromUDAny(_ any: Any?) -> Gender? {
        guard let any = any as? Int else {
            return nil
        }
        return Gender(rawValue: any)
    }
}

定义存储用户数据的字段(重点提示: SimpleStoreItem必须使用struct实现), 字段使用UDMapperParam属性包装定义, 再实现mapValue方法进行数据映射

/// **重点提示: SimpleStoreItem必须使用struct实现**
struct UserStoreItem: SimpleStoreUDItem {
    @UDMapperParam(key: "name", default: "") var name
    @UDMapperParam(key: "age", default: 0) var age
    @UDMapperParam(key: "gender", default: Gender.unknown) var gender
    
    mutating func mapValue<Mapper>(_ mapper: inout Mapper) where Mapper : DictMapper, UserStoreItem.Key == Mapper.Key, UserStoreItem.Value == Mapper.Value {
        mapper <- _name
        mapper <- _age
        mapper <- _gender
    }
}

定义管理StoreItem的管理类(此处简单使用单例, 可根据自己的业务进行调整, manager也可定义更多业务方法)

class UserManager: SimpleStoreUD<UserStoreItem> {
    static let shared = UserManager(udKey: "__User__")
    
    // 这里可以添加一些业务方法
}

使用演示, 修改item数据即可存自动储, 无需其它调用方法

var userM = UserManager.shared
// 清空之前的数据
userM.ud.set(nil, forKey: userM.udKey)

// 提示: 一次性更新多个字段最好是使用方法`batchUpdate`
userM[\.name] = "sky"
print("第一次修改 \(userM.ud.dictionary(forKey: userM.udKey) ?? [:])")
// 第一次修改 ["gender": 0, "age": 0, "name": sky]

userM[\.age] = 18
print("第二次修改 \(userM.ud.dictionary(forKey: userM.udKey) ?? [:])")
// 第二次修改 ["name": sky, "age": 18, "gender": 0]

userM[\.gender] = .male
print("第三次修改 \(userM.ud.dictionary(forKey: userM.udKey) ?? [:])")
// 第三次修改 ["age": 18, "name": sky, "gender": 1]


// 批量修改字段再存储
userM.batchUpdate { item in
    item.name = "yks"
    item.age = 81
    item.gender = .female
}
print("batchUpdate \(userM.ud.dictionary(forKey: userM.udKey) ?? [:])")
// batchUpdate ["age": 81, "name": yks, "gender": 2]

// 相当于重置数据
userM.item = UserStoreItem()
print("重置数据 \(userM.ud.dictionary(forKey: userM.udKey) ?? [:])")
// 重置数据 ["age": 0, "name": , "gender": 0]

详情

详情请参考github地址: https://github.com/skytoup/SimpleStoreData

评论(0)

© 2020  skytoup's blog  · 由 Typecho 强力驱动
  Design by 往记