【问题标题】:Populating Grouped Table from Alamofire and SwiftyJSON从 Alamofire 和 SwiftyJSON 填充分组表
【发布时间】:2016-10-26 07:02:01
【问题描述】:

我一直在尝试使用来自 Alamofire 请求的数据填充分组表。到目前为止,我已经设法用数组中的静态数据填充了一个表(如图所示),但是经过数小时的尝试、查找和试验,仍然无法弄清楚如何使用 JSON 数据。它不应该有太大的区别,但据记录,这在 Swift 3 中。

任何帮助将不胜感激。谢谢。

这是我的静态代码,效果很好。

import UIKit
import Alamofire
import SwiftyJSON

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    //static Data Here:
    var array = [ ["Clients", "John Doe", "Joe Bloggs"],["Departments", "HR", "Admin", "Finance"]]
    let cellReuseIdentifier = "cell"
    @IBOutlet var tableView: UITableView!

    override func viewDidLoad() {
        tableView.delegate = self
        tableView.dataSource = self
        super.viewDidLoad()
    }
    func numberOfSections(in tableView: UITableView) -> Int {
        return array.count
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return array[section].count - 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell:AreasCustomCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! AreasCustomCell

         cell.areasPreview.contentMode = .scaleAspectFit
        request(.GET, "https://url.here.com", parameters: ["file": "default.png"]).response { (request, response, data, error) in
            cell.areasPreview.image = UIImage(data: data!, scale:0.5)
            }

        cell.areasCellLabel.text = array[indexPath.section][indexPath.row + 1]
        return cell
    }
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return array[section][0]
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("You tapped cell number \(indexPath.row).")
        //More things planned here later!
    }
}

这也是我正在使用的 JSON 的格式。

content =     {
    clients =         (
                    {
            desc = "Description here";
            group = client;
            id = "group_7jsPXXAcoK";
            name = "John Doe";
        },
                    {
            desc = "Description here";
            group = client;
            id = "group_19MrV7OLuu";
            name = "Joe Bloggs";
        }
    );
    departments =         (
                    {
            desc = "Description here";
            group = department;
            id = "group_PhAeQZGyhx";
            name = "HR";
        },
                    {
            desc = "Description here";
            group = department;
            id = "group_RMtUqvYxLy";
            name = "Admin";
        },
                    {
            desc = "Description here";
            group = department;
            id = "group_T50mxN6fnP";
            name = "Finance";
        }
    );
};
state = success;

到目前为止,我已经添加了一个新类来保存我认为朝着正确方向迈进的 JSON 数据。

class Group {

    let id : String
    let name : String
    let desc : String
    let group : String

    init(dictionary : [String : AnyObject]) {
        id = dictionary["id"] as? String ?? ""
        desc = dictionary["desc"] as? String ?? ""
        name = dictionary["name"] as? String ?? ""
        group = dictionary["group"] as? String ?? ""
    }
}

最后,这是我首先获取 JSON 数据的函数,它应该从 viewDidLoad 调用。

func getData()
{
    let defaults = UserDefaults.standard()
    let token = defaults.string(forKey: defaultsKeys.userToken)
    let email = defaults.string(forKey: defaultsKeys.userEmail)
    request(.POST, "https://url.here.com/api/v2.php", parameters: ["type": "areas", "uEmail": email!, "token": token!])
        .responseJSON { response in
            var json = JSON(response.result.value!)
            let state = json["state"].stringValue
            if(state == "error"){
                print(json["message"].stringValue)
            } else {
                print(response.result.value)
                //Send JSON data here to Table!
            }
    }
}

