iPhone SDK Primi passi con i dati JSON utilizzando l'API di Twitter

Le API accessibili al Web offrono una vasta gamma di risorse per estendere la funzionalità delle tue app per iPhone. Queste API tendono ad essere consumate in due formati di dati primari: XML e JSON. L'iPhone SDK ha il supporto integrato per l'analisi XML, e questo sarà trattato in un tutorial separato. In questo tutorial, ci concentreremo sull'aggiunta del supporto JSON alle tue applicazioni iOS dimostrando come creare un'applicazione client di lettura di Twitter.

introduzione

Il framework JSON è un framework estremamente popolare. È utilizzato per alimentare un'ampia porzione delle app comunemente utilizzate su App Store, tra cui l'app di Facebook, l'app di Google Maps e praticamente ogni singolo client Twitter in circolazione.

Perché JSON?

Ci sono un paio di motivi per scegliere JSON su XML. Il motivo principale per cui JSON è preferito è perché i file JSON sono generalmente più piccoli nelle dimensioni del file rispetto alle loro controparti XML, e questo naturalmente comporta meno tempo di caricamento. Un'altra ragione che vale la pena considerare è che il sistema di notifica push di Apple funziona meglio con i payload JSON.

1. Per iniziare

Creazione di un progetto Xcode

  1. Crea un nuovo progetto Xcode di tua scelta. Utilizzerò il modello View-Based.
  2. Scarica qui il framework JSON.

Aggiunta del framework

Aggiungere la struttura è semplice. Hai solo bisogno di trascinare i file nel tuo progetto. Esiste un'opzione per collegare la libreria al progetto, ma tale opzione è ora deprecata e non supportata.

  1. Trascina la cartella JSON dal DMG e rilasciatela nel progetto Xcode. Puoi aggiungerlo al gruppo "Altre fonti" se lo desideri.
  2. Quando richiesto, seleziona l'opzione "Copia gli elementi nella cartella del gruppo di destinazione".
  3. Inserisci:
     #import "JSON.h" 

    nei file di origine in cui verrà utilizzato il framework.

2. Utilizzo della libreria JSON

Un messaggio JSON di esempio

Il seguente è un messaggio JSON di esempio che rappresenta l'aspetto di un oggetto persona:

 "firstName": "John", "lastName": "Smith", "age": 25, "address": "streetAddress": "21 2nd Street", "city": "New York", "state" : "NY", "postalCode": "10021", "phoneNumber": ["type": "home", "number": "212 555-1234", "type": "fax", " numero ":" 646 555-4567 "] 

Analisi di una stringa JSON

Per analizzare quanto sopra, prima carichiamo il messaggio JSON in una NSString:

 NSString * jsonString = [[NSString alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @ "data" ofType: @ "json"] codifica: NSUTF8StringEncoding errore: & error]; 

Osservando il messaggio JSON di esempio, possiamo vedere che i dati sono incapsulati con entrambe le parentesi (ad es. [] ) e parentesi graffe (ad es. ). Le parentesi sono array di dati e le parentesi sono i dizionari dei dati. Come puoi vedere, siamo in grado di nidificare matrici di dizionari e gli oggetti dizionario possono contenere matrici per valori multipli.

Nell'esempio sopra, abbiamo un dizionario per il contatto con chiavi come nome, cognome, ecc. La chiave dell'indirizzo punta a un altro dizionario che contiene le sue coppie chiave-valore. La chiave phoneNumber nel dizionario contiene una serie di dizionari.

Per analizzare un array usiamo:

 Risultati NSArray * = [jsonString JSONValue]; 

Per analizzare un dizionario, utilizziamo:

 Dizionario NSDictionary * = [jsonString JSONValue]; NSArray * keys = [dictionary allKeys]; // le chiavi per il tuo dizionario 

Scegli quello che ti serve in base all'oggetto radice. Ad esempio, se la tua API restituisce un elenco di contatti, dovresti recuperare un array di dizionari di contatti. Allo stesso modo, se chiedi una timeline di Twitter, stai recuperando una serie di tweet in cui ogni tweet è un dizionario.

Creazione di una stringa JSON

La creazione di una stringa JSON è molto semplice e diretta. Si crea un NSDictionary con le Chiavi e i Valori appropriati o un NSArray con l'elenco di oggetti. Questo processo è abbastanza simile a come abbiamo analizzato il JSON nel passaggio precedente.

Dovresti creare un dizionario con i tuoi dati.

 NSDictionary * contactData = [Dizionario NSDictionaryWithObjectsAndKeys: _titleField.text, @ "title", _summaryField.text, @ "summary", _urlField.text, @ "url", _phoneField.text, @ "phone", _bdayField.text, @ " compleanno ", _addrField.text, @" indirizzo ", nil]; 

