Search code examples
iosswiftgeolocationmapkitcllocationmanager

Get location results from another class in swift


How to get location results from one class (GPSLocation) from (userLocation.swift) and use them in another class in file (target.swift)..?

I need countryCode, city, longitude and latitude from:

userLocation.swift

import UIKit
import MapKit

class GPSLocation {

func getGPSLocation(completion: () -> Void) {

    let locManager = CLLocationManager()
    var currentLocation: CLLocation!
    locManager.desiredAccuracy = kCLLocationAccuracyBest

    if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse || CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways) {

        currentLocation = locManager.location

        let latitude = String(format: "%.7f", currentLocation.coordinate.latitude)
        let longitude = String(format: "%.7f", currentLocation.coordinate.longitude)
        let location = CLLocation(latitude: currentLocation.coordinate.latitude, longitude: currentLocation.coordinate.longitude)

        fetchCountryAndCity(location: location) { countryCode, city in
            // debugPrint("Country:", countryCode)
            // debugPrint("City:", city)
        }
        // debugPrint("Latitude:", latitude)
        // debugPrint("Longitude:", longitude)
    }
}

//MARK: Find countryCode & City name from longitude & latitude

func fetchCountryAndCity(location: CLLocation, completion: @escaping (String, String) -> ()) {
    CLGeocoder().reverseGeocodeLocation(location) { placemarks, error in
        if let error = error {
            debugPrint(error)
        } else if let countryCode = placemarks?.first?.isoCountryCode,
            let city = placemarks?.first?.locality {
            completion(countryCode, city)
        }
    }
}
}

And print them in file:

target.swift

import Foundation

class Post {

 fileprivate func Post() {

    func getLocation() {
        // Get user GPS location (longitude, latitude, Country Code, City)
        let getUserLocation = GPSLocation()
        getUserLocation.getGPSLocation {
            debugPrint("Country:", countryCode)
            debugPrint("City:", city)
            debugPrint("Latitude:", latitude)
            debugPrint("Longitude:", longitude)
        }
    }

  }

}

Thank you in advance..!!!


Solution

  • You can define a closure to run after getting location in your GPSLocation class. You can achieve it in two way:

    You can have a variable of a block code in your GPSLocation class like below :

    typealias completionHanlder = (_ lat: String, _ lng: String) -> Void
    var completion: completionHanlder?
    

    then in your Post class after instantiating GPSLocation you can pass a block of codes like :

    getUserLocation.completion = {
           // do any stuff here     
    }
    

    OR you can pass a block of code to your getGPSLocation function. here is how to redefine your function :

    func getGPSLocation(completion: (_ lat: String, _ lng: String) -> Void) {        
        let locManager = CLLocationManager()
        var currentLocation: CLLocation!
        locManager.desiredAccuracy = kCLLocationAccuracyBest
    
        if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse || CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways) {
    
        currentLocation = locManager.location
    
        let latitude = String(format: "%.7f", currentLocation.coordinate.latitude)
        let longitude = String(format: "%.7f", currentLocation.coordinate.longitude)
        let location = CLLocation(latitude: currentLocation.coordinate.latitude, longitude: currentLocation.coordinate.longitude)
    
        fetchCountryAndCity(location: location, completion: { countryCode, city in
            delegate?.fetchedLocationDetails(location: location, countryCode: countryCode, city: city)
        }) { delegate?.failedFetchingLocationDetails(error: $0) }
    
        debugPrint("Latitude:", latitude)
        debugPrint("Longitude:", longitude)
    
        completion(latitude, longitude)  // your block of code you passed to this function will run in this way
    
       }
    
    }
    

    and this would be your Post class :

    class Post {
    
    func getLocation() {
        // Get user GPS location (longitude, latitude, Country Code, City)
        let getUserLocation = GPSLocation()
        getUserLocation.getGPSLocation { (lat, lng) in
    
            debugPrint("Latitude:", lat)
            debugPrint("Longitude:", lng)
            // HERE I NEED to PRINT longitude, latitude, Country Code, City
        }
    
    }
    }
    

    This closure you put here would run whenever completion block called in getGPSLocation function as I rewrite your function above.