33// TableProMobile
44//
55
6+ import CoreSpotlight
67import Foundation
78import Observation
89import TableProDatabase
@@ -40,12 +41,14 @@ final class AppState {
4041 tags = tagStorage. load ( )
4142 secureStore. cleanOrphanedCredentials ( validConnectionIds: Set ( connections. map ( \. id) ) )
4243 updateWidgetData ( )
44+ updateSpotlightIndex ( )
4345
4446 syncCoordinator. onConnectionsChanged = { [ weak self] merged in
4547 guard let self else { return }
4648 self . connections = merged
4749 self . storage. save ( merged)
4850 self . updateWidgetData ( )
51+ self . updateSpotlightIndex ( )
4952 }
5053
5154 syncCoordinator. onGroupsChanged = { [ weak self] merged in
@@ -72,6 +75,7 @@ final class AppState {
7275 connections. append ( connection)
7376 storage. save ( connections)
7477 updateWidgetData ( )
78+ updateSpotlightIndex ( )
7579 syncCoordinator. markDirty ( connection. id)
7680 syncCoordinator. scheduleSyncAfterChange ( )
7781 }
@@ -81,6 +85,7 @@ final class AppState {
8185 connections [ index] = connection
8286 storage. save ( connections)
8387 updateWidgetData ( )
88+ updateSpotlightIndex ( )
8489 syncCoordinator. markDirty ( connection. id)
8590 syncCoordinator. scheduleSyncAfterChange ( )
8691 }
@@ -98,6 +103,7 @@ final class AppState {
98103 try ? secureStore. delete ( forKey: " com.TablePro.sshkeydata. \( connection. id. uuidString) " )
99104 storage. save ( connections)
100105 updateWidgetData ( )
106+ updateSpotlightIndex ( )
101107 syncCoordinator. markDeleted ( connection. id)
102108 syncCoordinator. scheduleSyncAfterChange ( )
103109 }
@@ -179,6 +185,26 @@ final class AppState {
179185 syncCoordinator. scheduleSyncAfterChange ( )
180186 }
181187
188+ // MARK: - Spotlight
189+
190+ private func updateSpotlightIndex( ) {
191+ let items = connections. map { conn in
192+ let attributes = CSSearchableItemAttributeSet ( contentType: . item)
193+ attributes. title = conn. name. isEmpty ? conn. host : conn. name
194+ attributes. contentDescription = " \( conn. type. rawValue) · \( conn. host) : \( conn. port) "
195+ return CSSearchableItem (
196+ uniqueIdentifier: conn. id. uuidString,
197+ domainIdentifier: " com.TablePro.connections " ,
198+ attributeSet: attributes
199+ )
200+ }
201+ if items. isEmpty {
202+ CSSearchableIndex . default ( ) . deleteAllSearchableItems ( )
203+ } else {
204+ CSSearchableIndex . default ( ) . indexSearchableItems ( items)
205+ }
206+ }
207+
182208 // MARK: - Widget
183209
184210 private func updateWidgetData( ) {
0 commit comments