Есть ли функция для получения n элементов из базы данных Firebase в реальном времени? - PullRequest
0 голосов
/ 21 декабря 2018

Мой код состоит из 3 быстрых файлов для создания динамического прототипа UITableViewController.

1) Rent_house_Controller.swift

2) Rent_house_Cell.swift

3) Rent_house_Detail.swift

Прежде всего я подключил UITableViewCell объекты к выделенному файлу swift:

@IBOutlet weak var rentImage: UIImageView!

@IBOutlet weak var rentLabel: UILabel!

Затем я определил свой UITableViewController:

import UIKit
import FirebaseDatabase

class Case_in_affitto: UITableViewController,
UISearchResultsUpdating, UISearchBarDelegate {

var rentImages = [String]()
var rentNames = [String]()
var webAddresses = [String]()

var searching = false
var matches = [Int]()
let searchController = UISearchController(searchResultsController: nil)

override func viewDidLoad() {
    super.viewDidLoad()

    initialize()
}

func initialize() {
    rentNames = ["Red Street",
                       "Green Street",
                       "Blue steet",
                       "Yellow Street",
                       "Colour Square"]

    webAddresses = ["https://website.com/rents/Red-Street",
                    "https://website.com/rents/Green-Street",
                    "https://website.com/rents/Blue-Street",
                    "https://website.com/rents/Yellow-Street",
                    "https://website.com/rents/Colour-Square"]

    rentImages = ["Red-Street.jpg",
                        "Green-Street.jpg",
                        "Blue-Street.jpg",
                        "Yellow-Street.jpg",
                        "Colour-Square.jpg"]

    tableView.estimatedRowHeight = 50
    navigationController?.navigationBar.prefersLargeTitles = true

    searchController.searchBar.delegate = self
    searchController.searchResultsUpdater = self
    searchController.obscuresBackgroundDuringPresentation = false
    searchController.searchBar.placeholder = "Cerca immobile"
    navigationItem.searchController = searchController
    definesPresentationContext = true
    let attributes = [
        NSAttributedString.Key.foregroundColor : UIColor.white,
        NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 17)
    ]
    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes(attributes, for: .normal)
    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title = "Annulla"
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: Search Controller
func updateSearchResults(for searchController: UISearchController) {
    if let searchText = searchController.searchBar.text,
        !searchText.isEmpty {
        matches.removeAll()

        for index in 0..<rentNames.count {
            if rentNames[index].lowercased().contains(
                searchText.lowercased()) {
                matches.append(index)
            }
        }
        searching = true
    } else {
        searching = false
    }
    tableView.reloadData()
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    searching = false
    tableView.reloadData()
}



// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return searching ? matches.count : rentNames.count
}


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

    let cell = self.tableView.dequeueReusableCell(withIdentifier:"rentTableCell", for: indexPath) as! Case_in_Affitto_Cell

    let row = indexPath.row
    cell.rentLabel.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.headline)
    cell.rentLabel.text = searching ? rentNames[matches[row]] : rentNames[row]
    let imageName = searching ? rentImages[matches[row]] : rentImages[row]

    cell.rentImage.image = UIImage(named: imageName)

    return cell
}



override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "ShowrentDetails" {

        let detailViewController = segue.destination
            as! Case_in_Affitto_Detail

        let myIndexPath = self.tableView.indexPathForSelectedRow!
        let row = myIndexPath.row
        detailViewController.webSite =
            searching ? webAddresses[matches[row]] : webAddresses[row]
    }
}

//Set cells height
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    switch indexPath.row {
    case 0,1,2,3,4:
        return 100
    default:
        return 40
    }
}


}

В этом случае у меня есть классический UITableViewController, который отображает значения, которые я реализовал в проекте, но мне нужно что-то другое.

Я хочу сделать n ячеек, заданных количеством узлов, которые у меня естьв базе данных.

Например:

{
"Sales":"",
"Rents":[
{
"Address":"Green_Street",
"Rooms":"2",
"Price":"70000"
},
{
"Address":"Red_Street",
"Rooms":"2",
"Price":"70000"
},
{
"Address":"Blue_Street",
"vani":"2",
"Price":"70000"
},
{
"Address":"Yellow_Street",
"Rooms":"2",
"Price":"70000"
},
{
"Address":"Colour_Square",
"Rooms":"4",
"Price":"140000"
}
]
}

Другими словами, первая проблема заключается в том, что в один прекрасный день число домов будет увеличиваться или уменьшаться, поэтому мне нужно сделать функции ведьмыавтоматически заполняет таблицу числом узлов в моей базе данных .?


Редактировать:

Я что-то сделал.Я создал новый UIViewController, который вызывает данные из базы данных, а затем я хочу передать все эти данные по UserDefaults.standard

Изображение предоставляется по URL-адресу, полученному из базы данных, поэтому я добавил также ключ "imageURL".

Loading.swift:

