核心位置代表闭包中的价值

Posted

技术标签:

【中文标题】核心位置代表闭包中的价值【英文标题】:Core-location delegates value in Closures 【发布时间】:2017-01-09 06:47:08 【问题描述】:

您好,我已经在 Swift 3 中实现了核心位置管理器,我想构建一个方法来从其委托中捕获位置值并返回闭包中的值,但无法这样做。任何帮助将不胜感激。

我的代码:

import Foundation
import CoreLocation

class LocationManager : NSObject, CLLocationManagerDelegate

var location: CLLocation?
var locationManager : CLLocationManager?
var currentLocation : CLLocationCoordinate2D?
var latitude : String?
var longitude : String?
var lat : Float?
var lon : Float?

//  var locationManagerCallback : (Float?,Float?,String?,String?) ->()


static let sharedInstance : LocationManager = 
    let instance = LocationManager()
    return instance
()


// MARK: - CLLocation Fetch Methods

func fetchLocationWithCompletionHandler(completion : @escaping(Float?,Float?,String?,String?) -> ()) -> Void 

    if locationManager != nil 

        locationManager?.stopUpdatingLocation()
        locationManager?.delegate = nil
        locationManager = nil
    
    locationManager = CLLocationManager()
    locationManager?.delegate = self
    locationManager?.distanceFilter = kCLLocationAccuracyNearestTenMeters
    locationManager?.desiredAccuracy = kCLLocationAccuracyBest

    let requestWhenInUseSelector = NSSelectorFromString("requestWhenInUseAuthorization")
    let requestAlwaysSelector    = NSSelectorFromString("requestAlwaysAuthorization")

    if (locationManager?.responds(to: requestWhenInUseSelector))! 

        locationManager?.requestWhenInUseAuthorization()

    else if (locationManager?.responds(to: requestAlwaysSelector))!

        locationManager?.requestAlwaysAuthorization()
    
    locationManager?.startUpdatingLocation()




func requestWhenInUseAuthorization() -> Void 

    let status : CLAuthorizationStatus = CLLocationManager.authorizationStatus()
    if status == CLAuthorizationStatus.denied  || status == CLAuthorizationStatus.restricted 
        // TODO : Handle Denial Here
    else if status == CLAuthorizationStatus.notDetermined
        locationManager?.requestWhenInUseAuthorization()
    

func requestAlwaysAuthorization() -> Void 

    let status : CLAuthorizationStatus = CLLocationManager.authorizationStatus()
    if status == CLAuthorizationStatus.denied || status == CLAuthorizationStatus.restricted 
        // TODO : Handle Denial Here
    else if status == CLAuthorizationStatus.notDetermined
        locationManager?.requestAlwaysAuthorization()
    




func reveseGeocode(currentLocation : CLLocation, completionCallback : @escaping(CLPlacemark?,Error?) -> Swift.Void) -> Void 

    let reverseGeocoder : CLGeocoder = CLGeocoder()
    reverseGeocoder.reverseGeocodeLocation(currentLocation)  (placemarkArray, error) in

        let placemark : CLPlacemark = (placemarkArray?.first)!
        completionCallback(placemark,error)
    



// MARK: - CLLocation Delegate Methods

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) 

    self.location = locations[0]
    currentLocation = self.location?.coordinate
    lat = Float((currentLocation?.latitude)!)
    lon = Float((currentLocation?.longitude)!)
    latitude = String(format: "%lf",lat!)
    longitude = String(format : "%lf",lon!)

    UserDefaults.standard.set(lat, forKey: CURR_LAT_VAL)
    UserDefaults.standard.set(lon, forKey: CURR_LON_VAL)
    UserDefaults.standard.set(latitude, forKey: CURR_LAT_STR)
    UserDefaults.standard.set(longitude, forKey: CURR_LON_STR)
    UserDefaults.standard.synchronize()

    print("\(lat)\(lon)\(latitude)\(longitude)")

   // locManager(lat,lon,latitude,longitude)



func locationManagerDidPauseLocationUpdates(_ manager: CLLocationManager) 
    print("location manager did pause")


func locationManagerDidResumeLocationUpdates(_ manager: CLLocationManager) 
    print("location manager did resume")


func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) 
    print("Location fetch failed with error : \(error.localizedDescription)")


func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) 
    print("Authorization Changed")



【问题讨论】:

【参考方案1】:

您需要将 block 变量保存在 LocationManager 类中,如下所示:

1。在你的类中添加变量:

var locationManagerCallback: ((Float?,Float?,String?,String?) -> ())?

2。从开始请求时保存完成块/关闭:

func fetchLocationWithCompletionHandler(completion: @escaping(Float?,Float?,String?,String?) -> ()) -> Void 
    locationManagerCallback = completion

    ...
 

3。从委托方法调用闭包:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) 
    locationManagerCallback?(lat, lon, latitude, longitude)

以下是如何在其他类中使用它:

LocationManager.sharedInstance.fetchLocationWithCompletionHandler  (lat, long, latitude, longitude) in
    print("\(lat)\(long)\(latitude)\(longitude)")

希望对你有帮助。

【讨论】:

以上是关于核心位置代表闭包中的价值的主要内容,如果未能解决你的问题,请参考以下文章

Python核心编程-闭包

viewDidLoad 之外的闭包

Python核心编程的四大神兽:迭代器生成器闭包以及装饰器

闭包中的变量捕获详解

JS核心知识点梳理——闭包

JavaScript语言核心-- 高阶函数 及 闭包