123 lines
3.3 KiB
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) }
|
|
}
|
|
}
|