MapKit & Firebase Error

Hello,

I am creating feature on my app that is supposed to launch the iOS map and who a destination using coordinates given from Firebase. I keep getting errors as shown in this video and here is the project:

//
//  ViewController.swift
//  Launch Map Button
//
//  Created by Gilbert Emuge on 8/24/21.
//

import UIKit
import MapKit
import FirebaseDatabase

class ViewController: UIViewController {
    
    // Launch map
    @IBAction func showMeWhere(_ sender: Any)
    {
        //Defining destination

        
        let ref = Database.database().reference()
        ref.child("location").observeSingleEvent(of: .value) {
            (snapshot) in
            let latitude = snapshot.value
            let longitude = snapshot.value
       
            let regionDistance: CLLocationDistance = 1000.0;
            let coordinates = CLLocationCoordinate2DMake(latitude as! CLLocationDegrees, longitude as! CLLocationDegrees)
            
       
        let regionSpan = MKCoordinateRegion(center: coordinates, latitudinalMeters: regionDistance, longitudinalMeters: regionDistance)
        
        let options = [MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center), MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span)]
        
        let placemark = MKPlacemark(coordinate: coordinates)
        let mapItem = MKMapItem(placemark: placemark)
        mapItem.name = "Destination"
        mapItem.openInMaps(launchOptions: options)
            
        }
    }
    

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }


}




/*
 
 @IBAction func showMeWhere(_ sender: Any)
 {
     //Defining destination
     let latitude:CLLocationDegrees = 38.791794
     let longitude:CLLocationDegrees = -90.563419
     
     let regionDistance: CLLocationDistance = 1000;
     let coordinates = CLLocationCoordinate2DMake(latitude, longitude)
     let regionSpan = MKCoordinateRegion(center: coordinates, latitudinalMeters: regionDistance, longitudinalMeters: regionDistance)
     
     let options = [MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center), MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span)]
     
     let placemark = MKPlacemark(coordinate: coordinates)
     let mapItem = MKMapItem(placemark: placemark)
     mapItem.name = "Destination"
     mapItem.openInMaps(launchOptions: options)
 }
 
 */

“An unrecognised selector” is usually where you have a disconnection between your storyboard and the associated ViewContoller. You may have renamed an IBOutlet or IBAction in your ViewController.swift file and that name now differs to the name that is associated with the storyboard object.

If you open your storyboard and then select the ViewController you last changed that broke your code, select the left most Icon at the top of the VC and then in your inspector panel choose the “Connections Inspector” and scan down the connections to see if there is an Amber triangle to the right. If there is then that’s the problem object. See the example image below for what I am getting at.

To solve the problem you must delete that entry and then re-create the connection between your storyboard object and your associated ViewController.

I’ll check it out. Thanks for the speedy reply!

Tap the x to the left of the connection that has the Amber triangle and that will remove it.

I don’t see the error on the connection. I went ahead and hit the “x” and reconnected it and I still get the same error as it crashes. I tried it with it disconnected and the error persists. I have the project here: https://drive.google.com/file/d/1v9w0uAXxJQtu-JoYCjNFm3u-iFTuWxF4/view?usp=sharing


@coder3000

Hi Gilbert,

You’ve got Firebase frameworks installed via Cocoapods and also via Swift Package Manager. Is there a reason for both?

(edit) When you installed Firebase using Swift Package Manager, do you remember what Firebase Frameworks you selected?

Oh… That’s internet. I didn’t realize I was using both the package manager and coco pods. I’ll change that. I am trying to use firebase database.

Are you using the Firestore database rather than the RealTime Database?

Yes, Firestore database. The Realtime seem like a better option. I will use Realtime Database once I have an understanding of Firestore database. I know I will need the bit of Realtime Datatbase knowledge soon. It’s just these errors that I run into that I am learning about. I thank you for your tips and suggestions as I progress in the coding realm.

I’m not so sure that the RealTime Database is the best option. I think you will find that the Firestore Database is much easier to use once you get the hang of it.

OK I have got it to work.

