skip to Main Content

My application read the data correctly and all things work as needed but when I run it on my iphone the data is not shown like it is empty or null, I checked the code try to figure out why but I did not find out the problem. and when I read the data directly in " FirstScreenViewController" View Controller the data is appear so I do know exactly where is the problem any help please
My code:

//
//  DataManager.swift
//  Aqra3
//
//  Created by Mahmoud Abdelaziz on 14/01/2023.
//


import UIKit
import FirebaseFirestore

class DataManager {
    static let shared = DataManager()
    var delegate: DataManagerDelegate?

    //var dataCache = [String: Any]() // for screen 1 [0] is the title
    let currentDateTime = Date()
    var db: Firestore!
    var db2: Firestore!
    var db3: Firestore!

    //var db4: Firestore!
    //var dailyAdvice = String()
    var screenOneBody = String()
    var screenOneTitle = String()
    var screenTwoBody = String()
    var screenTwoTitle = String()
    var screenThreeBody = String()
    var screenThreeTitle = String()
    
    //private init() {}

    func fetchDataFromFirestore(date: String) {
        let settings = FirestoreSettings()
        Firestore.firestore().settings = settings
        db = Firestore.firestore()
        db2 = Firestore.firestore()
        db3 = Firestore.firestore()
        //db4 = Firestore.firestore()
        
        //let topicDay = String(self.currentDateTime.formatted(date: .abbreviated, time: .omitted))// exp Jan 3, 2023

        let screenOne = db.collection("Screen1").document(date)
        screenOne.getDocument{ (document, error) in
            if let document = document, document.exists {
                self.screenOneBody = document.get("Body")! as! String
                self.screenOneTitle = document.get("Title")! as! String
                print("Screen One Body: (self.screenOneBody) n")
                print("Screen One Title: (self.screenOneTitle) n")
                print("Data: (date) n")
               // DispatchQueue.main.async {
               //     self.delegate?.dataDidUpdate()
               // }
                let screenTwo = self.db2.collection("Screen2").document(date)
                screenTwo.getDocument{ (document, error) in
                    if let document = document, document.exists {
                        self.screenTwoBody = document.get("Body")! as! String
                        self.screenTwoTitle = document.get("Title")! as! String
                        print("Screen Two Body: (self.screenTwoBody) n")
                        print("Screen Two Title: (self.screenTwoTitle) n")
                        print("Data: (date) n")
                        
                        let screenThree = self.db3.collection("Screen3").document(date)
                        screenThree.getDocument { (document, error) in
                            if let document = document, document.exists {
                                self.screenThreeBody = document.get("Body")! as! String
                                self.screenThreeTitle = document.get("Title")! as! String
                                print("Screen Three Body: (self.screenThreeBody) n")
                                print("Screen Three Title: (self.screenThreeTitle) n")
                                print("Data: (date) n")
                            } else {
                                        print("Document does not exist")
                                        print("Data: (date)")
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

protocol DataManagerDelegate {
    func fetchDataFromFirestore(date: String)
    func dataDidUpdate()

}

//
//  FirstScreenViewController.swift
//  Aqra3
//
//  Created by Mahmoud Abdelaziz on 01/01/2023.
//

import UIKit
import SwiftUI
import FirebaseFirestore

class FirstScreenViewController: UIViewController, DataManagerDelegate {
    func fetchDataFromFirestore(date: String) {
        DataManager.shared.fetchDataFromFirestore(date: date)
        changeTheBody()
        DataManager.shared.delegate?.dataDidUpdate()
        
    }
    
    //var newDateFromMenu = SideMenuViewController()
    var db: Firestore!
    let currentDateTime = Date()
    let refreshControl = UIRefreshControl()
    var refreshTimer = Timer()
    
    @IBOutlet weak var FirstScreenTextView: UITextView!
    @IBOutlet weak var firstScreenTitle: UITextView!
    

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.hidesBackButton = true // hide the back button
        let settings = FirestoreSettings()
        Firestore.firestore().settings = settings
        db = Firestore.firestore()
        //self.navigationController!.navigationBar.tintColor = UIColor.red // this if you want to cahnge the navigationBar color without change the global tint color

        //DataManager.shared.fetchDataFromFirestore()
        let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(handleGesture))

        swipeLeft.direction = .right
        self.view.addGestureRecognizer(swipeLeft)
        DataManager.shared.delegate = self

        //let topicDay = String(self.currentDateTime.formatted(date: .abbreviated, time: .omitted))// exp Jan 3, 2023
        //DataManager.shared.fetchDataFromFirestore(date: topicDay)
        changeTheBody()
        
        refreshTimer = Timer.scheduledTimer(timeInterval: 0.0, target: self, selector: #selector(changeTheBody), userInfo: nil, repeats: true)
    

    }
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        refreshTimer.invalidate()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        refreshTimer = Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(changeTheBody), userInfo: nil, repeats: true)
    }

    
    @objc func changeTheBody() {
        FirstScreenTextView.text =  "(DataManager.shared.screenOneBody)"
        //FirstScreenTextView.semanticContentAttribute = .forceRightToLeft
        let style = NSMutableParagraphStyle()
        style.lineSpacing = 10  // adjust line spacing as needed
        style.baseWritingDirection = .rightToLeft
        style.alignment = .justified
        let attributes = [    NSAttributedString.Key.paragraphStyle: style]
        FirstScreenTextView.attributedText = NSAttributedString(string: FirstScreenTextView.text, attributes: attributes)
        FirstScreenTextView.font = UIFont.systemFont(ofSize: 20)
        FirstScreenTextView.textColor = UIColor.white
        firstScreenTitle.textColor = UIColor.white
        firstScreenTitle.text =  "(DataManager.shared.screenOneTitle)"

        refreshControl.endRefreshing()

    }
    @objc func handleGesture(gesture: UISwipeGestureRecognizer) -> Void {
        if gesture.direction == UISwipeGestureRecognizer.Direction.right {
            performSegue(withIdentifier: "fromFirstScreenToMainScreen", sender: self)
        }
    }
    
   /* override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "goToResult" {
            let destinationVC = segue.destination as! SideMenuViewController
 
        }
    }*/
    func dataDidUpdate() {
        changeTheBody()
    }
}

//
//  AppDelegate.swift
//  AQRA3
//
//  Created by Mahmoud Abdelaziz on 01/01/2023.
//

import UIKit
import FirebaseCore
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    let currentDateTime = Date()



    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let topicDay = String(self.currentDateTime.formatted(date: .abbreviated, time: .omitted))// exp Jan 3, 2023
        FirebaseApp.configure()
        DataManager.shared.fetchDataFromFirestore(date: topicDay)
        return true
    }

    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }


}

2

Answers


  1. Chosen as BEST ANSWER

    I know the problem The data is saved in the firestore with the date in this format Jan 10, 2023 Jan 24, 2023 and so on when get the date i was test getting it with the simulator and the format was the same MMM DD, YYYY, but when turn on the physical device the format was DD MMM, YYYY so I add a code to force the format to be MMM DD, YYYY

    let topicDay = String(self.currentDateTime.formatted(date: .abbreviated, time: .omitted) )// exp Jan 3, 2023
    let dateString = topicDay
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "dd MMM yyyy"
    
    let date = dateFormatter.date(from: dateString)
    
    dateFormatter.dateFormat = "MMM dd, yyyy"
    let newDateString = dateFormatter.string(from: date!)
    

  2. I think I know what is happening here.

    When you read the data in your AppDelegate, it gets read, and the delegate callback (self.delegate?.dataDidUpdate()) in the DataManager occurs before you set your FirstScreenViewController view controller as the DataManager‘s delegate (on the line DataManager.shared.delegate = self). At this point the DataManager‘s delegate is nil, so you do not receive the callback in your view controller.

    The correct way to ensure that you always get the delegate callback would be that you set the DataManager‘s delegate before you execute the fetchDataFromFirestore(date: String) call.

    If this helps you, please consider marking this as the answer.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search