Newer
Older
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
import UIKit
import DifferenceKit
public protocol IndexableItem {
var indexedOn: NSString { get }
}
public class IndexedListCollator<Item: IndexableItem> {
private final class CollationWrapper: NSObject {
let value: Any
@objc let indexedOn: NSString
init(value: Any, indexedOn: NSString) {
self.value = value
self.indexedOn = indexedOn
}
func unwrappedValue<UnwrappedType>() -> UnwrappedType {
return value as! UnwrappedType
}
}
public init() {}
public func sectioned(items: [Item]) -> (sections: [[Item]], collation: UILocalizedIndexedCollation) {
let collation = UILocalizedIndexedCollation.current()
let selector = #selector(getter: CollationWrapper.indexedOn)
let wrappedItems = items.map { item in
CollationWrapper(value: item, indexedOn: item.indexedOn)
}
let sortedObjects = collation.sortedArray(from: wrappedItems, collationStringSelector: selector) as! [CollationWrapper]
var sections = collation.sectionIndexTitles.map { _ in [Item]() }
sortedObjects.forEach { item in
let sectionNumber = collation.section(for: item, collationStringSelector: selector)
sections[sectionNumber].append(item.unwrappedValue())
}
return (sections: sections.filter { !$0.isEmpty }, collation: collation)
}
}
public struct Contact: Codable, Hashable, Equatable {
public enum Request {
case all
case failed
case friends
case received
case requested
case isRecent
case verificationInProgress
case withUserId(Data)
case withUserIds([Data])
case withUsername(String)
}
public enum Status: Int64, Codable {
case friend
case stranger
case verified
case verificationFailed
case verificationInProgress
case requested
case requesting
case requestFailed
case confirming
case confirmationFailed
case hidden
}
public var id: Int64?
public var photo: Data?
public let userId: Data
public var email: String?
public var phone: String?
public var status: Status
public var marshaled: Data
public var createdAt: Date
public let username: String
public var nickname: String?
public var isRecent: Bool
public init(
photo: Data?,
userId: Data,
email: String?,
phone: String?,
status: Status,
marshaled: Data,
username: String,
nickname: String?,
createdAt: Date,
isRecent: Bool
) {
self.email = email
self.phone = phone
self.photo = photo
self.status = status
self.userId = userId
self.username = username
self.nickname = nickname
self.marshaled = marshaled
self.createdAt = createdAt
self.isRecent = isRecent
}
public var differenceIdentifier: Data { userId }
public static var databaseTableName: String { "contacts" }
}
extension Contact: Differentiable {}
extension Contact: IndexableItem {
public var indexedOn: NSString {
guard let nickname = nickname else {
return "\(username.first!)" as NSString
}
return "\(nickname.first!)" as NSString
}
}