Как отфильтровать ответ API для включения / исключения некоторых данных из TableView в Swift - PullRequest
1 голос
/ 28 апреля 2019

Я пытаюсь исключить некоторые данные, которые я получаю из ответа API,

Ответ API:

{"status":"ok","answer":[{
                    address = Newyork;
                    comments = test;
                    "contact_name" = "ios@ios.com";
                    status = "4";
                    },
                    {
                    address = Ohio;
                    comments = test;
                    "contact_name" = "ios@ios.com";
                    "status" = "3";
                    },
                    {
                    address = cityname;
                    comments = test;
                    "contact_name" = "ios@ios.com";
                    status = "3";
                    },
                    {
                    address = Washington;
                    comments = test;
                    "contact_name" = "ios@ios.com";
                    status = "4";
      }
      )
      )

Я пытаюсь добиться фильтрации этого ответаи просматривать только те заказы, которые имеют статус «4» в TableView.

Вот что я пробовал до сих пор:

func getOrdersHistory() {

    DispatchQueue.main.async {

        let headers = [
            "content-type" : "application/x-www-form-urlencoded",
            "cache-control": "no-cache",
            "postman-token": "dded3e97-77a5-5632-93b7-dec77d26ba99"
        ]

        let user  = CoreDataFetcher().returnUser()
        let email = user.email!

        let postData = NSMutableData(data: "data={\"email\":\"\(email)\",\"type_id\":\"2\"}".data(using: String.Encoding.utf8)!)
        let request = NSMutableURLRequest(url: NSURL(string: "http://www.someApi/Orders")! as URL,
                                          cachePolicy: .useProtocolCachePolicy,
                                          timeoutInterval: 10.0)

        request.httpMethod          = "POST"
        request.allHTTPHeaderFields = headers
        request.httpBody            = postData as Data

        let session  = URLSession.shared
        let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
            if (error != nil) {
                print(error!)
            } else {
                if let dataNew = data, let responseString = String(data: dataNew, encoding: .utf8) {
                    print(responseString)


                    let dict = self.convertToDictionary(text: responseString)
                    print(dict?["answer"] as Any)
                    self.responseArray = (dict?["answer"] as! NSArray) as! [ConfirmedOrders.JSONDictionary]
                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }


                }

            }

        })

        dataTask.resume()
    }
}

func convertToDictionary(text: String) -> [String: Any]? {
    if let data = text.data(using: .utf8) {
        do {
            return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]

        } catch {
            print(error.localizedDescription)
        }
    }
    return nil
}

Таким образом, я получаю в TableView, независимо отих статус, может кто-нибудь помочь, пожалуйста?

Ответы [ 2 ]

1 голос
/ 28 апреля 2019

На основе вашего набора данных и использования чистых массивов и словарей Swift вы можете просто отфильтровать их так:

func getConfirmedOrders(in dict: [String:Any]) -> [[String:Any]] {
    guard
        let answers = dict["answer"] as? [[String:Any]]
        else { print("Answer key not present"); return [] }

    //Your basic filter operation
    let filtered = answers.filter { (answer) -> Bool in
        return answer["status"] as? String == "4"
    }

    return filtered
}

Это просто правильное приведение типов и применение к нему операции filter.

Просто используя это так:

self.responseArray = self.getConfirmedOrders(in: dict)
DispatchQueue.main.async {
    self.tableView.reloadData()
}

Однако я вижу, что ваш responseArray имеет тип [ConfirmedOrders.JSONDictionary].
Так что либо измените getConfirmedOrders(from:), чтобы вернуть [ConfirmedOrders.JSONDictionary], либоизмените свой responseArray на тип [[String:Any]].


Пример игровой площадки

let jsonString = """
{"status":"ok","answer":[{"address":"Newyork","comments":"test","contact_name":"ios@ios.com","status":"4"},{"address":"Ohio","comments":"test","contact_name":"ios@ios.com","status":"3"},{"address":"cityname","comments":"test","contact_name":"ios@ios.com","status":"3"},{"address":"Washington","comments":"test","contact_name":"ios@ios.com","status":"4"}]}
"""

if let data = jsonString.data(using: .utf8) {
    do {
        //basically what you have in `convertToDictionary(text:)`
        let dict = try JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]

        let filtered = getConfirmedOrders(in: dict)
        print(filtered)
    }
    catch {
        print(error)
    }
}

Предложения:

  1. Использование кодируемых моделейвместо массива и словаря Swift
  2. Используйте Swift Array вместо NSArray и аналогично используйте Swift Dictionary вместо NSDictionary
0 голосов
/ 28 апреля 2019

Вам нужно

do {

    let dec = JSONDecoder()
    dec.keyDecodingStrategy = .convertFromSnakeCase
    let res = try dec.decode(Root.self, from: data)
     // here filter like e.x
     let filtered = res.answer.filter { $0.status == "4" }
}
catch{
    print(error)
}

struct Root: Codable {
    let status: String
    let answer: [Answer]
}

struct Answer: Codable {
    let address, comments, contactName, status: String
}

Если вам нужно избавиться от Root, тогда сделайте

do {

    guard let data = data else { return }
    let dic = try JSONSerialization.jsonObject(with:data, options: []) as! [String:Any]
    let dataAns = try JSONSerialization.data(withJSONObject:dic["answer"]!, options: [])

    let dec = JSONDecoder()
    dec.keyDecodingStrategy = .convertFromSnakeCase
    let res = try dec.decode([Answer].self, from: dataAns)
     // here filter like e.x
     let filtered = res.filter { $0.status == "4" }
}
catch{
    print(error)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...