Post

Replies

Boosts

Views

Activity

Reply to How to configure LazyVGrid with no spacing
Got an answer on StackOverflow - https://stackoverflow.com/a/63027052/515585, I missed the docs for GridItem: https://developer.apple.com/documentation/swiftui/griditem It also has a spacing parameter that controls the spacing between items, the documentation on grid should be clearer on the meaning of its spacing is not really the spacing between the grid and the next item, but the vertical spacing between grid rows.
Jul ’20
Reply to Is semantic search working with CSUserQuery?
Created an separate sample app, pretty sure this feature is not working as per video. import SwiftUI import CoreSpotlight import UniformTypeIdentifiers @main struct SemanticSearchApp: App { init() { // Prepare Core Spotlight for searching CSUserQuery.prepare() // Index sample items when app launches indexSampleItems() } var body: some Scene { WindowGroup { ContentView() } } private func indexSampleItems() { let items = [ ("windsurfing-1", "The Best Windsurfing Carmel County", "Learn about the best windsurfing spots in Carmel County"), ("windsurfing-2", "Windsurfing Lessons", "Professional windsurfing lessons for beginners"), ("windsurfing-3", "Sailboarding Lessons", "Expert sailboarding instruction in Carmel") ].map { (id, title, description) -> CSSearchableItem in let attributeSet = CSSearchableItemAttributeSet(contentType: .text) attributeSet.title = title attributeSet.contentDescription = description return CSSearchableItem( uniqueIdentifier: id, domainIdentifier: "com.example.windsurfing", attributeSet: attributeSet ) } // Use batch indexing for better performance let index = CSSearchableIndex(name: "SpotlightSearchSample") index.fetchLastClientState { state, error in if error == nil { index.beginBatch() index.indexSearchableItems(items) { error in if let error = error { print("Indexing error: \(error.localizedDescription)") } } // Create new state data (could be a timestamp or counter) let newState = "batch1".data(using: .utf8) ?? Data() index.endBatch(withClientState: newState) { error in if let error = error { print("Batch error: \(error.localizedDescription)") } } } } } } struct ContentView: View { @State private var query: String = "" @State private var searchResults: [SearchResult] = [] @State private var suggestions: [String] = [] @State private var allItems: [SearchResult] = [ SearchResult( id: "windsurfing-1", title: "The Best Windsurfing Carmel County", description: "Learn about the best windsurfing spots in Carmel County" ), SearchResult( id: "windsurfing-2", title: "Windsurfing Lessons", description: "Professional windsurfing lessons for beginners" ), SearchResult( id: "windsurfing-3", title: "Sailboarding Lessons", description: "Expert sailboarding instruction in Carmel" ) ] var body: some View { NavigationStack { List(query.isEmpty ? allItems : searchResults) { result in VStack(alignment: .leading) { Text(result.title) .font(.headline) Text(result.description) .font(.subheadline) .foregroundColor(.gray) } } .navigationTitle("Search Playground") .searchable( text: $query, prompt: "Search items", suggestions: { ForEach(suggestions, id: \.self) { suggestion in Text(suggestion) .searchCompletion(suggestion) } } ) .onChange(of: query) { newValue in performSearch(newValue) } } .padding() .frame(minWidth: 400, minHeight: 500) } private func performSearch(_ searchText: String) { guard !searchText.isEmpty else { searchResults = [] suggestions = [] return } let queryContext = CSUserQueryContext() queryContext.fetchAttributes = ["title", "contentDescription"] queryContext.maxSuggestionCount = 5 queryContext.enableRankedResults = true let searchQuery = CSUserQuery(userQueryString: searchText, userQueryContext: queryContext) Task { do { var newResults: [SearchResult] = [] var newSuggestions: [String] = [] for try await element in searchQuery.responses { switch element { case .item(let queryItem): if let title = queryItem.item.attributeSet.title, let description = queryItem.item.attributeSet.contentDescription { let result = SearchResult( id: queryItem.item.uniqueIdentifier, title: title, description: description ) newResults.append(result) } case .suggestion(let suggestion): newSuggestions.append(String(suggestion.suggestion.localizedAttributedSuggestion.characters)) @unknown default: break } } await MainActor.run { self.searchResults = newResults self.suggestions = newSuggestions } } catch { print("Search error: \(error.localizedDescription)") } } } } struct SearchResult: Identifiable { let id: String let title: String let description: String }
3w