Code Failure loading empty attribute from Cloudkit - using Swift

I am trying to access the value of a record in CloudKit, here is MyPin, it has a title / subtitle attribute / field value. However, it may happen that sometimes the value of the record is empty (subtitles here), and it crashes in the line when I call:

var tempS: String = Annot["Subtitle"] as! String 

because Annot["Subtitle"] does not exist ...

When i do

 println(Annot["Subtitle"]) 

he returns nil

but if I do this:

 if (Annot["Subtitle"] == nil) { println("just got a nil value") } 

I never enter the if statement:

Can someone help me determine if a record has a null value?

Here is my line of codes:

 let container = CKContainer.defaultContainer() let publicData = container.publicCloudDatabase let query = CKQuery(recordType: "MyPin", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil)) publicData.performQuery(query, inZoneWithID: nil) { results, error in if error == nil { // There is no error for Annot in results { var tempS: String = Annot["Subtitle"] as! String }} 
+5
source share
2 answers

when you get Annot["Subtitle"] , will you get a CKRecordValue? response CKRecordValue? which has the base class NSObjectProtocol . Thus, in your case, the field exists, but it is not a string, so it should be used using! String will crash your application. Since the field exists, CKRecordValue will not be nil. However, the content of this field is zero. When you print the field, it will output .description this field. In your case, it is zero. Could you try this code:

 if let f = Annot["Subtitle"] { print("f = \(f) of type \(f.dynamicType)") } 

then set a breakpoint on the print line and when it stops, try the following three statements in the output window:

 po Annot po f pf 

After po Annot you will see that in this entry. Including subtitle field. po f not so interesting. It will simply output the memory address. However, pf will show you the actual type. If this is a line, you should see something like: (__NSCFConstantString *) $R3 = 0xafdd21e0

PS Maybe you should call it a record instead of Annot. This is a local variable, so it must begin with a lowercase character. And it's still a record, not Annot.

+2
source

I think you are doing the right thing, but you do not see println as it is being executed in another thread (part of the completion is asynchronous). Try the following:

 if (Annot["Subtitle"] == nil) { dispatch_async(dispatch_get_main_queue()) { println("just got a nil value") } } 

and see if it works!

This way I get the values ​​from the cloud type. This takes care of zero values ​​and all other events. Just notice that I have implemented a delegate to return my results back to the caller asynchronously

 privateDB.performQuery(query, inZoneWithID: nil) { (result, error) -> Void in if error == nil{ for record in result{ let rec = record as! CKRecord if let xxxVar = rec.valueForKey("fieldName") as? String{ myArray.append( xxxVar! ) //append unwrapped xxxVar to some result or whatever }else{ //handle nil value } } dispatch_async(dispatch_get_main_queue()) { //do something with you data self.delegate?.myResultCallBack(myArray) return } }else{ dispatch_async(dispatch_get_main_queue()) { self.delegate?.myErrorCallBack(error) return } } } 

Beware there are some changes in Swift2

+1
source

All Articles