Aggiungi il tuo dizionario dati appena creato alla sua classe

 NSDictionary * finalData = [dizionario NSDictionaryWithObject: contactData forKey: @ "contact"]; 

Quindi genera la rappresentazione JSON del tuo dizionario di classe.

 NSString * newJSON = [finalData JSONRepresentation]; 

Puoi anche creare i tuoi array e nidificare dizionari o array di conseguenza.

Nota: non esiste alcun metodo nel framework JSON che convalidi se un messaggio è JSON valido.

3. Mettere tutto insieme

Creiamo una semplice app per iPhone che mostra un elenco degli ultimi 5 tweet che contengono mobtuts.

Utilizzeremo l'API di ricerca di Twitter per semplicità perché non richiede autenticazione o autorizzazione.

Un tweet

L'URL per la nostra richiesta è:

 http://search.twitter.com/search.json?q=mobtuts&result_type=recent

Questo ci restituirà un risultato di dizionario che contiene una serie di tweet.

Per semplificare la vita, concentriamoci solo sull'URL dell'immagine del profilo dell'utente, sul testo del tweet e sul nome twitter dell'utente.

Un singolo tweet risultante assomiglia a questo:

 "profile_image_url": "http://a3.twimg.com/profile_images/949941117/zucker_normal.jpg", "created_at": "Gio, 10 giu 2010 03:54:22 +0000", "from_user": "mariacarol "," metadata ": " result_type ":" recent "," to_user_id ": null," text ":" RT @mobtuts: come installare Android 2.2 Froyo su iPhone http://bit.ly/c8kBb6 ", "id": 15824617764, "from_user_id": 311.442, "geo": null, "iso_language_code": "en", "fonte": "Seesmic",  "profile_image_url": "http://a1.twimg.com /profile_images/655595496/retro9_normal.gif","created_at":"Thu, 10 giu 2010 03:52:28 +0000 "," from_user ":" cead22 "," metadata ": " result_type ":" recent " , "to_user_id": null, "text": "Quiero un # iPhone4 con #FroYo - Come installare Android 2.2 Froyo su iPhone http://bit.ly/c8kBb6 (@mobtuts)", "id": 15824510273, "from_user_id": 34036310, "geo": null, "iso_language_code": "en", "source": "Twitter per BlackBerry \ u00ae", "profile_image_url": "http://a1.twimg.com/profile_images /769690946/mobiletuts_icon_normal.png","created_at":"Thu, 10 giu 2010 03:45:51 +0000 "," from_user ":" mobtuts ", "metadata": "result_type": "recent", "to_user_id": null, "text": "Iscriviti ora al podcast @mobtuts! Scegli RSS http://bit.ly/9LMbGX o iTunes http://bit.ly/bq0QMC","id":15824135971,"from_user_id":104427899,"geo":null,"iso_language_code":"en ", "source": "HootSuite", "profile_image_url": "http://a1.twimg.com/profile_images/63581538/tutsplus_normal.jpg", "created_at": "Gio, 10 Jun 2010 03:25:00 + 0000 "," from_user ":" tutsplus "," metadata ": " result_type ":" recent "," to_user_id ": null," text ":" Iscriviti subito al podcast @mobtuts! Scegli RSS http://bit.ly/9LMbGX o iTunes http://bit.ly/bq0QMC","id":15822900558,"from_user_id":2295627,"geo":null,"iso_language_code":"en ", "source": "TweetDeck", "profile_image_url": "http://a1.twimg.com/profile_images/234225566/illustration_normal.jpg", "created_at": "Gio, 10 Jun 2010 03:22:33 + 0000 "," from_user ":" GreatTwitTips "," metadata ": " result_type ":" recent "," to_user_id ": null," text ":" RT @mobtuts: RT @berryizm_feeds: 5 BlackBerry Theme Developer Tips da MMMOOO un tema BlackBerry e un app di sviluppo comp ... http://bit.ly/agf0ND","id":15822755393,"from_user_id":19637346,"geo":null,"iso_language_code":"en","source ": "feed di Twitter" 

Possiamo vedere che stiamo cercando i tasti "profile_image_url", "from_user" e "text" per la nostra app.

The Parser

Creiamo un semplice parser JSON e facciamo la richiesta dall'API.

Twitter_SearchAppDelegate.h

 #importare  @class Twitter_SearchViewController; @interface Twitter_SearchAppDelegate: NSObject  Finestra UIWindow *; NSMutableData * responseData; Twitter_SearchViewController * viewController;  @property (nonatomic, retain) Finestra IBOutlet UIWindow *; @property (nonatomic, retain) IBOutlet Twitter_SearchViewController * viewController; @fine 

