Hi all,
I have been facing a problem while loading a file from the firebase storage. Basically in my code i have a data model which is the file/document (pdf in this case), a manager which goes into the database of Firebase to fetch the object and finally two views, one to list the files fetched and another one to show the document.
I can fetch all the documents with their specific data, pass them to my view and then show the document pdf in another view.
Everything seems correct but the problem comes when opening one of this docs. First, the doc doesn't open at first so you need to close the view and try to open the doc again. Then when i want to open another doc from my list, when i click on it the previous document is shown and not the correct one, so i need to do the same, close the view and click again on the doc to open the correct one.
So at the end what i'm looking for is to open the doc just clicking once but i don't know where is my problem.
List of docs:
1st time:
2nd time:
2nd doc but 1st time:
2nd doc and 2nd time clicking on it:
Here is my code
- Model:
struct DocumentoPdf {
let titulo: String
let docUrl: URL?
let id: String
let storageUrl: String
}
- Manager which fetches the documents from firebase:
final class DatabaseManager {
[...]
public func getNovedades(completion: @escaping ([DocumentoPdf]) -> Void) {
database.collection("novedades").getDocuments { snapshot, error in
guard let documents = snapshot?.documents.compactMap ({ $0.data() }), error == nil else {
return
}
let novedades: [DocumentoPdf] = documents.compactMap({ dictionary in
guard let id = dictionary["id"] as? String,
let titulo = dictionary["titulo"] as? String,
let docUrlString = dictionary["docUrl"] as? String,
let storageUrl = dictionary["storageUrl"] as? String else {
return nil
}
let novedad = DocumentoPdf(titulo: titulo,
docUrl: URL(string: docUrlString),
id: id,
storageUrl: storageUrl)
return novedad
})
completion(novedades)
}
}
}
- First View:
class NovedadesViewControllerViewModel {
let docUrl: URL?
var docData: Data?
init(docUrl: URL?) {
self.docUrl = docUrl
}
}
class NovedadesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, PDFViewDelegate {
private var tableView = UITableView()
private var doc = PDFDocument()
public func configureDocPdf(with viewModel: NovedadesViewControllerViewModel) {
if let data = viewModel.docData {
doc = PDFDocument(data: data)!
}
else if let url = viewModel.docUrl {
// fetch doc & cache
let task = URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in
guard let data = data else {
return
}
viewModel.docData = data
DispatchQueue.main.async {
self?.doc = PDFDocument(data: data)!
}
}
task.resume()
}
}
private var novedades: [DocumentoPdf] = []
private func obtenerNovedades() {
DatabaseManager.shared.getNovedades() { [weak self] novedades in
self?.novedades = novedades
DispatchQueue.main.async {
self?.tableView.reloadData()
}
}
}
override func viewDidLoad() {
[...]
obtenerNovedades()
[...]
}
[... sections, rows in section...]
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let novedad = novedades[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = novedad.titulo
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let novedad = novedades[indexPath.row]
switch indexPath.section {
case 0:
configureDocPdf(with: .init(docUrl: novedad.docUrl))
let lectorPdfView = LectorPdfViewController(doc: self.doc, nameDoc: novedad.titulo)
self.present(lectorPdfView, animated: true, completion: nil)
default:
break
}
}
}
- Second View to load the pdf:
class LectorPdfViewController: UIViewController, PDFViewDelegate {
private let navBar = UINavigationBar()
private let pdf = PDFView()
let nameDoc: String
let doc: PDFDocument
init(doc: PDFDocument, nameDoc: String) {
self.doc = doc
self.nameDoc = nameDoc
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError()
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
view.addSubview(navBar)
view.addSubview(pdf)
pdf.document = self.doc
pdf.delegate = self
let item = UINavigationItem(title: self.nameDoc)
navBar.setItems([item], animated: false)
navBar.barTintColor = .systemBackground
}
override func viewDidLayoutSubviews() {
navBar.frame = CGRect(x: 0,
y: 0,
width: view.frame.size.width,
height: 50)
pdf.frame = CGRect(x: 0,
y: navBar.frame.height,
width: view.frame.size.width,
height: view.frame.size.height - navBar.frame.height)
}
}
Please if someone can help me with this will be fantastic. I hope you understood my code and my problem. Sorry for my bad english
Thank you so much in advance