2015-09-05 9 views
5

Sto cercando di ottenere l'accesso a un valore di registrazione in CloudKit, qui MyPin, ha un titolo & attributo sottotitoli/valore del campo. Tuttavia può succedere che a volte il valore record è vuota (qui il sottotitolo), e si blocca alla linea quando chiamo: esistonoIl codice si blocca durante il caricamento di un attributo vuoto da Cloudkit - utilizzando Swift

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

perchè Annot["Subtitle"] doesn ...

Quando faccio

println(Annot["Subtitle"]) 

restituisce nil

ma se lo faccio:

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

ho mai inserire l'istruzione if:

qualcuno può aiutarmi come identificare se il record ha un valore vuoto?

Qui è la mia linea di codici:

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 
}} 

risposta

2

quando si arriva Annot["Subtitle"] vi darà un ritorno CKRecordValue? che ha un classe base di NSObjectProtocol. Quindi nel tuo caso il campo esiste ma non è una stringa, quindi lanciarlo usando come! La stringa interromperà la tua app. Poiché il campo esiste, lo CKRecordValue non sarà nullo. Tuttavia il contenuto di quel campo è nullo. Quando si stampa il campo, verrà emesso il .description di quel campo. Nel tuo caso è nulla. Potresti provare questo codice invece:

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

quindi impostare un punto di interruzione sulla linea di stampa e quando si ferma provare i seguenti tre affermazioni nella vostra finestra di output:

po Annot 
po f 
p f 

Dopo la po Annot si dovrebbe vedere cosa c'è in quel disco. Compreso il tuo campo sottotitoli. Il po f non è così interessante. Produrrà solo un indirizzo di memoria. Il p f tuttavia mostrerà il tipo effettivo. Se è una stringa dovresti vedere qualcosa del tipo: (__NSCFConstantString *) $R3 = 0xafdd21e0

P.S. Forse dovresti chiamarlo record invece di Annot. È una variabile locale quindi dovrebbe iniziare con un carattere minuscolo. Ed è ancora un record e non un Annot.

+0

Grazie Edwin sono riuscito a risolvere il problema con il tuo consiglio. –

1

Penso che si sta facendo la cosa giusta, ma non si vede il println come viene eseguito in un altro thread (la parte di completamento viene eseguito in modo asincrono) . Prova questo:

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

e vedere se funziona!

Il modo in cui ottengo i valori dal cloudkit è in questo modo. Entrambi si prendono cura dei valori nulli e di tutte le altre eventualità. Basta notare Ho implementato un delegato per ottenere i miei risultati al oggetto chiamante in modo asincrono

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 
      } 
     } 
    } 

Attenzione, ci sono alcuni cambiamenti in Swift2

+0

Grazie per la tua risposta, ma senza fortuna, ancora non stampandolo :-( –