【问题标题】:Get JSON data and display in tableview Xcode获取JSON数据并在tableview Xcode中显示
【发布时间】:2018-10-06 18:03:34
【问题描述】:

我正在创建一个 IOS 程序来从 url 下载 json 数据并显示在 ios 的表格视图中。我有问题在 loginpage 视图控制器中下载 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 更改为静态,但不能在 @objc func taskdo() 中使用静态变量。我也尝试了 UserDefaults 但无法在 TableViewController (NodeDataPage) 中获取数据

我在类 NodeDataPage 中使用局部变量测试 tableview 成功,但无法测试来自其他视图控制器的变量

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. 如何在 LoginPage VC 中每隔 10 秒运行一次 JSON 下载功能,问题 1 也是(我尝试使用静态变量进入其他视图,但无法在 @objc func taskdo() 中运行?
  3. 我想在用户登录后每 10 秒运行一次 JSON 下载数据。我应该把这个功能放在 LoginPage VC 还是其他视图中,因为我需要不断地从服务器获取数据?
  4. 当应用程序被隐藏(不被杀死)时,我如何运行 JSON 下载函数?

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

谢谢

【问题讨论】:

  • 请一次一个问题。请提前确定您要问的一件事以及构成该问题的最小完整可验证示例的内容,并请花时间正确格式化您的问题。
  • 嗨,马特,感谢您的评论。我的问题是:“如何在 LoginPage VC 中每 10 秒下载一次 JSON 数据并在 tableview 控制器 (NodeDataPage) 中显示数据?”。
  • 这仍然是两个问题。 :) 此外,问题的前提很麻烦;如果 JSON 数据要显示在 NodeDataPage 中,为什么要在其他地方下载?
  • 如果我更改为静态变量以在其他视图中获取数据,我无法在 @objc func taskdo() 中运行该变量。
  • @matt :因为即使应用程序被隐藏或用户移动到其他视图,我也想每 10 秒下载一次 JSON。这就是我将 JSON 下载函数放在初始化视图中的原因。我认为如果我将代码放在其他视图中,代码将不会运行

标签: ios json swift xcode tableview


【解决方案1】:

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

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

使用通知或观察者设计模式来提示 NodeDataPage 从 DataManager 获取数据并重新加载 tableview。

希望我能回答您的问题。

【讨论】:

  • 谢谢。我已经按照您的建议进行更改。但是如何重新加载表格视图或者我必须创建一个按钮让用户刷新页面?导入 UIKit 类 NodeDataPage: UIViewController,UITableViewDelegate,UITableViewDataSource { var NodeData = DataManager() @IBOutlet weak var tableView: UITableView!覆盖 func viewDidLoad() { super.viewDidLoad() NodeData.timerstart() } 覆盖 func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) tableView?.reloadData() } }
  • 当我运行 @objc func taskdo() 时。 nodeidArray 将在最后一个元素之后插入数据,但我只想从第一个元素覆盖。例如,对于下面的问题:第一负载载荷:nodeidArray = [ “mwmfl2og2l8888fjpj2d”, “aj2w1aljw8nd65ax79dm”, “y2cfwecrw3hqznuxmfvf”]第二:[ “mwmfl2og2l8888fjpj2d”, “aj2w1aljw8nd65ax79dm”, “y2cfwecrw3hqznuxmfvf”, “mwmfl2og2l8888fjpj2d”, “aj2w1aljw8nd65ax79dm”,“y2cfwecrw3hqznuxmfvf "]
  • 请分享您的 DataManager 课程。同样对于 nodeidArray,您不插入,只需替换数组或清空(removeAll)nodeidArray 并添加新数组。否则,您可以使用 set 代替数组,这将确保其中只有一个具有相同值的对象。
猜你喜欢
  • 2012-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-30
  • 1970-01-01
  • 2021-03-12
  • 2020-03-28
相关资源
最近更新 更多