NetNewsWire/Frameworks/Account/NewsBlur/Models/NewsBlurStoryHash.swift

81 lines
2.4 KiB
Swift

//
// NewsBlurStoryHash.swift
// Account
//
// Created by Anh Quang Do on 2020-03-13.
// Copyright (c) 2020 Ranchero Software, LLC. All rights reserved.
//
import Foundation
import RSCore
import RSParser
typealias NewsBlurStoryHash = NewsBlurStoryHashesResponse.StoryHash
struct NewsBlurStoryHashesResponse: Decodable {
typealias StoryHashDictionary = [String: [StoryHash]]
var unread: [StoryHash]?
var starred: [StoryHash]?
struct StoryHash: Hashable, Codable {
var hash: String
var timestamp: Date
}
}
extension NewsBlurStoryHashesResponse {
private enum CodingKeys: String, CodingKey {
case unread = "unread_feed_story_hashes"
case starred = "starred_story_hashes"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
// Parse unread
if let unreadContainer = try? container.nestedContainer(keyedBy: NewsBlurGenericCodingKeys.self, forKey: .unread) {
let storyHashes = try NewsBlurStoryHashesResponse.extractHashes(container: unreadContainer)
self.unread = storyHashes.values.flatMap { $0 }
}
// Parse starred
if let starredContainer = try? container.nestedUnkeyedContainer(forKey: .starred) {
self.starred = try NewsBlurStoryHashesResponse.extractArray(container: starredContainer)
}
}
static func extractHashes<Key>(container: KeyedDecodingContainer<Key>) throws -> StoryHashDictionary where Key: CodingKey {
var dict: StoryHashDictionary = [:]
for key in container.allKeys {
dict[key.stringValue] = []
var hashArrayContainer = try container.nestedUnkeyedContainer(forKey: key)
while !hashArrayContainer.isAtEnd {
var hashContainer = try hashArrayContainer.nestedUnkeyedContainer()
let hash = try hashContainer.decode(String.self)
let timestamp = try hashContainer.decode(Date.self)
let storyHash = StoryHash(hash: hash, timestamp: timestamp)
dict[key.stringValue]?.append(storyHash)
}
}
return dict
}
static func extractArray(container: UnkeyedDecodingContainer) throws -> [StoryHash] {
var hashes: [StoryHash] = []
var hashArrayContainer = container
while !hashArrayContainer.isAtEnd {
var hashContainer = try hashArrayContainer.nestedUnkeyedContainer()
let hash = try hashContainer.decode(String.self)
let timestamp = try (hashContainer.decode(String.self) as NSString).doubleValue
let storyHash = StoryHash(hash: hash, timestamp: Date(timeIntervalSince1970: timestamp))
hashes.append(storyHash)
}
return hashes
}
}