Ora aggiungeremo il framework JSON alle istruzioni di importazione.

Twitter_SearchAppDelegate.m

 #import "JSON.h" 

Da qui, modificheremo il metodo doneFinishLaunchingWithOptions nel Delegato app e faremo un NSURLRequest a Twitter con l'URL per afferrare i tweet che vogliamo elaborare. Imposteremo anche il delegato dell'app come il delegato di NSURLRequest.

 - Applicazione (BOOL): applicazione (UIApplication *) didFinishLaunchingWithOptions: (NSDictionary *) launchOptions // Punto di sostituzione per la personalizzazione dopo l'avvio dell'applicazione. // Aggiungi la vista del controller di visualizzazione alla finestra e visualizza. responseData = [[Dati NSMutableData] retain]; tweets = [NSMutableArray array]; NSURLRequest * request = [NSURLRequest requestWithURL: [NSURL URLWithString: @ "http://search.twitter.com/search.json?q=mobtuts&rpp=5"]]; [[NSURLConnection alloc] initWithRequest: request delegate: self]; return YES;  

Ora, dal momento che il nostro delegato dell'app è il delegato di NSURLRequest, dobbiamo implementare questi metodi delegati. Siamo interessati principalmente ad essere avvisati quando i dati ci vengono inviati e quando la richiesta è completa e non ci sono più dati da ricevere.

 #pragma mark NSURLConnection Delegate methods - (void) connection: (NSURLConnection *) connection didReceiveResponse: (NSURLResponse *) response [responseData setLength: 0];  - connessione (void): connessione (NSURLConnection *) didReceiveData: (NSData *) data [responseData appendData: data];  - (void) connection: (NSURLConnection *) connection didFailWithError: (NSError *) error label.text = [NSString stringWithFormat: @ "Connessione fallita:% @", [descrizione errore]];  

Questo è dove il nostro parser sta facendo la maggior parte del lavoro. Sta analizzando il file JSON e creando l'array di tweet per noi. Otteniamo la matrice e la passiamo al TableViewController per visualizzarla.

 - (void) connectionDidFinishLoading: connessione (NSURLConnection *) [connessione release]; NSString * responseString = [[NSString alloc] initWithData: responseData encoding: NSUTF8StringEncoding]; [responseData release]; NSDictionary * results = [responseString JSONValue]; NSArray * allTweets = [risultati objectForKey: @ "results"]; [viewController setTweets: allTweets]; [window addSubview: viewController.view]; [window makeKeyAndVisible];  

Un semplice TableView

Ora usiamo semplicemente la matrice creata dal parser per visualizzare i dati nel nostro TableView.

Twitter_SearchViewController.h

 #importare  @interface Twitter_SearchViewController: UITableViewController NSArray * tweets; // questo è l'array che ci è stato passato dal Delegato app @property (nonatomic, retain) tweets NSArray *; @fine 

TweetsTableViewController.m

Nel controller, dobbiamo prima sintetizzare la proprietà e quindi impostare il numero di righe che visualizzeremo

 @sintendere tweets; - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) section // Restituisce il numero di righe nella sezione. return [tweets count];  

Infine, mostreremo i tweet facendo riferimento alle loro chiavi specifiche dal dizionario. Guardando prima la stringa JSON, sappiamo che stiamo cercando i valori associati ai tasti "from_user", "profile_image_url" e "text".

 // Personalizza l'aspetto delle celle di visualizzazione tabella. - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath static NSString * CellIdentifier = @ "Cell"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; if (cell == nil) cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: CellIdentifier] autorelease];  // Configura la cella ... NSDictionary * aTweet = [tweets objectAtIndex: [indexPath row]]; cell.textLabel.text = [aTweet objectForKey: @ "text"]; cell.textLabel.adjustsFontSizeToFitWidth = YES; cell.textLabel.font = [UIFont systemFontOfSize: 12]; cell.textLabel.numberOfLines = 4; cell.textLabel.lineBreakMode = UILineBreakModeWordWrap; cell.detailTextLabel.text = [aTweet objectForKey: @ "from_user"]; NSURL * url = [NSURL URLWithString: [aTweet objectForKey: @ "profile_image_url"]]; NSData * data = [NSData dataWithContentsOfURL: url]; cell.imageView.image = [UIImage imageWithData: data]; cell.selectionStyle = UITableViewCellSelectionStyleNone; cella di ritorno;  

Considerazioni aggiuntive

Se hai intenzione di utilizzare Three20 o httpriot, non è necessario aggiungere il framework JSON. Questi progetti lo includono già nel loro codice. Se hai intenzione di utilizzare ASIHTTPRequest, il framework JSON non è incluso e devi aggiungerlo tu stesso.