if codesArray.contains("0") {
                    let userRef = rootRef.child("Rents").child("0")

                        userRef.observeSingleEvent(of: .value, with: { snapshot in
                            let userDict = snapshot.value as! [String: Any]

                            let rentAddress = userDict["Address"] as! String
                            self.address = rentAddress

                            let rentnumberOfRooms = userDict["numberOfRooms"] as! String
                            self.numberOfRooms = rentnumberOfRooms

                            let rentPrice = userDict["Price"] as! String
                            self.price = rentPrice

                            let rentimageURL = userDict["imageURL"] as! String
                            self.imageURL = rentimageURL
                            //save data on UserDefaults
                            self.savedata()
                            //loading finished
                            self.loading.stopAnimating()
                            self.performSegue(withIdentifier: "loadingfinish", sender: self)
                        })
                } else {
                    self.loading.stopAnimating()
                    let alert = UIAlertController(title: "Errore", message: "Caricamento annunci non riuscito", preferredStyle: UIAlertController.Style.alert)
                    alert.addAction(UIAlertAction(title: "ok", style: UIAlertAction.Style.default, handler: nil))
                    self.present(alert, animated: true, completion: nil)
                }

Как я могу изменить это условие для загрузки каждого вложенного узла узла "Аренда"?

(Помните, что мы не знаем каку многих детей есть Арендная плата)


Редактировать 2:

Я делаю все возможное, чтобы найти это решение.Я думал использовать параметр nextObject на некоторое время, чтобы проверить, есть ли другие объекты в базе данных для хранения в var address = [String]()

//setting firebase database
                        while (snapshotChildren.nextObject() as? DataSnapshot) != nil {

                            let string_child = snapshotChildren.nextObject() as? String

                            let userRef = rootRef.child("Rents").child(string_child!)

                                userRef.observeSingleEvent(of: .value, with: { snapshot in
                                    let userDict = snapshot.value as! [String: Any]

                                    self.address.append(userRef.value(forKey: "Address") as! String)

                                    let rentnumberOfRooms = userDict["numberOfRooms"] as! NSMutableArray
                                    self.numberOfRooms = rentnumberOfRooms

                                    let rentPrice = userDict["Price"] as! NSMutableArray
                                    self.price = rentPrice

                                    let rentimageURL = userDict["imageURL"] as! NSMutableArray
                                    self.imageURL = rentimageURL
                                    //avvio salvataggio dati del volontario
                                    func prepare(for segue: UIStoryboardSegue, sender: Any?) {
                                        let vc = segue.destination as! Case_in_affitto

                                        var i = 0
                                        while i==5 {
                                            //this will pass the value on the address array in the Case_in_affitto.swift file
                                            vc.address.append(self.address[i])
                                            i += 1
                                        }

                                    }
                                })
                        }
                        //loading complete
                        self.loading.stopAnimating()
                        self.performSegue(withIdentifier: "loadingfinish", sender: self)

К сожалению, это не правильно

1 Ответ

0 голосов
/ 21 декабря 2018

Il codice è abbastanza orribile ? (код довольно ужасный)

Не используйте несколько массивов в качестве источника данных.У вас уже будут проблемы с функцией поиска.

Используйте пользовательскую структуру со всеми необходимыми параметрами, изображение представлено ее именем в комплекте

struct Rent {
    let address : String
    let numberOfRooms : Int
    let price : String
    let image : String
}

Инициализатор

init(address : String, numberOfRooms : Int, price : String, image : String)

включен бесплатно.

Объявите один массив источника данных и заполните его из базы данных

var rents = [Rent]()

Объявите matchesс тем же типом

var matches = [Rent]()

и использовать этот оптимизированный код для фильтрации объектов, diacriticInsensitive весьма полезен для текста на итальянском языке.

func updateSearchResults(for searchController: UISearchController) {
    if let searchText = searchController.searchBar.text,
        !searchText.isEmpty {
        matches = rents.filter{ $0.name.range(of: searchText, options: [.caseInsensitive, .diacriticInsensitive]) != nil }
        searching = true
    } else {
        matches.removeAll()
        searching = false
    }
    tableView.reloadData()
}

Соответствующие методы делегата табличного представления:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return searching ? matches.count : rents.count
}


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

    let cell = self.tableView.dequeueReusableCell(withIdentifier:"rentTableCell", for: indexPath) as! Case_in_Affitto_Cell
    let object = searching ? matches[indexPath.row] : rents[indexPath.row]

    cell.rentLabel.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.headline)
    cell.rentLabel.text = object.name
    cell.rentImage.image = UIImage(named: object.image)

    return cell
}

Если изображения не должны находиться в комплекте, сохраните URL-адреса в базе данных и физические изображения в папке Documents.
В этом случае объявите

let imageURL : URL

в структуре и присвоить изображение

cell.rentImage.image = UIImage(contentsOfFile: object.imageURL.path)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...