             self.locationManager.requestWhenInUseAuthorization()
         }
     }
-
-}
+}
+
+extension LocationManagerSwift : LocationOperationDelegate {
+    
+    func operationDidStart(operation :LocationOperation) {
+        print("Location update started")
+    }
+    
+    func operationDidFinish(operation: LocationOperation, status: LocationOperationStatus, error: NSError?) {
+        print("Location update finished \(status) \(error)")
+    }
+    
+    func operationDidUpdateLocation(operation :LocationOperation, location: CLLocation) {
+        
+        self.longitude = location.coordinate.longitude
+        self.latitude = location.coordinate.latitude
+        
+        NSUserDefaults.standardUserDefaults().setObject(NSDate(), forKey: kLastLocationUpdate)
+        NSUserDefaults.standardUserDefaults().setDouble(self.latitude, forKey: kLastLocationLatitude)
+        NSUserDefaults.standardUserDefaults().setDouble(self.longitude, forKey: kLastLocationLongitude)
+        
+        NSNotificationCenter.defaultCenter().postNotificationName(kLocationUpdated, object: nil)
+    }
+}
+
+// MARK: Location operation
+
+public enum LocationOperationStatus :String {
+    case OK                         = "OK"
+    case TIME                       = "TIME"
+    case ERROR                      = "ERROR"
+    case MISSING_AUTHORIZATION      = "MISSING AUTHORIZATION"
+    case LOCATION_SERVICE_DISABLED  = "LOCATION SERVICE DISABLED"
+}
+
+class LocationOperation: NSOperation, CLLocationManagerDelegate
+{
+    lazy var locationManager = CLLocationManager()
+    
+    private var _executing : Bool = false
+    private var _finished: Bool = false
+    
+    override var executing : Bool {
+        get { return _executing }
+        set {
+            guard _executing != newValue else { return }
+            willChangeValueForKey("isExecuting")
+            _executing = newValue
+            didChangeValueForKey("isExecuting")
+        }
+    }
+    
+    override var finished: Bool {
+        get { return _finished }
+        set {
+            guard _finished != newValue else { return }
+            willChangeValueForKey("isFinished")
+            _finished = newValue
+            didChangeValueForKey("isFinished")
+        }
+    }
+}
+
+protocol LocationOperationDelegate
+{
+    func operationDidStart(operation :LocationOperation)
+    
+    func operationDidFinish(operation :LocationOperation, status :LocationOperationStatus, error :NSError?)
+ 
+    func operationDidUpdateLocation(operation :LocationOperation, location: CLLocation)
+}
+
+final class LocationUpdateOperation: LocationOperation
+{
+    var delegate: LocationOperationDelegate?
+    var locationCompletionHandler :LocationCompletionHandler?
+    
+    func requestLocation(status :CLAuthorizationStatus = .AuthorizedWhenInUse, accuracy :CLLocationAccuracy = kCLLocationAccuracyBest) {
+        
+        guard CLLocationManager.locationServicesEnabled() else {
+            stopUpdatingLocation(status: .LOCATION_SERVICE_DISABLED)
+            return
+        }
+        
+        locationManager.delegate = self
+        locationManager.desiredAccuracy = accuracy
+        
+        switch CLLocationManager.authorizationStatus() {
+        case .AuthorizedAlways, .AuthorizedWhenInUse:
+            startUpdatingLocation()
+        case .Denied, .Restricted:
+            stopUpdatingLocation(status: .MISSING_AUTHORIZATION)
+        case .NotDetermined:
+            if status == .AuthorizedAlways {
+                locationManager.requestAlwaysAuthorization()
+            }
+            else {
+                locationManager.requestWhenInUseAuthorization()
+            }
+        }
+    }
+    
+    func startUpdatingLocation() {
+        
+        locationManager.startUpdatingLocation()
+        delegate?.operationDidStart(self)
+    }
+    
+    func stopUpdatingLocation(latitude: Double = 0.0, longitude: Double = 0.0, status :LocationOperationStatus, error :NSError? = nil) {
+        
+        locationManager.stopUpdatingLocation()
+        
+        if let locationCompletionHandler = locationCompletionHandler {
+            locationCompletionHandler(latitude: latitude, longitude: longitude, status: status, error: error)
+        }
+        
+        delegate?.operationDidFinish(self, status: status, error: error)
+        
+        self._executing = false
+        self._finished = true
+    }
+}
+
+extension LocationUpdateOperation
+{
+    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
+        
+        switch status {
+        case .AuthorizedAlways, .AuthorizedWhenInUse:
+            startUpdatingLocation()
+        case .Denied, .Restricted:
+            stopUpdatingLocation(status: .MISSING_AUTHORIZATION)
+        case .NotDetermined:
+            break
+        }
+    }
+    
+    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
+        stopUpdatingLocation(status: .ERROR, error: error)
+    }
+    
+    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
+        
+        guard let location = locations.last else {
+            return
+        }
+        
+        let timeSinceLastUpdate = location.timestamp.timeIntervalSinceNow
+        
+        // Check for cached location and invalid measurement
+        guard fabs(timeSinceLastUpdate) < 5.0 && location.horizontalAccuracy > 0.0 else {
+            return
+        }
+        
+        delegate?.operationDidUpdateLocation(self, location: location)
+        
+        stopUpdatingLocation(location.coordinate.latitude, longitude: location.coordinate.longitude, status: .OK, error: nil)
+    }
+}

    
    private var updateDistanceThreshold :Double!
    private var updateTimeintervalThreshold :Double!
    private var initWithLastKnownLocation = true
    
    private var googleAPIKey :String?
    private var googleAPIResultType :String?

    // Initialize longitude and latitude with last know location
    public lazy var latitude:Double = {

        self.googleAPIResultType = googleAPIResultType
        self.updateDistanceThreshold = updateDistanceThreshold
        self.updateTimeintervalThreshold = updateTimeintervalThreshold
        self.desiredLocationAccuracy = locationAccuracy
        self.initWithLastKnownLocation = initWithLastKnownLocation
    }
    
