2017-06-18 46 views
2

如何從(userLocation.swift)中的一個類(GPSLocation)獲取位置結果並將其用於文件(target.swift)中的另一個類中。從swift獲取其他類的位置結果

我需要COUNTRYCODE,城市,經度和緯度:

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

而在文件打印出來:

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

    } 

} 

預先感謝您.. !!!

+0

創建共享實例/單身? – Larme

+0

當你調用'getGPSLocation'時,你不打印你想要的東西嗎? – Sweeper

+0

將閉包傳遞給'getGPSLocation'並從'fetchCountryAndCity'完成處理函數中調用它 – Paulw11

回答

4

您可以在GPSLocation類中獲取位置後定義閉包。

你可以有塊碼的變量在GPSLocation類象下面這樣::您可以通過兩種方式實現它實例GPSLocation

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

,那麼你可以通過代碼塊像:

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

OR你可以傳遞一個代碼塊給你getGPSLocation功能。這裏是如何重新定義你的函數:

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 

    } 

} 

,這將是您的Post類:

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 
    } 

} 
} 

此次關閉你把這裏將運行每當getGPSLocation函數調用完成塊,我重寫上面的功能。

+0

根據您的建議更新代碼...但是我在收到錯誤時我想debugPrint在** target.swif ** ..我評論打印部分在** userLocation.swif ** t只是爲了檢查它是否正在工作... –

+0

好吧,我編輯了我的封閉,現在它有2個變量lat和lng,現在你可以在調用函數時在你的代碼塊中打印這些代碼。 –

+1

不要忘記在getGPSLocation函數中調用完成塊。 –

3

您可以使用委託模式來做到這一點。使用委託模式,您不僅可以獲取經度,緯度,城市和國家,還可以執行錯誤處理。

首先,改寫fetchCountryAndCity包括一個錯誤處理:

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

然後,創建一個委託協議:

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

弱屬性delegate添加到GPSLocation

weak var delegate: GPSLocationDelegate? 

在適當的時候,調用委託方法:

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

Post類,使Post符合GPSLocationDelegate

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

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

添加一個名爲gpsLocation屬性:

let gpsLocation = GPSLocation() 

在初始化,其委託設置爲self和呼叫getLocation

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

您的位置信息應在成功讀取後打印。

+0

我也試過這個,但它僅用於獲取和打印** userLocation.swift **中的變量。我需要變量來打印另一個類Post,function Post()/ file ** target.swift ** –

+0

@FanbandTest請參閱已編輯的答案 – Sweeper