spoax
spoax

Reputation: 589

fetch data from Firebase using autoID - Xcode

On the top level of my app I have a tableViewController where you can create new jobs that are saved to my firebase database using an autoID.

Here is the JSON

  {
    "jobInfo" : {
      "-L59sEGslWF7HFza26ay" : {
        "FPS" : "25",
        "director" : "Mike & Jim",
        "jobBrand" : "Honda",
        "jobName" : "Dreammakers"
      },
      "-L59sWGEccWMFEeFWyNU" : {
        "FPS" : "25",
        "director" : "Anthony Test",
        "jobBrand" : "WWF",
        "jobName" : "Eye"
      }
    }
  }

This is the code that links you to the UITabBarController:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let jobInfo = page_jobTabController()
    show(jobInfo, sender: self)
 }

You can then click on one of the cells which takes you to a UItabBarViewController that has 4 tabs. In the first tab I have several textFields that lists information about the job.

I am struggling to work out how to send the autoID from the UITableViewController through the UITabBarController to the UIViewController so the textFields can be filled in with the correct information.

Here is a screenshot of the two pages to get an idea of what I want to do.

enter image description here

Sorry to dump all this code below - I am not trying to spam.

This is my dictionary:

    class Job: NSObject {
        var id: String?
        var jobBrand: String?
        var jobName : String?
        var directorName : String?
        var FPSvalue : String?
        init(dictionary: [String: AnyObject]) {
            self.id = dictionary["id"] as? String
            self.jobBrand = dictionary["jobBrand"] as? String
            self.jobName = dictionary["jobName"] as? String
            self.directorName = dictionary["directorName"] as? String
            self.FPSvalue = dictionary["FPSvalue"] as? String
        }
    }

This is my jobList page (top level)

        class page_jobList: UITableViewController {

        let cellId = "cellId"
        var jobs = [Job]()

        override func viewDidLoad() {
            super.viewDidLoad()
            // NAVIGATION ITEM
            navigationItem.title = "Jobs"
            navigationController?.navigationBar.prefersLargeTitles = true
            tableView.register(JobCell.self, forCellReuseIdentifier: cellId)
            // FIREBASE FETCH JOBS
            fetchJobs()
        }

        // FETCH JOBS
        func fetchJobs() {
            Database.database().reference().child("jobInfo").observe(.childAdded) { (snapshot) in

                if let dictionary = snapshot.value as? [String: AnyObject] {
                        print (snapshot)
                        // PROCESSES VALUES RECEIVED FROM SERVER
                        if ( snapshot.value is NSNull ) {

                            // DATA WAS NOT FOUND
                            print("– – – Data was not found – – –")

                        } else {
                            let job = Job(dictionary: dictionary)
                            job.id = snapshot.key
                            self.jobs.append(job)

                            //this will crash because of background thread, use dispatch_async to fix
                            DispatchQueue.main.async(execute: {
                                self.tableView.reloadData()
                            })
                        }
                    }
                }
            }

        // AFTER DATA IS FETCHED AND ADD IT TO TABLE VIEW
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return jobs.count
        }

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

            let cell =  tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
            let job = jobs[indexPath.row]
            cell.accessoryType = UITableViewCellAccessoryType.disclosureIndicator
            cell.textLabel?.text = job.jobBrand
            cell.detailTextLabel?.text = job.jobName

            return cell
        }

        override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return 72
        }


        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            let jobInfo = page_jobTabController()
            jobInfo.job? = jobs[indexPath.row]
            show(jobInfo, sender: self)
         }
    }

    class JobCell: UITableViewCell {

        override init(style: UITableViewCellStyle, reuseIdentifier: String?){
            super .init(style: .subtitle, reuseIdentifier: reuseIdentifier)
        }
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implented")
        }
    }

This is my tabBarController:

        class page_jobTabController: UITabBarController {
        override func viewDidLoad() {
            super.viewDidLoad()

            // NAVIGATION ITEM

            let jobInfo = page_jobInformation()
            jobInfo.job? = job!
            let shots = page_shotList()
            let attachments = page_attachments()
            let notes = page_notesList()

            jobInfo.tabBarItem.title = "Information"
            jobInfo.tabBarItem.image = UIImage(named: "jobInfo")

            shots.tabBarItem.title = "Shots"
            shots.tabBarItem.image = UIImage(named: "shots")

            attachments.tabBarItem.title = "Attachments"
            attachments.tabBarItem.image = UIImage(named: "attachments")

            notes.tabBarItem.title = "Notes"
            notes.tabBarItem.image = UIImage(named: "notes")

            viewControllers = [jobInfo, shots, attachments, notes]
        }

        @IBAction func HandleEdit(sender : UIButton) {
            let transition = CATransition()
            transition.duration = 0.5
            transition.type = kCATransitionPush
            transition.subtype = kCATransitionFromRight
            transition.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut)
            view.window!.layer.add(transition, forKey: kCATransition)

        }

    }