【问题讨论】:

    标签: ios json swift uitableview alamofire


    【解决方案1】:

    好的,当您收到请求的响应时,闭包会返回 3 个值。 示例:

    request(gibberish: DoesntMatter) {
        data, response, error in
    }
    

    您通常希望检查响应以获取 200 的结果,像这样

    if let httpResponse = response as? NSHTTPURLResponse {
          if httpResponse.statusCode == 200 {
                //do something with data
          }
    }
    

    此时,在使用 swiftyJSON 时,您可以像这样获取数据:

    if let httpResponse = response as? NSHTTPURLResponse {
          if httpResponse.statusCode == 200 {
                let json = JSON(data: data)
          }
    }
    

    此时检索 json 的最佳方式是使用闭包,因为 API 调用是异步完成的,我们需要知道响应何时完成。

        func performAPICall(url: NSURL, resultHandler: ((json: JSON) -> Void)) {
    
                let session = NSURLSession(configuration: .defaultSessionConfiguration())
                let tokenRequest = NSMutableURLRequest(URL: url)
                tokenRequest.HTTPMethod = "GET"
    
                let dataTask = session.dataTaskWithRequest(tokenRequest) {
                    (let data, let response, let error) in
                    if let httpResponse = response as? NSHTTPURLResponse {
                        if error == nil {
                              if httpResponse.statusCode == 200 {
                                    let json = JSON(data: data!)
                                    resultHandler(json)
                              } else {
                                    print("Failed request with response: \(httpResponse.statusCode)")
                              }
                        } else {
                            print("Error during GET Request to the endpoint \(url).\nError: \(error)")
                        }
                    }
                }
                dataTask.resume()
        }
    

    然后您调用该函数并对数据执行您喜欢的操作,如下所示:

     performAPICall(url) {
                  json in
              //this will have your full response
              print(json)
              //parse the json easily by doing something like
              var clientArray: [Group] = []
    
              let clients = json["clients"]
              for client in clients {
                    var thisClient = Group()
                    thisClient.id = json["id"].string
                    thisClient.desc = json["desc"].string
                    thisClient.name = json["name"].string
                    //not quite sure how to store this one
                    thisClient.group = json["group"].anyObject
                    clientArray.setByAddingObject(thisClient)
              }
              //make sure to call tableView.reloadData() when you give the tableViews //it's value.
        }
    

    您也可以通过 init 执行此操作,但请确保正确设置该功能。否则我只会将你的对象的值初始化为 nil 或空。此外,您的 JSON 响应返回的值不是字符串。确保您弄乱了它以找到正确的存储方法。希望这会有所帮助!

    【讨论】:

    • 感谢您的回复,我现在明白为什么知道响应何时完成很重要 - 不过我有两个问题,首先,我怎样才能将 performAPICall 转换为 POST 请求?我需要发送几个值来取回 JSON。最后,我如何将我的小组课程放入如图所示的表格中?也就是说,使用单独的分组单元格?再次感谢:)
    【解决方案2】:

    我经常使用这个。只需将“POST”或“GET”传入方法参数,然后在 body 参数中输入 body,如果是 GET 请求,则输入 nil。您可以删除可达性部分,但我通常喜欢使用某种形式的 API 调用来检查网络连接,因此如果我没有连接,我可以立即诊断错误。有几个不同的 git 项目可供您使用。当前警报控制器只是我放置在 UIViewController 上的一个扩展,以便更轻松地发出警报消息。

    这里唯一棘手的部分是身体。如果 if 遵循 RESTful 设计,而不仅仅是将主体作为遵循此设计的字符串传递

    “key1=(value1)&key2=(value2)&key3=(value3)&key4=(value4)&key5=(value5)”等...

    我相信你也可以通过 json 序列化来做到这一点,这样更干净,但我还没有发现在我的任何项目中都需要它。

       typealias APIResultHandler = ((response: Int, json: JSON) -> Void)
    
        func performAPICall(url: NSURL, method: String, body: String?, resultHandler: APIResultHandler) {
            if Reachability.isConnectedToNetwork() == true {
                print("Internet connection OK")
                let session = NSURLSession(configuration: .defaultSessionConfiguration())
                let tokenRequest = NSMutableURLRequest(URL: url)
                tokenRequest.HTTPMethod = method
                if body != nil && method == Constant.POST {
                    tokenRequest.HTTPBody = body!.dataUsingEncoding(NSUTF8StringEncoding)
                }
                let dataTask = session.dataTaskWithRequest(tokenRequest) {
                    (let data, let response, let error) in
                    if let httpResponse = response as? NSHTTPURLResponse {
                        if error == nil {
                            let json = JSON(data: data!)
                            resultHandler(response: httpResponse.statusCode, json: json)
                        } else {
                            print("Error during \(method) Request to the endpoint \(url).\nError: \(error)")
                        }
                    }
                }
                dataTask.resume()
            } else {
                print("Internet connection FAILED")
                presentAlertController("No Internet Connection", message: "Make sure your device is connected to the internet.")
            }
        }
    

    【讨论】:

    • 这也将响应传回,我只是检查函数调用的闭包。
    • 好吧,我已经分别删除了,您可以帮我把 JSON 数据真正放入 分组表,而不是再次发布?分组位难倒我 - 因为我想把它放在我添加的图像中。感谢您迄今为止给我的帮助。
    • 你了解如何从json中提取信息并处理API请求吗?如果是这样,只需将其相应地放入您的数组中。
    • 老实说,一旦数据从 API 移动到字典(组类),我不确定如何进行。解析JSON的时候也有错误。我所有的代码都在这里,pastebin.com/e6HPkA80 - 我不想占用你太多的时间,但是如果你能指出我正确的方向,我将非常感激。我不得不删除很多错误检查位,因为它们需要我没有的框架,而且在我用 Swift3 编写时,一些代码已经改变。
    【解决方案3】:
    typealias APIResultHandler = ((response: Int, json: JSON) -> Void)
    
    func performAPICall(url: NSURL, method: String, body: String?, resultHandler: APIResultHandler) {
        let session = NSURLSession(configuration: .defaultSessionConfiguration())
        let tokenRequest = NSMutableURLRequest(URL: url)
        tokenRequest.HTTPMethod = method
        if body != nil && method == Constant.POST {
            tokenRequest.HTTPBody = body!.dataUsingEncoding(NSUTF8StringEncoding)
        }
        let dataTask = session.dataTaskWithRequest(tokenRequest) {
            (let data, let response, let error) in
            if let httpResponse = response as? NSHTTPURLResponse {
                if error == nil {
                    let json = JSON(data: data!)
                    resultHandler(response: httpResponse.statusCode, json: json)
                } else {
                    print("Error during \(method) Request to the endpoint \(url).\nError: \(error)")
                }
            }
        }
        dataTask.resume()
    }
    

    结构客户{ 变量 ID:字符串 var desc: 字符串 变量名称:字符串

    init() {
        id = ""
        desc = ""
        name = ""
    }
    

    }

    var clientArray: [客户端] = [] 让 body = "key1=(value1)&key2=(value2)&key3=(value3)&key4=(value4)&key5=(value5)" 等等... 覆盖 func viewDidLoad() { super.viewDidLoad()

       performAPICall(url, method: "POST", body: body) {
                json in
            //this will have your full response
            print(json)
    
            //put this as a class variable instead in the call
            var clientArray: [Client] = []
    
            let clients = json["clients"]
            for client in clients {
                  var thisClient = Client()
                  thisClient.id = json["id"].string
                  thisClient.desc = json["desc"].string
                  thisClient.name = json["name"].string
                  clientArray.append(thisClient)
            }
            tableview.reloadData()
      }
    

    }

    func tableView(tableView: UITableView, cellForRowAtindexPath: IndexPath) -> UITableViewCell {

        if section == 0 {
          let cell:AreasCustomCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! AreasCustomCell
    
          cell.areasPreview.contentMode = .scaleAspectFit
          cell.areasCellLabel.text = clientArray[indexPath.row]
        }
    
        if section == 1 {
            //do stuff for the other cell
        }
    }
    

    【讨论】:

      【解决方案4】:

      我不会花很长时间,但我现在没有时间。下班后的星期一将是下一次我什至有几分钟看代码的时间。我的电子邮件是sethmr21@gmail.com。给我发电子邮件,如果您仍然无法弄清楚,我会帮助您。当你第一次开始时,混淆闭包、异步事物、API 调用等等可能会让人感到困惑。虽然有很多关于它们的好文章。我建议买一本尺寸不错的书,比如SWIFT 我相信你可以在网上找到一些免费的 pdf 书。从头到尾阅读它们将为您提供一个通过略读堆栈溢出难以获得的基础。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-04-24
        • 1970-01-01
        • 2016-09-30
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        • 2018-10-06
        相关资源
        最近更新 更多