New Fuitableviewdatasource - How to Use? Swift 3

New FUITableViewDataSource - how to use? Swift 3

The test for this latest version uses a tableView:bind: method (seems like a UITableView class extension they made) and I was able to get it to work.

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

let firebaseRef = FIRDatabase.database().reference().child(/*insert path for list here*/)

let query = firebaseRef.queryOrderedByKey() /*or a more sophisticated query of your choice*/

let dataSource = self.tableView.bind(to: query, populateCell: { (tableView: UITableView, indexPath: IndexPath, snapshot: FIRDataSnapshot) -> UITableViewCell in

let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath)

let value = snapshot.value as! NSDictionary

let someProp = value["someProp"] as? String ?? ""

cell.textLabel?.text = someProp

return cell
})
}

Also make sure you are observing your query for changes or else the tableView won't get populated

self.query?.observe(.value, with: { snapshot in
})

Swift 3 - iOS 10 UITableView enabling swipe-to-delete

Recent FirebaseUI updates have broken the original answer.

UPDATED ANSWER:

Simply subclass FUITableViewDataSource to implement custom UITableViewDataSource functionality, then bind the subclass to your UITableView.

The FUITableViewDataSource subclass:

import UIKit
import FirebaseDatabaseUI

class EditableTableDataSource: FUITableViewDataSource {

/// Called to populate each cell in the UITableView.
typealias PopulateCellBlock = (UITableView, IndexPath, FIRDataSnapshot) -> UITableViewCell

/// Called to commit an edit to the UITableView.
typealias CommitEditBlock = (UITableView, UITableViewCellEditingStyle, IndexPath) -> Void

private let commitEditBlock: CommitEditBlock?

/// A wrapper around FUITableViewDataSource.init(query:view tableView:populateCell:), with the
/// addition of a CommitEditBlock.
public init(query: FIRDatabaseQuery,
populateCell: @escaping PopulateCellBlock,
commitEdit: @escaping CommitEditBlock)
{
commitEditBlock = commitEdit
super.init(collection: FUIArray.init(query: query), populateCell: populateCell)
}

override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}

override func tableView(_ tableView: UITableView,
commit editingStyle: UITableViewCellEditingStyle,
forRowAt indexPath: IndexPath)
{
if (commitEditBlock != nil) {
commitEditBlock!(tableView, editingStyle, indexPath)
}
}

}

extension UITableView {

/// Creates a data source, binds it to the table view, and returns it. Note that this is the
/// `EditableTableViewDataSource` equivalent of the
/// `FUITableViewDataSource.bind(to:populateCell:)` method.
///
/// - parameters:
/// - to: The Firebase query to bind to.
/// - populateCell: A closure that's called to populate each cell.
/// - commitEdit: A closure that's called when the user commits some kind of edit. Maps to
/// `tableView(:commit:forRowAt:)`.
func bind(to query: FIRDatabaseQuery,
populateCell: @escaping EditableTableDataSource.PopulateCellBlock,
commitEdit: @escaping EditableTableDataSource.CommitEditBlock)
-> EditableTableDataSource
{
let dataSource = EditableTableDataSource(query: query,
populateCell: populateCell,
commitEdit: commitEdit)
dataSource.bind(to: self)
return dataSource
}

}

And usage:

import UIKit
import FirebaseDatabaseUI

class ScheduleViewController: UITableViewController {

private let TAG = String(describing: ScheduleViewController.self)

private var dataSource: FUITableViewDataSource!
private var dataManager: DataManager!

override func viewDidLoad() {
super.viewDidLoad()

dataManager = AppManager.defaultInstance.dataManager()

dataSource = tableView.bind(
to: dataManager.scheduledHabitsQuery(),
populateCell: populateCellBlock(),
commitEdit: commitEditBlock())
}

// MARK: TableView Data Source

func populateCellBlock() -> EditableTableDataSource.PopulateCellBlock {
return { tableView, indexPath, snapshot in
let cell = ScheduledHabitTableViewCell.from(tableView: tableView, at: indexPath)
cell.set(habit: ScheduledHabit(fromSnapshot: snapshot))
return cell
}
}

func commitEditBlock() -> EditableTableDataSource.CommitEditBlock {
return { tableView, editingStyle, indexPath in
if (editingStyle != .delete) {
return
}

// Delete the data from Firebase.
let snapshot = self.dataSource.snapshot(at: indexPath.row)
self.dataManager.moveToTrash(ScheduledHabit(fromSnapshot: snapshot))

// Deleting the table view row is done automatically by the FirebaseUI data source.
}
}

// MARK: - Navigation

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}

}

