6

I want to fetch only Song_Name field in Musics records in CloudKit. I'm trying below code but It still fetches all the fields in Music record. I think I need to compile operation with publicDB.add(operation) method but It doesn't allow me to declare ¨results¨ as I do now with publicDB.perform(query, in....)

 let predicate = NSPredicate(value: true)
    let query = CKQuery(recordType: "Musics", predicate: predicate)
    let operation = CKQueryOperation(query: query)
    operation.desiredKeys = ["Song_Name"]

    publicDB.perform(query, inZoneWith: nil) { [unowned self] results, error in

        guard error == nil else {
            DispatchQueue.main.async {
                self.delegate?.errorUpdating(error! as NSError)
                print("Cloud Query Error - Refresh: \(error)")
            }
            return
        }
        self.items_music.removeAll(keepingCapacity: true)
        for record in results! {
            let music = Musics(record: record, database: self.publicDB)
            self.items_music.append(music)
        }
        DispatchQueue.main.async {
            self.delegate?.modelUpdated()
        }
    }
}
2
  • 3
    Please define "isn't working". That's the most useless phrase a programmer can use. Be specific. Is it an error when you compile? Does it crash? Does it simply not do what you expect? Edit your question with error message or debugging information. Clearly explain what your code actually does and clearly explain what you are expecting it to do. Make it easy for people to help you. Do not post this info in comments. Please edit your question with the relevant details. Commented Feb 22, 2017 at 19:56
  • @rmaddy I edited the description, yea I noticed that now. Sorry for that. Commented Feb 22, 2017 at 19:59

1 Answer 1

6

You are creating a CKQueryOperation and setting the operation's desiredKeys property, but then you are not using this operation. You simply perform a query against the database, so none of the query operation's properties will be used.

You need to assign a record fetched block and query completion block to your operation and then add the operation to the database to actually run it.

let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: "Musics", predicate: predicate)
let operation = CKQueryOperation(query: query)
operation.desiredKeys = ["Song_Name"]
var newItems = [Musics]()
operation.queryCompletionBlock = ( { (cursor, error)->Void in
    guard error == nil else {

        DispatchQueue.main.async {
            self.delegate?.errorUpdating(error! as NSError)
            print("Cloud Query Error - Refresh: \(error)")
        }
        return
    }
    self.items_music = newItems
    DispatchQueue.main.async {
        self.delegate?.modelUpdated()
    }
})

operation.recordFetchedBlock = ( { (record) -> Void in
    let music = Musics(record: record, database: self.publicDB)
    newItems.append(music)
})

publicDB.add(operation)

I have omitted some code that you will need that checks the cursor provided to the completion block. If this isn't nil then you need to issue another query to fetch additional items

Sign up to request clarification or add additional context in comments.

2 Comments

operation.recordFetchedBlock line gives this error " Cannot assign value of type '(() -> Void, Void)' (aka '(() -> (), ())') to type '((CKRecord) -> Void)?'"
For for my last comment. It is working. Just there is one ")" is missing after operation.recordFetchedBlock function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.