Search code examples
swiftdelegatesseguecore-location

Swift get Coordinates Latitude Longitude in a Variable


I am a newbie and would be thankful for any help.

I want the latitude and longitude Value for my Poststring. But it shows that my response string is empty I want in the below long code in the line:

let postString = "latiTude=23&longiTude=12";

Put the Users Position. Now I have to put latiTude and longiTude manually, but I want replace it with the actual users location. I have no Idea how.

import Foundation
import CoreLocation


protocol FeedmodelProtocol: class {
    func itemsDownloaded(items: NSArray)
}


class Feedmodel: NSObject, URLSessionDataDelegate, CLLocationManagerDelegate {



    weak var delegate: FeedmodelProtocol!
    let locationManager = CLLocationManager() // create Location Manager object
    var latitude : Double?
    var longitude : Double?

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let location: CLLocationCoordinate2D = manager.location?.coordinate else { return }
        // set the value of lat and long
        latitude = location.latitude
        longitude = location.longitude

    }

    func downloadItems() {
        self.locationManager.requestAlwaysAuthorization()

        // For use in foreground
        // You will need to update your .plist file to request the authorization
        self.locationManager.requestWhenInUseAuthorization()

        if CLLocationManager.locationServicesEnabled() {
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
            locationManager.startUpdatingLocation()

        }
        let myUrl = URL(string: "http://example.com/stock_service4.php");
        let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
        var request = URLRequest(url:myUrl!)
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "POST"
        var postString = ""
        if let lat = latitude, let long = longitude {
            locationManager.stopUpdatingLocation()
            postString = "lati=\(Int(lat))&longi=\(Int(long))"
            // do task here now that postString is not empty
        }
        request.httpBody = postString.data(using: .utf8)
        let task = defaultSession.dataTask(with: request) { data, response, error in


            guard let data = data, error == nil else {                                                 // check for fundamental networking error
                print("error=\(String(describing: error))")
                return

            }


            if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
                print("statusCode should be 200, but is \(httpStatus.statusCode)")
                print("response = \(String(describing: response))")

            }

            let responseString = String(data: data, encoding: .utf8)
            print("responseString = \(String(describing: responseString))")


        }

        task.resume()

    }

    func parseJSON(_ data:Data) {

        var jsonResult = NSArray()

        do{
            jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray;
        } catch let error as NSError {
            print(error)

        }

        var jsonElement = NSDictionary()
        let stocks = NSMutableArray()

        for i in 0 ..< jsonResult.count
        {
            print(jsonResult)
            jsonElement = jsonResult[i] as! NSDictionary


            let stock = Stockmodel()

            //the following insures none of the JsonElement values are nil through optional binding
            if  let Datum = jsonElement["Datum"] as? String,
                let Tankstelle = jsonElement["Tankstelle"] as? String,
                let Kraftstoff1 = jsonElement["Kraftstoff1"] as? String,
                let Preis1 = jsonElement["Preis1"] as? String,
                let Kraftstoff2 = jsonElement["Kraftstoff2"] as? String,
                let Preis2 = jsonElement["Preis2"] as? String,
                let Notiz = jsonElement["Notiz"] as? String,
                let longitude = jsonElement["longitude"] as? String,
                let latitude = jsonElement["latitude"] as? String



            {
                print (Datum)
                print(Tankstelle)
                print(Kraftstoff1)
                print(Preis1)
                print(Kraftstoff2)
                print(Preis2)
                print(Notiz)
                print(longitude)
                print(latitude)
                stock.Datum = Datum
                stock.Tankstelle = Tankstelle
                stock.Kraftstoff1 = Kraftstoff1
                stock.Preis1 = Preis1
                stock.Kraftstoff2 = Kraftstoff2
                stock.Preis2 = Preis2
                stock.Notiz = Notiz
                stock.longitude = longitude
                stock.latitude = latitude


            }

            stocks.add(stock)

        }

        DispatchQueue.main.async(execute: { () -> Void in

            self.delegate.itemsDownloaded(items: stocks)

        })
    }
}

And this is my php mysql file:

<?php



// Create connection
$con=mysqli_connect("......,......,......,.......");

// Check connection
if (mysqli_connect_errno())
{
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

$firstName= $_REQUEST['latiTude'];
$lastName = $_REQUEST['longiTude'];// Store values in an array
$returnValue = array($latiTude,$longiTude);


// Send back request in JSON format

// Select all of our stocks from table 'stock_tracker'
$sql ="SELECT m. *


      , ( ACOS( COS( RADIANS( $latiTude) ) 
              * COS( RADIANS( m.latitude ) )
              * COS( RADIANS( m.longitude ) - RADIANS( $longiTude) )
              + SIN( RADIANS($Latitude) )
              * SIN( RADIANS( m.Latitude) )
          )
        * 6371
        ) AS distance_in_km

  FROM TankBilliger m
  HAVING distance_in_km <= 100
 ORDER BY distance_in_km ASC
 LIMIT 100";

// Confirm there are results
if ($result = mysqli_query($con, $sql))
{
    // We have results, create an array to hold the results
        // and an array to hold the data
    $resultArray = array();
    $tempArray = array();



    // Loop through each result
    while($row = $result->fetch_object())
    {
        // Add each result into the results array
        $tempArray = $row;
        array_push($resultArray, $tempArray);
    }

    // Encode the array to JSON and output the results


    echo json_encode($resultArray);


}

// Close connections
mysqli_close($con);
?>

Thank You!


Solution

  • First you need to import CoreLocation:

    import CoreLocation
    // and add  CLLocationManagerDelegate to the class declaration
    

    Then you need to declare the location manager and variables to hold the lat and long values:

    // set these outside of any functions in your class
    let locationManager = CLLocationManager() // create Location Manager object
    var latitude : Double?
    var longitude : Double?
    

    After that is done you want to ask for authorization to use the location of the device. You will need to add the proper items ( NSLocationAlwaysUsageDescription, and/or NSLocationWhenInUseDescription I beleive) to your .plist file to do so.

    // in the function you want to grab the user's location from
    // Ask for Authorisation from the User.
    self.locationManager.requestAlwaysAuthorization() 
    
    // For use in foreground
    // You will need to update your .plist file to request the authorization
    self.locationManager.requestWhenInUseAuthorization()
    
    if CLLocationManager.locationServicesEnabled() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
        locationManager.startUpdatingLocation()
    }
    

    Then you'll need to add the function to retrieve the location

    // Add this function to your program
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let location: CLLocationCoordinate2D = manager.location?.coordinate else { return }
        // set the value of lat and long 
        latitude = location.latitude
        longitude = location.longitude
    
    }
    

    After all of that you will be able to use the latitude and longitude variables whenever you want to. You will also want to tell the locationManager to stop updating the location after you get what you want like, locationManager.stopUpdatingLocation().

    You can create the string like:

    // in the function where you need the postString you can do this
    var postString = ""
    if let lat = latitude, let long = longitude {
        locationManager.stopUpdatingLocation() 
        postString = "latiTude=\(lat)&longiTude=\(long)"
        // do task here now that postString is not empty
    }