-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathNotificationContentRangeFactory.swift
More file actions
91 lines (79 loc) · 3.63 KB
/
NotificationContentRangeFactory.swift
File metadata and controls
91 lines (79 loc) · 3.63 KB
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
import Foundation
struct NotificationContentRangeFactory: FormattableRangesFactory {
static func contentRange(from dictionary: [String: AnyObject]) -> FormattableContentRange? {
guard let range = rangeFrom(dictionary) else {
return nil
}
let properties = propertiesFrom(dictionary, with: range)
if let kind = kindString(from: dictionary) {
return contentRange(ofKind: kind, with: properties, from: dictionary)
}
return contentRangeWithoutKindSpecified(with: properties, from: dictionary)
}
private static func propertiesFrom(
_ dictionary: [String: AnyObject],
with range: NSRange
) -> NotificationContentRange.Properties {
var properties = NotificationContentRange.Properties(range: range)
properties.siteID = dictionary[RangeKeys.siteId] as? NSNumber
properties.postID = dictionary[RangeKeys.postId] as? NSNumber
properties.streamKey = dictionary[RangeKeys.id] as? String
if let urlString = dictionary[RangeKeys.url] as? String, let url = URL(string: urlString) {
properties.url = url
if let items = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems {
for item in items {
if let value = item.value, !value.isEmpty {
properties.streamQueryParameters[item.name] = value
}
}
}
}
return properties
}
private static func contentRange(ofKind type: String, with properties: NotificationContentRange.Properties, from dictionary: [String: AnyObject]) -> FormattableContentRange? {
var properties = properties
let kind = FormattableRangeKind(type)
switch kind {
case .comment:
let commentID = dictionary[RangeKeys.id] as? NSNumber
return NotificationCommentRange(commentID: commentID, properties: properties)
case .noticon:
return nil
case .post:
properties.postID = dictionary[RangeKeys.id] as? NSNumber
return NotificationContentRange(kind: kind, properties: properties)
case .site:
properties.siteID = dictionary[RangeKeys.id] as? NSNumber
return NotificationContentRange(kind: kind, properties: properties)
case .user:
properties.userID = dictionary[RangeKeys.id] as? NSNumber
return NotificationContentRange(kind: kind, properties: properties)
default:
return NotificationContentRange(kind: kind, properties: properties)
}
}
private static func contentRangeWithoutKindSpecified(with properties: NotificationContentRange.Properties, from dictionary: [String: AnyObject]) -> NotificationContentRange? {
if containsSiteID(dictionary) {
return NotificationContentRange(kind: .site, properties: properties)
}
if containsValidURL(dictionary) {
return NotificationContentRange(kind: .link, properties: properties)
}
return nil
}
private static func containsSiteID(_ dictionary: [String: AnyObject]) -> Bool {
return (dictionary[RangeKeys.siteId] as? NSNumber) != nil
}
private static func containsValidURL(_ dictionary: [String: AnyObject]) -> Bool {
let urlString = dictionary[RangeKeys.url] as? String ?? ""
return URL(string: urlString) != nil
}
enum RangeKeys {
static let rawType = "type"
static let url = "url"
static let id = "id"
static let value = "value"
static let siteId = "site_id"
static let postId = "post_id"
}
}