ORIGINAL ANSWER:

The solution is to subclass FUITableViewDataSource and override the UITableViewDataSource methods you want. Everything worked perfectly after that.

import UIKit
import FirebaseDatabaseUI

class FUIEditableTableViewDataSource: FUITableViewDataSource {

/// Called to populate each cell in the UITableView.
typealias PopulateCellBlock = (UITableView, IndexPath, FIRDataSnapshot) -> UITableViewCell

/// Called to commit an edit to the UITableView.
typealias CommitEditBlock = (UITableView, UITableViewCellEditingStyle, IndexPath) -> Void

private let commitEditBlock: CommitEditBlock?

/// A wrapper around FUITableViewDataSource.init(query:view tableView:populateCell:), with the
/// addition of a CommitEditBlock.
public init(query: FIRDatabaseQuery,
tableView: UITableView,
populateCell: @escaping PopulateCellBlock,
commitEdit: @escaping CommitEditBlock)
{
commitEditBlock = commitEdit
super.init(query: query, view: tableView, populateCell: populateCell)
}

override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}

override func tableView(_ tableView: UITableView,
commit editingStyle: UITableViewCellEditingStyle,
forRowAt indexPath: IndexPath)
{
if (commitEditBlock != nil) {
commitEditBlock!(tableView, editingStyle, indexPath)
}
}

}

What is the iOS version of firebase list adapter?

The equivalent is:

FUITableViewDataSource

Data source to bind a Firebase query to a UITableView

Equivalent for FirebaseRecyclerAdapter:

FUICollectionViewDataSource

Data source to bind a Firebase query to a UICollectionView

more info here:

FirebaseUI for IOS

Accessing a variable outside closure Swift3

this is what should happens because observe function is asynchronous and the rest of your code is synchronous, in addition if you remove the optional unwrap from requestPostArray? you will get a nil exception because the async task needs time to get executed so the compiler will execute the snyc task before it.
basically what you have to do is the following

 else {

ref.child("Request Posts").observe(.value, with: { (snapshot) in
let count = Int(snapshot.childrenCount)

// Request Post database is empty
if count == 0 {
cell.nameLabel.text = "No requests so far."
cell.userNameLabel.isHidden = true
cell.numberOfRequestsLabel.isHidden = true
}

// Request Post data is populated
else {

var requestPostArray: [RequestPost]? = []
self.ref.child("Request Posts").observe(.value, with: { (snapshot) in
if let result = snapshot.children.allObjects as? [FIRDataSnapshot] {

for child in result {
let post = RequestPost(snapshot: child)
requestPostArray?.append(post)
}
}

else {
print("No Result")
}
print("RequestPostArray size = \(requestPostArray?.count ?? 90)")

cell.nameLabel.text = self.requestPostArray?[indexPath.row].name
cell.userNameLabel.text = self.requestPostArray?[indexPath.row].name
cell.numberOfRequestsLabel.text = self.requestPostArray?[indexPath.row].name
})

}
})
}

another advice think about using singleton so you can gain the reuse of your object and you will not invoke the database several time at the same method like you are doing now.

Visual Studio Find dialog non-standard regular expressions

Maybe for the same reason that Perl, Emacs, extended Regexps all have different 'standard' syntaxes (albeit mostly similar): they were all developed with different requirements. Emacs doesn't seem to offer \d for instance for matching numeric digits. (arguably \d isn't 'standard', but is reasonably widely supported, so one might think that is was standard)

There's support for bidirectional and other unicode characters offers more control than what's available in POSIX, plus there's the rather useful :i and :q as shortcuts for C/C++ identifiers and quoted strings. So the different syntax presumably grew out of the domain-specific requirements of VS.Net. More on the different things supported here.

I agree that it is an annoyance to have a different syntax, but I also find it annoying to remember to type [:digit:] rather than \d when I'm emacs.



Related Topics



Leave a reply



Submit