Hello guys,
I am trying to build a search box to fetch cloudkit items, based on the great post bellow by @NigelGee
https://www.hackingwithswift.com/forums/swiftui/show-cloudkit-public-database-info-in-list/2057
I am stuck tryng to pass data from Search input to CKQuery predicate.
@Binding var inputText: String
let query = CKQuery(recordType: "Shoes", predicate: inputText)
Really appreciate any inputs! : )
Cheers to all
SearchBar file
import SwiftUI
struct SearchBar: View {
@Binding var inputText: String
@State private var isEditing = false
var body: some View {
HStack {
//SearchBox
TextField("Search ...", text: $inputText)
.padding(7)
.padding(.horizontal, 25)
.background(Color(.systemGray6))
.cornerRadius(8)
.overlay(
HStack {
Image(systemName: "magnifyingglass")
.foregroundColor(.gray)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.padding(.leading, 8)
if isEditing {
Button(action: {
self.inputText = ""
}) {
Image(systemName: "multiply.circle.fill")
.foregroundColor(.gray)
.padding(.trailing, 8)
}
}
}
)
.padding(.horizontal, 10)
.onTapGesture {
self.isEditing = true
}
if isEditing {
Button(action: {
self.isEditing = false
self.inputText = ""
// Dismiss the keyboard
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}) {
Text("Cancel")
}
.padding(.trailing, 10)
.transition(.move(edge: .trailing))
.animation(.default)
}
}
}
}
struct SearchBar_Previews: PreviewProvider {
static var previews: some View {
SearchBar(inputText: .constant(""))
}
}
import Foundation
import CloudKit
class Shoes: ObservableObject {
@Published var lists: [Shoe] = []
}
struct Shoe: Identifiable {
var id = UUID()
var recordID: CKRecord.ID?
var brand: String = ""
var name: String = ""
var size: Int = 0
}
CKShoe file:
import Foundation
import CloudKit
class CKShoe {
static let database = CKContainer.default().publicCloudDatabase
class func fetch(completion: @escaping (Result<[Shoe], Error>) -> ()) {
let predicate = NSPredicate(value: true)
let name = NSSortDescriptor(key: "name", ascending: true)
let query = CKQuery(recordType: "Shoes", predicate: predicate)
query.sortDescriptors = [name]
let operation = CKQueryOperation(query: query)
operation.desiredKeys = ["brand", "name", "size"]
operation.resultsLimit = 50
var newShoes = [Shoe]()
operation.recordFetchedBlock = { record in
var shoe = Shoe()
shoe.recordID = record.recordID
shoe.brand = record["brand"] as! String
shoe.name = record["name"] as! String
shoe.size = record["size"] as! Int
newShoes.append(shoe)
}
operation.queryCompletionBlock = { (cursor, error) in
DispatchQueue.main.async {
if let error = error {
completion(.failure(error))
} else {
completion(.success(newShoe))
}
}
}
database.add(operation)
}
List file:
import SwiftUI
struct ContentView: View {
@EnvironmentObject var shoes: Shoes
var body: some View {
//insert seach bar here on top of List
List {
ForEach(shoes.lists, id: \.id) { shoe in
Text(shoe.name) // What you want to show in List
}
}
.onAppear(perform: loadShoes)
}
private func loadShoes() {
CKShoe.fetch { (results) in
switch results {
case .success(let newShoes):
self.shoes.lists = newShoes
case .failure(let error):
print(error) // handle error
}
}
}
}
SceneDelegate file
let lists = Shoes()
let contentView = ContentView().environmentObject(lists)