获取JSON数据并在tableview Xcode中显示

时间:2018-10-06 18:03:34

标签: ios json swift xcode tableview

我正在创建一个IOS程序,以从url下载json数据并显示在ios的表视图中。我在登录页面视图控制器中下载JSON(每10秒)并解析JSON数据到tableview控制器时遇到问题。在发布此之前,我已经尝试搜索了很多次,但是找不到解决方案。下面是StoryBoad和代码

Story Board

  1. 用户将登录,登录成功后,将加载JSON数据(userlogin = true)。登录类loginPage中的以下代码:UIViewController

    @IBOutlet weak var usernameLogin: UITextField!
    
    @IBOutlet weak var passwordLogin: UITextField!
    
    @IBAction func loginPress(_ sender: Any) {
    
        username = usernameLogin.text!
        password = passwordLogin.text!
        let request = NSMutableURLRequest(url: NSURL(string: "http://talectric.com/wp-admin/a_p/users/userlogin.php")! as URL)
        request.httpMethod = "POST"
        let postString = "username=\(username)&password=\(password)"
        request.httpBody = postString.data(using: String.Encoding.utf8)
        let task = URLSession.shared.dataTask(with: request as URLRequest) {
        data, response, error in
            if error != nil {
                print("error=\(error!)")
                return
            }
            else
            {
                do {
                    let respondString = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary
                    print(respondString!)
                    let message = respondString?["message"] as! String
                    if message == "Check Pass" {
                        userlogin = true
                        DispatchQueue.main.async {
                            let TabViewPageController = self.storyboard?.instantiateViewController(withIdentifier: "TabViewPageID") as! TabViewPage
                            self.present(TabViewPageController, animated: true, completion: nil)
                        }
                    }
                    else {
                        DispatchQueue.main.async {
                        let alertController = UIAlertController(title: "Login", message:
                            "Username or Password is not correct", preferredStyle: UIAlertController.Style.alert)
                        alertController.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default,handler: nil))
                        self.present(alertController, animated: true, completion: nil)
                        }
                    }
                }
                catch let error as NSError {
                   print(error.debugDescription)
                }
            }
        }
        task.resume()
    }
    
  2. 在userlogin = true之后,@ objc func taskdo()会将JSON数据加载到nodeidArray,但是第二次下载不会覆盖nodeidArray的第一个元素,并且在最后一个元素之后插入nodeidArray(我只希望覆盖nodeidArray)

    import UIKit
    
    var timer = Timer()
    
    var userlogin = false
    
    struct Data {}
    
    var username = String()
    
    var password = String()
    
    class loginPage: UIViewController{
    
        var nodeidArray = [String]()
        override func viewDidLoad() {
            super.viewDidLoad()
            timerstart()
        }
        func timerstart()
        {
            timer = Timer.scheduledTimer(timeInterval: 5, target: self,selector: #selector(loginPage.taskdo),userInfo:nil,repeats: true)
        }
        @objc func taskdo()
        {
            if userlogin == true{
                let request = NSMutableURLRequest(url: NSURL(string: "http://talectric.com/wp-admin/a_p/iot/read_all.php")! as URL)
                request.httpMethod = "POST"
                let postString = "username=\(username)&password=\(password)&authen=wdwfesf9329140dsvfxkciospdkm"
                request.httpBody = postString.data(using: String.Encoding.utf8)
                let task = URLSession.shared.dataTask(with: request as URLRequest) {
                    data, response, error in
                    if error != nil {
                        print("error=\(error!)")
                        return
                    }
                    else
                    {
                        do {
                            if let respondString = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary {
                                if let nodedata = respondString.value(forKey: "nodedata") as? NSArray {
                                    for node in nodedata{
                                        if let nodeDict = node as? NSDictionary {
                                            if let nodeid = nodeDict.value(forKey: "nodeid"){
                                                self.nodeidArray.insert(nodeid as! String, at: 0)
                                            }
                                        }
                                    }                             
                                }
                            }
                         //   print(respondString!)
                            //let message = respondString?["numberofnodeid"] as! Int
                            //let nodedata = respondString!.value(forKey: "nodedata")//
                           // let nodeid = (nodedata as AnyObject).value(forKey: "nodeid")
                          //  print(respondString!.value(forKey: "nodedata")!)                        
                            print(self.nodeidArray)
                            let defaults = UserDefaults.standard
                            defaults.set(self.nodeidArray, forKey: "YourKey")
                        }
                        catch let error as NSError {
                            print(error.debugDescription)
                        }                 
                    }
                }
                task.resume()
            }
        }
    }
    
  3. 在LoginViewController中下载JSON之后,我无法将数据粘贴到tableview控制器中。我试图在LoginPage中将nodeidArray更改为static,但是无法在@objc func taskdo()中使用静态变量。我也尝试使用UserDefaults,但无法在TableViewController(NodeDataPage)中获取数据

我使用NodeDataPage类中的Local Variable成功测试了tableview,但是无法测试其他viewcontroller中的变量

import UIKit

class NodeDataPage: 
UIViewController,UITableViewDelegate,UITableViewDataSource {

    //var nodeidname = ["nodeid1","nodeid2","nodeid3"]
    var testArray : [String]() = UserDefaults.standard.objectForKey("YourKey") {
        var nodeidname : [NSString] = testArray! as! [NSString]
        println(readArray)
    }
    @IBOutlet weak var tableView: UITableView!
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return nodeidname.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier:"nodeCell",for: indexPath)
        cell.textLabel?.text = nodeidname[indexPath.row]
        return cell
    }}

我指定了问题:

  1. 如何将JSON数据(在LoginPage VC中下载)传输到Table View VC(NodeDataPage VC)?
  2. 我还如何每隔10s在LoginPage VC中运行带有问题1的JSON下载功能(我尝试使用静态变量进入其他视图并且不能在@objc func taskdo()中运行?
  3. 我想在用户登录后每10秒钟运行JSON下载数据。我是否应该将此功能放在LoginPage VC或其他视图中,因为我需要不断从服务器获取数据?
  4. 在隐藏应用程序(不被杀死)时如何运行JSON下载功能?

我尝试研究一小部分,但现在变得更加复杂。请帮助我。

谢谢

1 个答案:

答案 0 :(得分:0)

创建一个单独的类,例如“ DataManager”,该类保存所有数据(nodeidArray),并每10秒对服务器进行一次调用以从Web服务获取。

用户成功登录后,显示NodeDataPage。在此类的viewDidLoad中,创建DataManager对象并调用用于处理计时器并从服务器获取数据的方法。

使用通知或观察者设计模式来关联NodeDataPage以从DataManager获取数据并重新加载表视图。

希望我能回答您的问题。