Chi siamoContattiDisclaimer

Swift UITableView: caricare dati da json

In questo tutorial ti spiegherò come riempire le celle di un UITableView caricando i dati direttamente da un URL utilizzando il formato JSON. Vedrai come definire una tableview controller utilizzando swift, come scaricare i dati da URL e come estrarre i dati nel formato JSON.

Definizione del progetto

Crea un nuovo progetto Swift a singola vista.

Nel Main.storyboard puoi disattivare l'opzione use size classes

 Ora puoi rimuovere la View controller che è già inserita di default nello storybord, non ne abbiamo bisogno!

  

Definizione del layout e delle classi personalizzate

Nel Main.storyboard aggiungi la componente UITableViewController.

 

Ora devi definire una classe personalizzata per il UITableViewController.

Crea una nuova classe di tipo iOS Cocoa Toach Class, sotto classe di UITableViewController e chiamala TableController.

Swift: add custom class

 Ora nel Main.storyboard seleziona la tua UITableViewController e nell'identity inspector imposta la classe appena creata (TableController).

 

Swift: set custom class

 Nell'attribute inspector attiva l'opzione is initial view controller.

Swift: is initial controller

 

Ora seleziona la cella della tabella e nella sezione attribute inspector imposta come l'identificativo cell.

Swift: cell identifier

 

Classe TableController

Ora è da implementare le classe TableController. Tramite questa classe definiremo la funzione di download, la funzione di estrazione dei dati e la cella stessa.

La prima cosa da fare è definire l'array che verrà usato per salvare e leggere i dati. Definiamo l'array TableData come:

var TableData:Array< String > = Array < String >()

La funzione viewDidLoad è la funzione che viene chiamata non appena la vista è stata caricata. All'interno va chiamata la funzione get_data_from_url. Definiremo questa funzione più tardi, ma intanto inserisci la chiamata di funzione.

var TableData:Array< String > = Array < String >()
override func viewDidLoad() {
      super.viewDidLoad()
      get_data_from_url("https://www.kaleidosblog.com/tutorial/tutorial.json")
}

A questo link puoi trovare l'oggetto json utilizzato per questo esempio. L'oggetto utilizzato in questo esempio è una lista di paese e codici di paesi. Imposta il numero di sezioni a 1 e il numero di celle uguale alla dimensione dell'array.

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
     return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     return TableData.count
}

 Ora devi configurare la cella per caricare i dati alla posizione definita dall'oggetto indexPath. L'identificatore "cell" è lo stesso identificatore utilizzato precedentemente nella definizione della cella. La funzione cellForRowAtIndexPath è chiamata per ogni cella che è visibile nello schermo ad un particolare istante. Per esempio, se vuoi caricare 200 celle nella tabella, questa funzione è chiamata solamente 10-15 volte, questo perchè solo gli elementi visibili che devono essere mostrati vengono caricati. Ogni volta che fai lo scroll della tabella, questa funzione è chiamata di nuovo per i successivi elementi che devono essere mostrati.
In questo caso utilizzeremo la textlabel che è definita nel layout della cella.

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
     let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
     cell.textLabel?.text = TableData[indexPath.row]
     return cell
}

 Definiamo ora la funzione get_data_from_url sfruttando la chiamata asincrona di iOS.

func get_data_from_url(url:String)
{
    let httpMethod = "GET"
    let timeout = 15
    let url = NSURL(string: url)
    let urlRequest = NSMutableURLRequest(URL: url!,
    cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData,
    timeoutInterval: 15.0)
    let queue = NSOperationQueue()
    NSURLConnection.sendAsynchronousRequest(
                                  urlRequest,
                                  queue: queue,
                                  completionHandler: {(response: NSURLResponse!,
                                                                   data: NSData!,
                                                                   error: NSError!) in
             if data.length > 0 && error == nil{
                 let json = NSString(data: data, encoding: NSASCIIStringEncoding)
                 self.extract_json(json!)
             }else if data.length == 0 && error == nil{
                 println("Nothing was downloaded")
             } else if error != nil{
                 println("Error happened = \(error)")
             }
         }
     )
}

 Quando la funzione get_data_from_url ha terminato di scaricare i dati, la funzione extract_json viene chiamata. Questa funzione  estrarrà i dati json e riempirà l'array TableData. In un formato JSON ci sono due principali tipi: gli array e gli oggetti. Gli array sono identificati dalle parentesi [ ] mente gli oggetti sono identificati dalle parentesi { }. Questi due tipi in Swift sono definiti da: NSArray e NSDictionary. Per ogni oggetto JSON devi definire una varialbile sicura (utilizzando il punto di domanda) con il tipo giusto. Questo ti permette di gestire gli errori nel caso in cui il formato JSON non sia valido. I dati JSON utilizzati in questo esempio hanno la seguente struttura:

array
   Object
       name (String)
       code (String)
   ...
   Object
       name (String)
       code (String)

 Definiamo ora la funzione di estrazione dei dati json:

func extract_json(data:NSString)
{
     var parseError: NSError?
     let jsonData:NSData = data.dataUsingEncoding(NSASCIIStringEncoding)!
     let json: AnyObject? = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: &parseError)
     if (parseError == nil)
     {
        if let countries_list = json as? NSArray
        {
           for (var i = 0; i < countries_list.count ; i++ )
           {
               if let country_obj = countries_list[i] as? NSDictionary
               {
                   if let country_name = country_obj["country"] as? String
                   {
                       if let country_code = country_obj["code"] as? String
                       {
                             TableData.append(country_name + " [" + country_code + "]")
                       }
                   }
                }
            }
        }
     }
     do_table_refresh();
}

 Ora abbiamo i dati nell'array TableData, dobbiamo solo fare il refresh della tabella.

func do_table_refresh()
{
     dispatch_async(dispatch_get_main_queue(), {
         self.tableView.reloadData()
        return
     })
}

 Scarica il progetto di questo esempio da qui.

Swift: TableView tutorial

 

Lascia un commento








Commenti


- 01 February 2016 at 16:41
Complimenti per il Blog. Ho visto che hai anche un esempio compilato con Swift2 in Inglese, ma non è molto documentato. Sbaglio?
Andrea - 01 February 2016 at 20:56
Ciao, grazie per il commento, si il tutorial era stato fatto un pò di tempo fa utilizzando la versione precedente di Swift, il progetto è stato aggiornato alla versione 2. Nei prossimi giorni scrivo un nuovo articolo documentato con Swift 2. Ti avviso non appena è disponibile.





Chi siamoContattiPrivacyDisclaimer