Swift 2 - Variable with null value

Asked

Viewed 328 times

2

I have a web page that returns the following json structure:

[  
   {  
      "nomeDoServico":"fdPHost",
      "nomeParaExibicao":"Host de Provedor da Descoberta de Função",
      "status":"Iniciado"
   },
   {  
      "nomeDoServico":"LanmanWorkstation",
      "nomeParaExibicao":"Estação de trabalho",
      "status":"Iniciado"
   }
]

The code below written in Swift 2 should take this return and per hour fill the tableView with only the value nameServico. However, when I print I see that the function consultService failed to popular the variable values:

import UIKit

class ViewController: UIViewController, UITableViewDelegate {

    var valores = [Dictionary<String, String>]()

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return valores.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
        let valor = valores[indexPath.row]
        cell.textLabel?.text = valor["nomeDoServico"]
        return cell
    }

    func consultarServico() -> Void
    {
        let myUrl = NSURL(string: "http://192.168.56.101/database_servico.php")
        let request = NSMutableURLRequest(URL:myUrl!)

        let postString:String = "id_menu=1"
        request.HTTPMethod = "POST"
        request.timeoutInterval = 5.0

        request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);

        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) in

            if (error?.code == -1001)
            {
                print("Opa, timeout")
            }

            do {
                let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! [Dictionary<String, String>]
                self.valores = jsonResult
            }
            catch
            {
                print("Erro ao buscar os dados")
            }
        }

        task.resume()
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // ocultar teclado ao clicar na view
        let tap:UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "DismissKeyboard")
        self.view.addGestureRecognizer(tap)

        consultarServico()
    }

    // encerra o teclado
    func DismissKeyboard(){
        self.view.endEditing(true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

Could someone please help me?

  • Have you checked what comes in response?

  • Try instead of placing on a Let, calling the values[indexPath.Row] straight into the cell string

  • I’ve tried that, but the problem is that I’m not actually able to fill in the "values" variable with the return of json. I think it would be more accurate to say that I’m not getting the callback.

  • The json is being returned, I already tested it and the return is what I passed in the first block of code. But I’m not able to play this return inside the variable "values".

  • When you pass self.valores = jsonResult, is passing an immutable object to a mutable object, try to create a new object by taking as a basis the jsonResult using the method initWithDictionary

  • I’ve tried a lot of alternatives, but nothing works. From what I could see I can’t get the returned json inside the clousure "closure" and cry into an external variable the same.

  • Can you post this url somewhere so I can simulate?

  • I published a similar json I’m using at: http://fabiojanio.com/json/json.php

  • Fábio, here we do not mark the question as solved in the title, just accept an answer as you already did.

Show 4 more comments

1 answer

1


I tested here with your code and the return is saved in the variable normally.

You just need to change a few points.

1) Your json is a array and not a dicionary, change to:

var values: Nsarray = []

2) When you receive the data in the request switch to:

Let jsonResult = Try Nsjsonserialization.Jsonobjectwithdata(data!, options: Nsjsonreadingoptions.Mutablecontainers) as! Nsarray

3) Give a reload in the table as soon as you get the data:

self.tableView.reloadData()

4) In the tableView(_:numberOfRowsInSection:) change to:

Let value = values[indexPath.Row] as! Nsdictionary

Cell.textLabel?. text = value["useName"] as? String


Follow the full code

class TesteViewController: UIViewController, UITableViewDelegate {
        
    var valores: NSArray = []
    
    @IBOutlet weak var tableView : UITableView!
    
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return valores.count
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
        let valor = valores[indexPath.row] as! NSDictionary
        cell.textLabel?.text = valor["nomeDoServico"] as? String
        return cell
    }
    
    func consultarServico() -> Void
    {
        let myUrl = NSURL(string: "http://fabiojanio.com/json/json.php")
        let request = NSMutableURLRequest(URL:myUrl!)
        
        let postString:String = "id_menu=1"
        request.HTTPMethod = "POST"
        request.timeoutInterval = 5.0
        
        request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
        
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) in
            
            if (error?.code == -1001)
            {
                print("Opa, timeout")
            }
            
            do {
                let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray
                
                self.valores = jsonResult
                
                self.performSelectorOnMainThread(Selector("atualizaTabela"), withObject: nil, waitUntilDone: false)
            }
            catch
            {
                print("Erro ao buscar os dados")
            }
        }
        
        
        task.resume()
    }
    
    func atualizaTabela(){
        self.tableView.reloadData()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // ocultar teclado ao clicar na view
        let tap:UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "DismissKeyboard")
        self.view.addGestureRecognizer(tap)
        
        consultarServico()
    }
    
    // encerra o teclado
    func DismissKeyboard(){
        self.view.endEditing(true)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
  • Oops, ball show. Thanks for the help. I just found it strange one thing, when I click on the table I have an immediate update of it, however, waiting usually takes more than 7 seconds for the values to be presented. You know what would be?

  • I noticed this delay anyway, I won’t be able to tell you what the real reason is, probably because this ends the thread, I edited the answer giving a performSelectorOnMainThread and apparently got the update right now

  • Now it’s perfect. This was my biggest problem, thanks again for the help. Now I’m searching to know how to customize that prototype Cell, I want to put a label there for the service and another for the status, items that are the values returned in json.

  • Come on, we are here to always help, give an upvote and mark as your chosen answer if it has helped your problem, good luck in the surveys, any problem can create a new question

  • I advise to use frameworks for connection, after a search on Afnetworking or Alamofire

Browser other questions tagged

You are not signed in. Login or sign up in order to post.