-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Copy pathBloggingPrompt+CoreDataClass.swift
130 lines (106 loc) · 4.48 KB
/
BloggingPrompt+CoreDataClass.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import Foundation
import CoreData
import WordPressKit
public class BloggingPrompt: NSManagedObject {
@nonobjc public class func fetchRequest() -> NSFetchRequest<BloggingPrompt> {
return NSFetchRequest<BloggingPrompt>(entityName: Self.classNameWithoutNamespaces())
}
@nonobjc public class func newObject(in context: NSManagedObjectContext) -> BloggingPrompt? {
return NSEntityDescription.insertNewObject(forEntityName: Self.classNameWithoutNamespaces(), into: context) as? BloggingPrompt
}
public override func awakeFromInsert() {
self.date = .init(timeIntervalSince1970: 0)
self.displayAvatarURLs = []
}
var promptAttribution: BloggingPromptsAttribution? {
BloggingPromptsAttribution(rawValue: attribution.lowercased())
}
/// Convenience method to map properties from `BloggingPromptRemoteObject`.
///
/// - Parameters:
/// - remotePrompt: The remote prompt model to convert
/// - siteID: The ID of the site that the prompt is intended for
func configure(with remotePrompt: BloggingPromptRemoteObject, for siteID: Int32) {
self.promptID = Int32(remotePrompt.promptID)
self.siteID = siteID
self.text = remotePrompt.text
self.attribution = remotePrompt.attribution
self.date = remotePrompt.date
self.answered = remotePrompt.answered
self.answerCount = Int32(remotePrompt.answeredUsersCount)
self.displayAvatarURLs = remotePrompt.answeredUserAvatarURLs
self.additionalPostTags = [String]() // reset previously additional tags.
if let brandContext = BrandContext(with: remotePrompt) {
brandContext.configure(self)
}
}
func textForDisplay() -> String {
return text.stringByDecodingXMLCharacters().trim()
}
/// Convenience method that checks if the given date is within the same day of the prompt's date without considering the timezone information.
///
/// Example: `2022-05-19 23:00:00 UTC-5` and `2022-05-20 00:00:00 UTC` are both dates within the same day (when the UTC date is converted to UTC-5),
/// but this method will return `false`.
///
/// - Parameters:
/// - localDate: The date to compare against in local timezone.
/// - Returns: True if the year, month, and day components of the `localDate` matches the prompt's localized date.
func inSameDay(as dateToCompare: Date) -> Bool {
return DateFormatters.utc.string(from: date) == DateFormatters.local.string(from: dateToCompare)
}
/// Used for comparison on upsert – there can't be two `BloggingPrompt` objects with the same date, so we can use it as a unique identifier
@objc
var dateString: String {
DateFormatters.local.string(from: date)
}
}
// MARK: - Notification Payload
extension BloggingPrompt {
struct NotificationKeys {
static let promptID = "prompt_id"
static let siteID = "site_id"
}
}
// MARK: - Private Helpers
private extension BloggingPrompt {
enum Constants {
static let bloganuaryTag = "bloganuary"
}
enum BrandContext {
case bloganuary(String)
init?(with remotePrompt: BloggingPromptRemoteObject) {
// Bloganuary context
if let bloganuaryId = remotePrompt.bloganuaryId,
bloganuaryId.contains(Constants.bloganuaryTag) {
self = .bloganuary(bloganuaryId)
return
}
return nil
}
/// Configures the given prompt with additional data based on the brand context.
///
/// - Parameter prompt: The `BloggingPrompt` instance to configure.
func configure(_ prompt: BloggingPrompt) {
switch self {
case .bloganuary(let id):
prompt.additionalPostTags = [Constants.bloganuaryTag, id]
prompt.attribution = BloggingPromptsAttribution.bloganuary.rawValue
}
}
}
struct DateFormatters {
static let local: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = .init(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
static let utc: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = .init(identifier: "en_US_POSIX")
formatter.timeZone = .init(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
}
}