Unable to populate value from CloudKit onto my display

Hello everyone! I am pretty new to SwiftUI and have been trying to figure out a solution to the issue below for about a week.

I can successfully save values in CloudKit, and can load them within the operation.recordFetchedBlock block using print(String(ping.value)) on line 15. However, I can not figure out a way to actually load them on the display within ContentView: View For some reason I continue to get the following (empty array) in the output when using print(loadPing()) on line 9:

[] No Error Found

Below is the code:

struct ContentView: View {
    @StateObject var progress = UserProgress()

    var body: some View{
        VStack{
            Button("Submit") {
                progress.ping += 1
                sendItem(counter: progress.ping)
                print(loadPing())
            }
            Text("Ping Count \(progress.ping)")
        }
    }
}
class Ping: NSObject {
    let id = UUID()
    var recordID: CKRecord.ID!
    var name: String!
    var value: String!
}
loadPing() -> [Ping]{
    var newPing = [Ping]()
    let ping = Ping()
    let query = CKQuery(recordType: "PingTest", predicate:      NSPredicate(value: true))
    let operation = CKQueryOperation(query: query)

    operation.desiredKeys = ["value", "name"]
    operation.recordFetchedBlock = { record in
        ping.recordID = record.recordID
        ping.name = record["name"]
        ping.value = record["value"]
        newPing.append(ping)

//        print(String(ping.value))
    }

    operation.queryCompletionBlock = {(cursor, error) in
            DispatchQueue.main.async {
                if error == nil {
                    print("No Error Found")
                } else {
                    print("Error was Found")
                    print(error!.localizedDescription)
                }
            }
        }
     CKContainer.default().publicCloudDatabase.add(operation)
    return newPing
}

I would be very grateful if someone could help me figure out a way to populate the actual values from CloudKit onto my display in the ContentView. I have sifted through various tutorials but nothing has worked so far.

Accepted Reply

You could use the new public sample projects to get started. Take a look at cloudkit-sample-privatedb for a simple starting point.

  • I've been battling this problem for some time now, and the sample you provided helped to resolve my issue. Thank you very much!!

Add a Comment

Replies

Hi,

I can see a couple of mistakes.

The first one, you should create your new Ping() inside your recordFetched block, and I would use a struct, not a class.

The second is that you are printing the return from loadPing(), that will print to your console only.

If you want to automatically show them, you should fetch them from an ObservableObject, similar to what it seems to be UserProgress. Basically you create a model, and your results as @Published array that you can put in a ForEach.

Finally, your operations run asynchronously. Probably your return is return an empty array because the operations are still running in another thread.

You make a really good point! Im going to research the ObservableObject wrapper and go from there. Thanks for your input!

You could use the new public sample projects to get started. Take a look at cloudkit-sample-privatedb for a simple starting point.

  • I've been battling this problem for some time now, and the sample you provided helped to resolve my issue. Thank you very much!!

Add a Comment