-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathArticleCollection.swift
109 lines (84 loc) · 2.57 KB
/
ArticleCollection.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//
// ArticleCollection.swift
// RSSReader
//
// Created by Mitchell Cooper on 10/9/14.
// Copyright (c) 2014 Mitchell Cooper. All rights reserved.
//
import Foundation
/*
an article collection represents a set of articles
to be displayed with an ArticleListVC.
complying with this protocol are:
Feed
An actual feed.
FeedGroup
A category of feeds.
GenericArticleCollection
A generic collection with a list of articles.
Used for total, unread, saved, etc.
*/
protocol ArticleCollection {
// a list of articles in a specific order.
var articles: [Article] { get }
// all feeds involved in the articles
var feeds: [Feed] { get }
// a single feed will set it to false when the
// request finishes.
//
// a collection of feeds should set this as soon as
// ALL feeds' requests have finished.
//
var loading: Bool { get }
// the title of the collection.
// for a feed, it's the feed title.
// it could also be "All feeds," etc.
var title: String { get }
var shortTitle: String { get }
// if more than one operation occurs, the callback will
// be called after the completion of each one. this is
// because fetchThen is usually used to refresh
// something in the interface.
mutating func fetchThen(_ then: ((Void) -> Void)?)
// returns the lists of unread and saved articles
var unread: [Article] { get }
var saved: [Article] { get }
}
// the generic article collection consists of a title
// and a list of articles.
struct GenericArticleCollection: ArticleCollection {
var articles: [Article]
var title = "Articles"
var shortTitle: String { return title }
// feeds
var feeds: [Feed] {
var f = [Feed: Bool]()
for feed in (articles.map { $0.feed }) {
f[feed] = true
}
return f.keys.array
}
// unread articles
var unread: [Article] {
return articles.filter { !$0.read }
}
// saved articles
var saved: [Article] {
return articles.filter { $0.saved }
}
// initialize with title and articles
init(title: String, articles: [Article]) {
self.articles = articles
self.title = title
}
// loading updated by fetchThen()
var loading: Bool {
return feeds.filter { $0.loading }.first != nil
}
// fetch all feeds involved
mutating func fetchThen (_ then: ((Void) -> Void)?) {
for feed in feeds {
feed.fetchThen(then)
}
}
}