jsdw_ios/QuickLocation/Manager/Account/RelationStore.swift

123 lines
3.3 KiB
Swift

//
// RelationStore.swift
// QuickLocation
//
import Foundation
import ObjectMapper
import RxSwift
import SwiftyUserDefaults
struct RelationListResponse: BaseModelProtocol {
var code: String?
var message: String?
var list: [RelationModel] = []
init?(map: Map) {}
mutating func mapping(map: Map) {
code <- (map["code"], kIntTransformStr)
message <- map["message"]
if message == nil {
message <- map["msg"]
}
list <- map["data"]
}
}
struct RelationModel: Mappable, Equatable {
var name: String = ""
var type: String = ""
var limit: Int = -1
var icon: String = ""
init?(map: Map) {}
mutating func mapping(map: Map) {
name <- map["name"]
type <- (map["type"], kRelationTypeTransform)
limit <- (map["limit"], kStrTransformInt)
icon <- map["icon"]
}
var idx: String { type.trimmingCharacters(in: .whitespacesAndNewlines) }
var showsHeart: Bool { idx == "1" }
}
private let kRelationTypeTransform = TransformOf<String, Any>(fromJSON: { value in
transformStr(value)
}, toJSON: { value in
value
})
private enum RelationStoreError: LocalizedError {
case business(String)
case empty
var errorDescription: String? {
switch self {
case let .business(message):
return message
case .empty:
return "关系列表为空"
}
}
}
final class RelationStore {
static let shared = RelationStore()
private(set) var list: [RelationModel] = []
private let disposeBag = DisposeBag()
private init() {
loadDisk()
}
func preload(completion: ((Result<[RelationModel], Error>) -> Void)? = nil) {
UserService.relations()
.subscribe(onNext: { [weak self] response in
guard response.code == "0" else {
completion?(.failure(RelationStoreError.business(response.message ?? "获取关系列表失败")))
return
}
guard !response.list.isEmpty else {
completion?(.failure(RelationStoreError.empty))
return
}
self?.replace(response.list)
completion?(.success(response.list))
}, onError: { error in
completion?(.failure(error))
})
.disposed(by: disposeBag)
}
func item(for idx: String) -> RelationModel? {
let key = idx.trimmingCharacters(in: .whitespacesAndNewlines)
guard !key.isEmpty else { return nil }
return list.first { $0.idx == key }
}
func name(for idx: String) -> String? {
let name = item(for: idx)?.name.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
return name.isEmpty ? nil : name
}
func showsHeart(for idx: String) -> Bool {
item(for: idx)?.showsHeart == true
}
private func replace(_ list: [RelationModel]) {
self.list = list
let json = list.map { $0.toJSON() }
Defaults[\.userRelations] = try? JSONSerialization.data(withJSONObject: json)
}
private func loadDisk() {
guard let data = Defaults[\.userRelations],
let json = try? JSONSerialization.jsonObject(with: data) as? [[String: Any]] else { return }
list = json.compactMap { RelationModel(JSON: $0) }
}
}