I assume that you have a Cloud Firestore collection named “location” and within that you have an auto-generated document which has two fields named latitude and longitude much like this screenshot from a dummy project I set up on my Firebase access.

If that is the case then you need to do these things to your project.

  • Remove Pods from your project by opening Terminal and navigating to your Project. Then type pod deintegrate
  • You can remove the Podfile and Podfile.lock in Finder if you like but you also need to remove the file Launch Map Button.xcworkspace
  • Open the project via Launch Map Button.xcodeproj
  • Clean the Build folder Shift + Command + K
  • Edit the file AppDelegate.swift and change the import statement to import Firebase
  • Edit the ViewController.swift file and change the contents of your IBAction function to this:
    @IBAction func showMeWhere(_ sender: Any) {
        //Defining destination

        let db = Firestore.firestore()
        db.collection("location").getDocuments { snapshot, error in
            if let error = error {
                print(error.localizedDescription)
            } else if let snapshot = snapshot {
                for doc in snapshot.documents {
                    let latitude = doc["latitude"] as! Double
                    let longitude = doc["longitude"] as! Double

                    let regionDistance: CLLocationDistance = 1000.0;
                    let coordinates = CLLocationCoordinate2DMake(latitude , longitude )


                    let regionSpan = MKCoordinateRegion(center: coordinates, latitudinalMeters: regionDistance, longitudinalMeters: regionDistance)

                    let options = [MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center), MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span)]

                    let placemark = MKPlacemark(coordinate: coordinates)
                    let mapItem = MKMapItem(placemark: placemark)
                    mapItem.name = "Destination"
                    mapItem.openInMaps(launchOptions: options)
                }
            }
        }
    }

Build your project and make sure that there are no errors then run it on your simulator.

Yes, my database is just like that… as a test. But ideally it would follow this JSON tree:

{
  "pickup": {
    "name": "Kermit's Salads",
    "phoneNumber": "+12125551234",
    "street": "26 Broadway",
    "city": "New York City",
    "state": "NY",
    "postalCode": "10004",
    "country": "US",
    "latitude": 40.716038,
    "longitude": -74.00631,
    "unit": "104B",
    "instructions": "Use back entrance"
  },
  "dropoff": {
    "name": "Miss Piggy",
    "phoneNumber": "+12125555678",
    "street": "312 Broadway",
    "city": "New York City",
    "state": "NY",
    "postalCode": "10004",
    "country": "US",
    "latitude": 40.24377,
    "longitude": -74.10277,
    "unit": "Suite 300",
    "instructions": "Leave with security guard"
  },
  "orderDetails": [
    {
      "title": "Salad Green",
      "quantity": 3
    }
  ],
  "pickupTime": "2015-09-22T18:30:00.0000000Z",
  "quoteExternalReference": "basket_e699aece",
  "deliveryExternalReference": "order_713a8bd9",
  "tip": 3.5,
  "deliveryId": "cb1915b1-3330-4477-b4bf-88c9b935943c",
  "statusUpdateUrl": "https://dispatch.myWebsite.com/v1",
  "dropoffTime": "2015-09-22T18:30:00.0000000Z",
  "controlledContents": "Alcohol,Tobacco",
  "allowedVehicles": "Walker,Bicycle,DeliveryBicycle,Car,Van",
  "orderValue": 22.5,
  "brandName": "BigBellyBurger",
  "currency": "USD"
}

I’m super stoked that you got it to work! I’ll work on it now.

No problem. See if it works with just those two fields and once you have that behaving properly you can then begin to expand it to suit what you want to achieve.

1 Like

Everything is working but, one more thing. How would I access documents deeper?
This isn’t working:


What am I doing wrong?

@coder3000

I had to go to bed. It was midnight and I have only just surfaced.

To test that all I had was a collection named “location” and the two fields “latitude” and “longitude” as per the screenshot.

As for anything deeper in terms of collections within collections, I am afraid I am a little vague on that.

Hey Chris,

You were a rockstar today! Thanks for the help. Get some sleep! :slightly_smiling_face:

Hey good news! I figured it out!

Well done.

1 Like