1import Foundation
2import CoreSpotlight
3import MobileCoreServices
4
5// Compilation: swiftc spotlight.swift -o spotlight
6// Usage: ./spotlight <json_of_emails>
7
8struct EmailToIndex: Codable {
9 let id: String
10 let subject: String
11 let sender: String
12 let body: String
13 let date: Date
14}
15
16func indexEmails(jsonString: String) {
17 guard let data = jsonString.data(using: .utf8),
18 let emails = try? JSONDecoder().decode([EmailToIndex].self, from: data) else {
19 print("Error: Invalid JSON")
20 exit(1)
21 }
22
23 var searchableItems: [CSSearchableItem] = []
24
25 for email in emails {
26 let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeEmailMessage as String)
27 attributeSet.title = email.subject
28 attributeSet.contentDescription = email.body
29 attributeSet.authorNames = [email.sender]
30 attributeSet.contentCreationDate = email.date
31
32 let item = CSSearchableItem(
33 uniqueIdentifier: email.id,
34 domainIdentifier: "com.floatpane.matcha.emails",
35 attributeSet: attributeSet
36 )
37 searchableItems.append(item)
38 }
39
40 CSSearchableIndex.default().indexSearchableItems(searchableItems) { error in
41 if let error = error {
42 print("Error indexing items: \(error.localizedDescription)")
43 exit(1)
44 } else {
45 print("Successfully indexed \(searchableItems.count) emails")
46 exit(0)
47 }
48 }
49}
50
51let args = ProcessInfo.processInfo.arguments
52if args.count > 1 {
53 indexEmails(jsonString: args[1])
54} else {
55 let input = FileHandle.standardInput.readDataToEndOfFile()
56 if let text = String(data: input, encoding: .utf8) {
57 indexEmails(jsonString: text)
58 }
59}
60
61RunLoop.main.run()