2014-08-30 9 views
6

Come si converte un oggetto di tipo (NSObject, AnyObject) nel tipo String?'(NSObject, AnyObject)' non è convertibile in 'String'

Alla fine della prima riga del metodo seguito, as String causa l'errore del compilatore:

'(NSObject, AnyObject)' is not convertible to 'String' 

Casting street a NSString invece di String compila, ma sto gettando street a String perché voglio confrontarlo con placemark.name, che ha il tipo String!, non NSString.

so name e street sono optional, ma sto supponendo che non sono nil per ora, perché tutti i luoghi tornato da MKLocalSearch sembrano avere i nomi non-nil e strade.

func formatPlacemark(placemark: CLPlacemark) -> (String, String) { 
    let street = placemark.addressDictionary["Street"] as String 
    if placemark.name == street { 
     // Do something 
    } 
} 

risposta

6

Un String non è un oggetto, in modo che non ha bisogno di lanciare a un NSString. Raccomanderei la seguente sintassi per lanciarlo e scartarlo allo stesso tempo. Non preoccuparti di confrontarlo con una variabile di tipo String! poiché sono compatibili. Ciò funzionerà:

func formatPlacemark(placemark: CLPlacemark) -> (String, String) { 
    if let street = placemark.addressDictionary["Street"] as? NSString { 
     if placemark.name == street { 
      // Do something 
     } 
    } 
} 

Questo ha l'ulteriore vantaggio che, se "Street" non è una chiave valida nel vostro dizionario o se il tipo di oggetto è qualcosa di diverso da NSString, questo non crash. Semplicemente non entrerà nel blocco.

Se davvero vuole strada per essere un String si potrebbe fare questo:

if let street:String = placemark.addressDictionary["Street"] as? NSString 

ma non ti comprare nulla in questo caso.

+0

Come sai che posso fare 'segnaposto.nome == street' invece di 'street.isEqualToString (placemark.name)'? Voglio assicurarmi di controllare l'uguaglianza delle stringhe ('isEqualToString'), non l'identità dell'oggetto (' == '). – ma11hew28

+0

Swift collega automaticamente i due tipi, e '==' è il modo rapido di testare l'uguaglianza delle stringhe. Vedi: https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html – vacawama

+0

Provalo in un parco giochi. Vedrai che funziona come vorresti. – vacawama

1

penso che possa avere a che fare con addressDictionary essere un NSDictionary.

Se si converte addressDictionary in un dizionario Swift, dovrebbe funzionare.

let street = (placemark.addressDictionary as Dictionary<String, String>)["String"] 
+0

Ma, è più lento della [soluzione di @ vacawama] (http://stackoverflow.com/a/25582668/242933)? Perché 'Dictionary' non è completamente diverso da' NSDictionary'? Quindi, ciò significherebbe lanciando il 'NSDictionary' a' Dictionary', il programma dovrà creare un oggetto 'Dictionary' completamente nuovo e riempirlo con le chiavi e i valori dell'originale' NSDictionary'? Sembra più un lavoro che un semplice cast. – ma11hew28

+0

Questo non è sicuro. Se qualsiasi valore nel dizionario è un oggetto diverso da un 'NSString', ciò causerà il crash dell'applicazione. Lo faresti solo se tu fossi al 100% sicuro che tutti gli oggetti fossero 'NSString's, e lo faresti solo una volta, quando i dati verranno creati per la prima volta. Se stai chiamando un'API esterna alla tua app per ottenere il 'NSDictionary', sarebbe più sicuro controllare ogni oggetto con il modulo opzionale dell'operatore di cast type (' as? '). – vacawama

2

Il tipo restituito da guardare tramite indice per un dizionario rapida deve essere un optional in quanto non vi può essere alcun valore per la chiave data.

Perciò si deve fare:

as String? 
+1

'as String?' Indica lo stesso errore del compilatore. – ma11hew28