Нужна помощь в использовании предикатов для фильтрации NSArray, который представляет данные в UITableVIew - PullRequest
0 голосов
/ 01 мая 2019

В настоящее время у меня есть NSArray, который получает свои данные из базы данных mySQL.

Мне нужно отфильтровать эти данные на основе жестко закодированной строки "Customer1"

У меня есть следующее:

import UIKit

class showCustomerDetails: UIViewController, UITableViewDataSource, UITableViewDelegate, FeedDetailProtocol  {



    var feedItems: NSArray = NSArray()
    var selectedStock : DetailModel = DetailModel()


    @IBOutlet weak var stockResultsFeed: UITableView!


    override func viewDidLoad() {
        super.viewDidLoad()


        self.stockResultsFeed.delegate = self
        self.stockResultsFeed.dataSource = self

        let detailModel = FeedDetail()
        detailModel.delegate = self
        detailModel.downloadItems()

    }
    func itemsDownloaded(items: NSArray) {

        feedItems = items
        self.stockResultsFeed.reloadData()
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // Return the number of feed items
        return feedItems.count

    }

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

        // Retrieve cell
        let cellIdentifier: String = "customerDetails"
        let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
        myCell.textLabel?.textAlignment = .center
        // Get the stock to be shown
        let item: DetailModel = feedItems[indexPath.row] as! DetailModel



        // Configure our cell title made up of name and price
        let customerDetails = [item.code, item.manufacturer, item.model].compactMap { $0 }.joined(separator: " — ")



        print(customerDetails)
        // Get references to labels of cell
        myCell.textLabel!.text = customerDetails

        return myCell
    }


}

Вот что я хотел сделать, но я не уверен, как правильно его применить:

let searchString = "Customer1"
let predicate = NSPredicate(format: "SELF contains %@", searchString)
let searchDataSource = feedItems.filter { predicate.evaluateWithObject($0) }

А затем:

let item: DetailModel = searchDataSource[indexPath.row] as! DetailModel

Данные NSArray поступают из:

import Foundation

protocol FeedDetailProtocol: class {
    func itemsDownloaded(items: NSArray)
}


class FeedDetail: NSObject, URLSessionDataDelegate {



    weak var delegate: FeedDetailProtocol!

    let urlPath = "https://www.example.com/test1/test1.php"

    func downloadItems() {

        let url: URL = URL(string: urlPath)!
        let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)

        let task = defaultSession.dataTask(with: url) { (data, response, error) in

            if error != nil {
                print("Error")
            }else {
                print("details downloaded")
                self.parseJSON(data!)
            }

        }

        task.resume()
    }

    func parseJSON(_ data:Data) {

        var jsonResult = NSArray()

        do{
            jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray

        } catch let error as NSError {
            print(error)

        }

        var jsonElement = NSDictionary()
        let stocks = NSMutableArray()

        for i in 0 ..< jsonResult.count
        {

            jsonElement = jsonResult[i] as! NSDictionary

            let stock = DetailModel()

            //the following insures none of the JsonElement values are nil through optional binding
            if let code = jsonElement[“code”] as? String,
                let customer = jsonElement["customer"] as? String,
                let manufacturer = jsonElement["manufacturer"] as? String,
                let model = jsonElement["model"] as? String

            {
                print(code)
                print(manufacturer)
                print(model)
                print(customer)
                stock.code = code
                stock.manufacturer = manufacturer
                stock.model = model
                stock.customer = customer

            }

            stocks.add(stock)

        }

        DispatchQueue.main.async(execute: { () -> Void in

            self.delegate.itemsDownloaded(items: stocks)

        })
    }
}

1 Ответ

0 голосов
/ 01 мая 2019

Это Свифт. Используйте Array , а не NSArray, и просто вызовите метод Array filter. NSArray принадлежит Какао и Objective-C; Вы должны как можно больше использовать нативные типы Swift и методы Swift.

Если вы настаиваете на фильтрации NSArray с использованием метода Cocoa Objective-C и настаиваете на использовании NSPredicate, самый простой подход - сформировать свой предикат с init(block:).

Вот простая иллюстрация:

    let arr = ["Manny", "Moe", "Jack"] as NSArray
    let p = NSPredicate { element, _ in
        return (element as? String)?.contains("a") ?? false
    }
    let arr2 = arr.filtered(using: p)
    print(arr2) // [Manny, Jack]

Но (просто чтобы понять суть) в родном Swift все намного проще:

    let arr = ["Manny", "Moe", "Jack"]
    let arr2 = arr.filter {$0.contains("a")}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...