Files
2022-04-27 13:49:36 +09:00

69 lines
2.1 KiB
Swift

//
// EntryGenerator.swift
// LifeGameApp
//
// Created by Yusuke Hosonuma on 2020/09/12.
//
import Foundation
import Combine
import WidgetKit
import FirebaseAuth
import FirebaseFirestore
import Core
public final class TimelineEntryGenerator {
public static let shared = TimelineEntryGenerator()
private let patternService: PatternService = .shared
private var cancellables: [AnyCancellable] = []
public func generate(for family: WidgetFamily, times: Int, staredOnly: Bool, completion: @escaping ([Entry]) -> Void) {
let displayCount = family.displayCount
let totalCount = displayCount * times
candidatePatternURLs(staredOnly: staredOnly)
.map { $0.shuffled().prefix(totalCount) }
.flatMap { urls in
Publishers.MergeMany(
urls.map { self.patternService.fetch(from: $0) }
)
}
.collect()
.map { $0.compactMap { $0 } }
.sink { item in
let entries = self.generateEntries(from: item, displayCount: displayCount, times: times)
completion(entries)
}
.store(in: &cancellables)
}
// MARK: Private
private func generateEntries(from items: [PatternItem], displayCount: Int, times: Int) -> [Entry] {
let currentDate = Date()
let entries: [Entry] = items
.group(by: displayCount)
.prefix(times)
.enumerated()
.map { offset, items in
let entryDate = Calendar.current.date(byAdding: .minute, value: offset, to: currentDate)!
let data = items.map(BoardData.init)
return Entry(date: entryDate, relevance: data)
}
return entries
}
private func candidatePatternURLs(staredOnly: Bool) -> AnyPublisher<[URL], Never> {
let publisher = staredOnly
? patternService.staredPatternURLs()
: patternService.patternURLs()
return publisher
.map { $0.map(\.url) }
.eraseToAnyPublisher()
}
}