2017-06-18 5 views
2

Wie erhalte ich Lokalergebnisse von einer Klasse (GPSLocation) von (userLocation.swift) und verwende sie in einer anderen Klasse in der Datei (target.swift) ..?Erhalte Lokationsergebnisse von einer anderen Klasse in swift

Ich brauche Ländercode, Stadt, Länge und Breite von:

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) 
     } 
    } 
} 
} 

Und sie in der Datei drucken:

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) 
     } 
    } 

    } 

} 

Vielen Dank im Voraus .. !!!

+0

Erstellen Sie eine SharedInstance/Singleton? – Larme

+0

Wenn Sie 'getGPSLocation' aufrufen, drucken Sie nicht schon das Zeug, das Sie wollen? – Sweeper

+0

Übergeben Sie eine Closure an 'getGPSLocation' und rufen Sie sie aus dem' fetchCountryAndCity'-Beendigungshandler auf. – Paulw11

Antwort

4

Sie können eine Schließung definieren, die ausgeführt wird, nachdem Sie den Standort in Ihrer GPSLocation Klasse erreicht haben. Sie können es in zwei Art und Weise erreichen:

Sie können wie unten in Ihre GPSLocation Klasse eine Variable eines Blockcodes haben:

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

dann in Ihrer Post Klasse nach GPSLocation Instanziieren Sie einen Block von Codes passieren kann wie:

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

ODER Sie einen Code-Block zu Ihrer getGPSLocation Funktion übergeben können.hier ist, wie Sie Ihre Funktion neu zu definieren:

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 

    } 

} 

und dies würde Ihre Post Klasse:

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 
    } 

} 
} 

Dieser Verschluss Sie hier setzen würde ausgeführt, wenn Abschluss Block in getGPSLocation Funktion aufgerufen, wie ich Ihre Funktion oben umschreiben .

+0

Ich aktualisiere Code in Frage nach Ihrem Rat ... aber ich bekomme Fehler wenn Ich möchte debuggenPrint in ** target.swif ** .. Ich kommentierte Druck Teil in ** userLocation.swif ** t nur um zu überprüfen, ob es funktioniert ... –

+0

okay, ich habe meine Schließung bearbeitet, jetzt hat es 2 Variablen lat und lng, jetzt können Sie diese beim Aufruf der Funktion in Ihrem Blockcode ausdrucken. –

+1

Vergessen Sie nicht, den Completion-Block in der Funktion getGPSLocation aufzurufen. –

3

Sie können dies mit dem Delegatenmuster tun. Mit dem Delegate-Muster können Sie nicht nur den Längengrad, den Breitengrad, die Stadt und das Land abrufen, sondern auch die Fehlerbehandlung durchführen.

Zuerst umschreiben fetchCountryAndCity einen Fehlerhandler enthalten:

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

Erstellen Sie dann einen Delegaten Protokoll:

protocol GPSLocationDelegate { 
    func fetchedLocationDetails(location: CLLocation, countryCode: String, city: String) 
    func failedFetchingLocationDetails(error: Error) 
} 

hinzufügen schwache Eigenschaft delegate-GPSLocation:

weak var delegate: GPSLocationDelegate? 

Rufen Sie zu gegebener Zeit die Delegate-Methoden auf :

public func getGPSLocation() { 

    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) 
    } 
} 

In der Post Klasse Post-GPSLocationDelegate konform machen:

class Post: GPSLocationDelegate { 
    func fetchedLocationDetails(location: CLLocation, countryCode: String, city: String) { 
     // print the stuff here 
    } 

    func failedFetchingLocationDetails(error: Error) { 
     // handle errors 
    } 
} 

eine Eigenschaft hinzufügen gpsLocation genannt:

let gpsLocation = GPSLocation() 

Im initializer, setzen Sie den Delegierten zu self und Call getLocation:

init() { 
    gpsLocation.delegate = self 
    gpsLocation.getLocation() 
} 

Ihre Standortdetails sollten gedruckt werden, nachdem sie erfolgreich abgerufen wurden.

+0

Ich versuche das auch, aber es ist nur für das Abrufen und Drucken von Variablen in ** userLocation.swift **. Ich brauche Variablen zum Drucken in einer anderen Klasse Post, Funktion Post()/Datei ** target.swift ** –

+0

@FanbandTest Siehe die bearbeitete Antwort – Sweeper

Verwandte Themen