This is my jobInfo tab ViewController

                class page_jobInformation: UIViewController{

        // CONTENT CREATION

            // GENERAL
        let generalTitle: UILabel = {
            let generalTitle = UILabel()
            generalTitle.font = UIFont(name: "HelveticaNeue", size: 12.0)
            generalTitle.text = "GENERAL"
            generalTitle.translatesAutoresizingMaskIntoConstraints = false
            return generalTitle
        }()
        let jobBrand: UITextField = {
            let jobBrand = UITextField()
            //jobBrand.text = "jobBrand"
            jobBrand.isUserInteractionEnabled = false
            jobBrand.keyboardType = UIKeyboardType.default
            jobBrand.translatesAutoresizingMaskIntoConstraints = false
            return jobBrand
        }()
        let jobName: UITextField = {
            let jobName = UITextField()
            jobName.keyboardType = UIKeyboardType.default
            jobName.text = "jobName"
            jobName.isUserInteractionEnabled = false
            jobName.translatesAutoresizingMaskIntoConstraints = false
            return jobName
        }()
        let directorName: UITextField = {
            let directorName = UITextField()
            directorName.text = "directorName"
            directorName.keyboardType = UIKeyboardType.default
            directorName.isUserInteractionEnabled = false
            directorName.translatesAutoresizingMaskIntoConstraints = false
            return directorName
        }()
        let AgencyName: UITextField = {
            let AgencyName = UITextField()
            AgencyName.text = "Agency"
            AgencyName.keyboardType = UIKeyboardType.default
            AgencyName.isUserInteractionEnabled = false
            AgencyName.translatesAutoresizingMaskIntoConstraints = false
            return AgencyName
        }()
        let prodCoName: UITextField = {
            let prodCoName = UITextField()
            prodCoName.text = "Production Company"
            prodCoName.keyboardType = UIKeyboardType.default
            prodCoName.isUserInteractionEnabled = false
            prodCoName.translatesAutoresizingMaskIntoConstraints = false
            return prodCoName
        }()

            // TECHNICAL
        let technicalTitle: UILabel = {
            let technicalTitle = UILabel()
            technicalTitle.font = UIFont(name: "HelveticaNeue", size: 12.0)
            technicalTitle.text = "TECHNICAL"
            technicalTitle.translatesAutoresizingMaskIntoConstraints = false
            return technicalTitle
        }()
        lazy var jobSpecsButton: UIButton = {
            let jobSpecsButton = UIButton(type: .system)
            jobSpecsButton.setTitle("Job Specifications", for: .normal)
            jobSpecsButton.titleLabel?.font = UIFont(name: "HelveticaNeue", size: 14.0)
            jobSpecsButton.layer.masksToBounds = true
            jobSpecsButton.contentHorizontalAlignment = .left
            jobSpecsButton.setTitleColor(UIColor.gray, for: UIControlState.normal)
            jobSpecsButton.backgroundColor = UIColor(red:1.00, green:1.00, blue:1.00, alpha:1.0)
            jobSpecsButton.setTitleColor(.black, for: .normal)
            jobSpecsButton.translatesAutoresizingMaskIntoConstraints = false

            jobSpecsButton.addTarget(self, action: #selector(HandleJobSpecs), for: .touchUpInside)

            return jobSpecsButton
        }()
        lazy var cameraButton: UIButton = {
            let cameraButton = UIButton(type: .system)
            cameraButton.setTitle("Camera & Lenses", for: .normal)
            cameraButton.titleLabel?.font = UIFont(name: "HelveticaNeue", size: 14.0)
            cameraButton.layer.masksToBounds = true
            cameraButton.contentHorizontalAlignment = .left
            cameraButton.setTitleColor(UIColor.gray, for: UIControlState.normal)
            cameraButton.backgroundColor = UIColor(red:1.00, green:1.00, blue:1.00, alpha:1.0)
            cameraButton.setTitleColor(.black, for: .normal)
            cameraButton.translatesAutoresizingMaskIntoConstraints = false

            cameraButton.addTarget(self, action: #selector(HandleCameraLenses), for: .touchUpInside)

            return cameraButton
        }()
        lazy var SKCButton: UIButton = {
            let SKCButton = UIButton(type: .system)
            SKCButton.setTitle("Shoot Kit Checklist", for: .normal)
            SKCButton.titleLabel?.font = UIFont(name: "HelveticaNeue", size: 14.0)
            SKCButton.layer.masksToBounds = true
            SKCButton.contentHorizontalAlignment = .left
            SKCButton.setTitleColor(UIColor.gray, for: UIControlState.normal)
            SKCButton.backgroundColor = UIColor(red:1.00, green:1.00, blue:1.00, alpha:1.0)
            SKCButton.setTitleColor(.black, for: .normal)
            SKCButton.translatesAutoresizingMaskIntoConstraints = false

            SKCButton.addTarget(self, action: #selector(HandleSKC), for: .touchUpInside)

            return SKCButton
        }()

            // STACKED VIEWS

        lazy var stack:UIStackView = {
            let s = UIStackView(frame: self.view.bounds)
            s.axis = .vertical
            s.distribution = .equalSpacing
            s.alignment = .fill
            s.spacing = 10
            //s.autoresizingMask = [.flexibleWidth, .flexibleHeight]

            s.addArrangedSubview(self.generalTitle)
            s.addArrangedSubview(self.jobBrand)
            s.addArrangedSubview(self.jobName)
            s.addArrangedSubview(self.directorName)
            s.addArrangedSubview(self.AgencyName)
            s.addArrangedSubview(self.prodCoName)
            s.addArrangedSubview(self.technicalTitle)
            s.addArrangedSubview(self.jobSpecsButton)
            s.addArrangedSubview(self.cameraButton)
            s.addArrangedSubview(self.SKCButton)

            return s
        }()

            // SUPER VIEW DID LOAD
        override func viewDidLoad() {
            super.viewDidLoad()
            view.backgroundColor = UIColor.white
        }
            // VIEW WILL APPEAR
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            self.tabBarController?.navigationItem.title = "Job Information"
            self.tabBarController?.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(HandleEditJob))
            view.addSubview(stack)
            jobInfoValues()
            setupLayout()
        }

            // OBSERVE JOB
        var job: Job?

        // FILL IN TEXT FIELDS FROM FIREBASE
        func jobInfoValues(){
            jobBrand.text = job?.jobBrand
            jobName.text = job?.jobName
            directorName.text = job?.directorName
        }

        // BUTTONS & ACTIONS

        @IBAction func HandleJobSpecs(sender : UIButton) {
            let jobSpecs = page_jobSpecs()
            show(jobSpecs, sender: self)
        }
        @IBAction func HandleCameraLenses(sender : UIButton) {
            let cameras = page_camera_lenses()
            show(cameras, sender: self)
        }
        @IBAction func HandleSKC(sender : UIButton) {
            let shootKit = page_SKC()
            show(shootKit, sender: self)
        }
        @IBAction func HandleEditJob(sender : UIButton) {
                // CHANGE NAVIGATION BAR ITEM
            self.tabBarController?.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(HandleJobEditDone))
                // ALLOW TEXT FIELDS TO BE EDITABLE
            jobBrand.isUserInteractionEnabled = true
            jobName.isUserInteractionEnabled = true
            directorName.isUserInteractionEnabled = true
            AgencyName.isUserInteractionEnabled = true
            prodCoName.isUserInteractionEnabled = true
                // ADDING CLEAR BUTTON
            jobBrand.clearButtonMode = .always
            jobName.clearButtonMode = .always
            directorName.clearButtonMode = .always
            AgencyName.clearButtonMode = .always
            prodCoName.clearButtonMode = .always

        }
        @IBAction func HandleJobEditDone(sender : UIButton) {
            self.tabBarController?.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(HandleEditJob))
            jobBrand.isUserInteractionEnabled = false
            jobName.isUserInteractionEnabled = false
            directorName.isUserInteractionEnabled = false
            AgencyName.isUserInteractionEnabled = false
            prodCoName.isUserInteractionEnabled = false
                // ADDING CLEAR BUTTON
            jobBrand.clearButtonMode = .never
            jobName.clearButtonMode = .never
            directorName.clearButtonMode = .never
            AgencyName.clearButtonMode = .never
            prodCoName.clearButtonMode = .never
        }

        // CONSTRAINTS
        private func setupLayout(){

            // Auto layout constraints for jobInfo
            generalTitle.topAnchor.constraint(equalTo: view.topAnchor, constant: 150).isActive = true
            generalTitle.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true

            // Auto layout constraints for jobInfo
            jobBrand.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true

            // Auto layout constraints for cameras
            jobName.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true

            // Auto layout constraints for attachments
            directorName.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true

            // Auto layout constraints for attachments
            AgencyName.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true

            // Auto layout constraints for attachments
            prodCoName.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true

            // Auto layout constraints for attachments
            technicalTitle.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true

            // Auto layout constraints for attachments
            jobSpecsButton.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true

            // Auto layout constraints for attachments
            cameraButton.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true

            // Auto layout constraints for SKC
            SKCButton.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true
            SKCButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -100).isActive = true



        }
    }

Upvotes: 0

Views: 115

Answers (1)

Hsiao Ai Lee
Hsiao Ai Lee

Reputation: 95

Please check the codes. https://github.com/HsiaoAi/JobInfoStackoverflow/tree/master/JobInfoStackoverflow

  1. Make sure your Json decoding is correct, because I found you used"director" in Firebase but "directorName" when init Job

  2. I modified the "fetchJobs()" because I dont have the Firebase plist file

  3. I modified 5 stuff and I marked them in code as "###", you can use search and check them, I hope it works for you too.

enter image description here

Upvotes: 1

Related Questions