Search code examples
iosswiftxcodecore-locationcllocation

Location based app using CL Location. Having issues with one line in my code


I am making this app and keep getting this error "Value of type ‘LocationsStorage’ has no member ‘saveCLLocationToDisk’"

I can't figure out why the issue is and I have even tried to look into the documentation on Apple's website but I still don't know what the issue is. The line in question is after section 4

import UIKit
import CoreLocation
import UserNotifications

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate {
  var window: UIWindow?
  static let geoCoder = CLGeocoder()

  let center = UNUserNotificationCenter.current()
  let locationManager = CLLocationManager()

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    let rayWenderlichColor = UIColor(red: 0/255, green: 104/255, blue: 55/255, alpha: 1)
    UITabBar.appearance().tintColor = rayWenderlichColor
    center.requestAuthorization(options: [.alert, .sound]) { granted, error in

    }
    locationManager.requestAlwaysAuthorization()
    locationManager.startMonitoringVisits()
    locationManager.delegate = self as? CLLocationManagerDelegate

    locationManager.distanceFilter = 35
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.startUpdatingLocation()
    return true
  }

}
extension AppDelegate: CLLocationManagerDelegate {
  func locationManager(_ manager: CLLocationManager, didVisit visit: CLVisit) {
    // create CLLocation from the coordinates of the CLVisit
    let clLocation = CLLocation(latitude: visit.coordinate.latitude, longitude: visit.coordinate.longitude)
    AppDelegate.geoCoder.reverseGeocodeLocation(clLocation) { placemarks, _ in
      if let place = placemarks?.first {
        let description = "\(place)"
        self.newVisitReceived(visit, description: description)
      }
    }

  }

  func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
      // 1
      guard let location = locations.first else {
        return
      }

      // 2
      AppDelegate.geoCoder.reverseGeocodeLocation(location) { placemarks, _ in
      if let place = placemarks?.first {
        // 3
        let description = "Fake visit: \(place)"

        //4
        let fakeVisit = FakeVisit(
          coordinates: location.coordinate,
          arrivalDate: Date(),
          departureDate: Date())
        self.newVisitReceived(fakeVisit, description: description)
      }
    }
  }
  // MY issue is here in the line with the ** before and after it
  func newVisitReceived(_ visit: CLVisit, description: String) {
    let location = Location(visit: visit, descriptionString: description)
    **LocationsStorage.shared.saveLocationOnDisk(location)**

    // save location to the disk

    // Get location description

    let content = UNMutableNotificationContent()
    content.title = "New Journal Entry 📌"
    content.body = location.description
    content.sound = .default

    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
    let request = UNNotificationRequest(identifier: location.dateString, content: content, trigger: trigger)

    center.add(request, withCompletionHandler: nil)

  }

}

final class FakeVisit: CLVisit {
  private let myCoordinates: CLLocationCoordinate2D
  private let myArrivalDate: Date
  private let myDepartureDate: Date

  override var coordinate: CLLocationCoordinate2D {
    return myCoordinates
  }

  override var arrivalDate: Date {
    return myArrivalDate
  }

  override var departureDate: Date {
    return myDepartureDate
  }

  init(coordinates: CLLocationCoordinate2D, arrivalDate: Date, departureDate: Date) {
    myCoordinates = coordinates
    myArrivalDate = arrivalDate
    myDepartureDate = departureDate
    super.init()
  }

  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
}

Solution

  • Looks like you are working through the following tutorial

    Just over half way through the tutorial there is a section and code block that looks like this:

    Saving Records on Disk

    Open LocationsStorage.swift. At the bottom of the class, add the following function:

    func saveLocationOnDisk(_ location: Location) {
      // 1
      let encoder = JSONEncoder()
      let timestamp = location.date.timeIntervalSince1970
    
      // 2
      let fileURL = documentsURL.appendingPathComponent("\(timestamp)")
    
      // 3
      let data = try! encoder.encode(location)
    
      // 4
      try! data.write(to: fileURL)
    
      // 5
      locations.append(location)
    }
    

    Make sure that you have added this method and are using the correct name to call the method in your code