I try to make an application in Swift 2 that displays all the GPS informations.
I can recover latitute, longitue, horizontalAccuracy, verticalAccuracy, altitude, distance and cap but I am unable to recover speed, whereas I arrived in Objective-C :-(
Thanks for your help
Below is my code:
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
var running = false
var pause = false
var locationManager: CLLocationManager = CLLocationManager()
var startLocation: CLLocation!
#IBOutlet weak var latitudeLabel: UILabel!
#IBOutlet weak var longitudeLabel: UILabel!
#IBOutlet weak var horizontalAccuracyLabel: UILabel!
#IBOutlet weak var verticalAccuracyLabel: UILabel!
#IBOutlet weak var capLabel: UILabel!
#IBOutlet weak var altitudeLabel: UILabel!
#IBOutlet weak var partielLabel: UILabel!
#IBOutlet weak var distanceLabel: UILabel!
#IBOutlet weak var vitesseLabel: UILabel!
#IBOutlet weak var moyenneLabel: UILabel!
#IBOutlet weak var timerLabel: UILabel!
#IBOutlet weak var totalDistanceLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
locationManager.startUpdatingHeading()
startLocation = nil
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func startDistance(sender: AnyObject) {
startLocation = nil
running = true
}
#IBAction func stopDistance(sender: AnyObject) {
running = false
}
#IBAction func resetDistance(sender: AnyObject) {
startLocation = nil
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let latestLocation: AnyObject = locations[locations.count - 1]
latitudeLabel.text = String(format: "%.4f",latestLocation.coordinate.latitude)
longitudeLabel.text = String(format: "%.4f",latestLocation.coordinate.longitude)
horizontalAccuracyLabel.text = String(format: "%.4f",latestLocation.horizontalAccuracy)
verticalAccuracyLabel.text = String(format: "%.4f",latestLocation.verticalAccuracy)
altitudeLabel.text = String(format: "%.4f",latestLocation.altitude)
if running == true {
if startLocation == nil {
startLocation = latestLocation as! CLLocation
}
let distanceBetween: CLLocationDistance =
latestLocation.distanceFromLocation(startLocation)
distanceLabel.text = String(format: "%.2f", distanceBetween)
}
}
func locationManager(manager: CLLocationManager, didUpdateHeading newHeading: CLHeading)
{
capLabel.text = String(format: "%.4f",newHeading.magneticHeading)
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
}
}
I tested this code :
vitesseLabel.text = String(CLLocationSpeed())
but speed remains at 0.00
I finally found, so here's the code:
var speed: CLLocationSpeed = CLLocationSpeed()
speed = locationManager.location!.speed
vitesseLabel.text = String(format: "%.0f km/h", speed * 3.6)
The reason you don't know the speed is that you have not written any code where you ask the CLLocation for its speed.
Related
I have prepared the app and I am stuck at adding the code to turn the ringer silent. When I press the button a notification is sent but I want to turn the ringer volume to 0. This is my code. ALSO I AM CONFUSED WHERE TO PUT THE CODE.
import UIKit
import MapKit
protocol AddViewControllerDelegate {
func addViewController(controller: AddViewController, didAddCoordinate coordinate: CLLocationCoordinate2D, radius: Double, identifier: String, note: String, eventType: EventType)
}
class AddViewController: UITableViewController {
#IBOutlet var addButton: UIBarButtonItem!
#IBOutlet var zoomButton: UIBarButtonItem!
#IBOutlet weak var eventTypeSegmentedControl: UISegmentedControl!
#IBOutlet weak var radiusTextField: UITextField!
#IBOutlet weak var noteTextField: UITextField!
#IBOutlet weak var mapView: MKMapView!
var delegate: AddViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItems = [addButton, zoomButton]
addButton.isEnabled = false
}
#IBAction func textFieldEditingChanged(sender: UITextField) {
addButton.isEnabled = !radiusTextField.text!.isEmpty && !noteTextField.text!.isEmpty
}
#IBAction func onCancel(sender: AnyObject) {
dismiss(animated: true, completion: nil)
}
#IBAction private func onAdd(sender: AnyObject) {
let coordinate = mapView.centerCoordinate
let radius = Double(radiusTextField.text!) ?? 0
let identifier = NSUUID().uuidString
let note = noteTextField.text
let eventType: EventType = (eventTypeSegmentedControl.selectedSegmentIndex == 0) ? .onEntry : .onExit
delegate?.addViewController(controller: self, didAddCoordinate: coordinate, radius: radius, identifier: identifier, note: note!, eventType: eventType)
}
#IBAction private func onZoomToCurrentLocation(sender: AnyObject) {
mapView.zoomToUserLocation()
}
}
I have many different buttons like UIStepper and DatePicker and a MapView. Can anyone help me get my whole view controller and the button working. I have been getting an error about SIGABRT. It say's "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Field_Service_Report.AddController hoursStepper:]: unrecognized selector sent to instance 0x7fb5d7c8d010'"
This is my View Controller code :
import UIKit
import MapKit
import CoreLocation
class AddController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var hoursStepperResult: UILabel!
#IBOutlet weak var hoursStepper: UIStepper!
#IBOutlet weak var minutesStepperResult: UILabel!
#IBOutlet weak var minutesStepper: UIStepper!
#IBOutlet weak var currentLocationLabel: UILabel!
#IBOutlet weak var dateOfReport: UIDatePicker!
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Start Map Contents
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.mapView.showsUserLocation = true
// End Map Contents
}
// Start Stepper Contents
#IBAction func hoursStepperAction(_ sender: UIStepper) {
hoursStepperResult.text = String(Int(sender.value))
}
#IBAction func minutesStepperAction(_ sender: UIStepper) {
minutesStepperResult.text = String(Int(sender.value))
}
// End Stepper Contents
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// Here is the new code its giving me 3 erroe because im trying to get the text and numbers from another ViewController to print out in this VC.
#IBAction func doneACButton(_ sender: AnyObject) {
let newVC = storyboard?.instantiateViewController(withIdentifier: "ResultController") as! ResultController
newVC.intPassed = hoursIntProvided
newVC.intPassed = minutesIntProvided
newVC.stringPassed = resultedHours.text!
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1))
self.mapView.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Errors: " + error.localizedDescription)
}
// MARK: - Navigation
}
Notice the colon right here in the method signature:
-[Field_Service_Report.AddController hoursStepper:]
^
This is the signature of a method that takes a parameter, not the signature of an accessor. Are you sure you didn't misspell a selector name somewhere or leave something accidentally connected in IB that should have been removed? (Perhaps if you renamed a method and forgot to redo the action connection?)
So I have a map view(mapkit based) and a slider in my storyboard. As the user slides, map zooms in or out based on their action. How do I implement that? I think that might have something to do with longitudeDelta and latitudeDelta.
Please help me.
import UIKit
import MapKit
import CoreLocation
class ConfigureViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapkitView: MKMapView!
#IBOutlet weak var travelRadius: UILabel!
#IBAction func button(sender: AnyObject) {
}
#IBAction func sliderChanged(sender: AnyObject) {
let sliderValue = lrintf(sender.value)
travelRadius.text = "\(sliderValue) mi."
let delta = Double(self.sliderChanged(sender.value))
var currentRegion = self.mapkitView.region
currentRegion.span = MKCoordinateSpan(latitudeDelta: delta, longitudeDelta: delta)
self.mapkitView.region = currentRegion
}
let locationManager = CLLocationManager()
#IBOutlet weak var mapKitView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.mapKitView.showsUserLocation = true
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 1.5,
longitudeDelta: 1.5))
self.mapKitView.setRegion(region, animated: false)
self.locationManager.stopUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
{
print ("Errors:" + error.localizedDescription)
}
}
Screenshot of my storyboard
You set the zoom via the region property of the mapView. It defines both the center point of the map and the span (i.e. zoom level)
Edit
Do yourself a favor and define a separate IBOutlet for the slider. It turns out that your slider is measured in miles, but the span is measured in degrees latitude and longitude. How long 1 degree of latitude/longitude is in terms of miles vary depend on your location on Earth. Wikipedia has some discussion on latitude and longitude. Assuming you are on the equator, the conversion is 69 miles per degree of both.
(Remember to connect the outlets)
class ViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var slider: UISlider!
#IBOutlet weak var travelRadius: UILabel!
#IBOutlet weak var currentLocationLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
sliderChanged(self) // Set the correct zoom according to the slider initial value
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func sliderChanged(sender: AnyObject) {
let miles = Double(self.slider.value)
let delta = miles / 69.0
var currentRegion = self.mapView.region
currentRegion.span = MKCoordinateSpan(latitudeDelta: delta, longitudeDelta: delta)
self.mapView.region = currentRegion
travelRadius.text = "\(Int(round(miles))) miles"
let (lat, long) = (currentRegion.center.latitude, currentRegion.center.longitude)
currentLocationLabel.text = "Current location: \(lat), \(long))"
}
}
I am currently not able to clear the overlay.I would like to clear my overlay that was traveled and then start again. I have looked at a ton of different lines of code and can't seem to figure it out. Could you please help me out on this? I am new to Swift so please play nice :)
import UIKit
import CoreLocation
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var theMap: MKMapView!
#IBOutlet weak var theLabel: UILabel!
#IBOutlet weak var startTracking: UIButton!
#IBOutlet weak var stopTracking: UIButton!
#IBOutlet weak var clearTrack: UIButton!
var polyline:MKPolyline = MKPolyline()
var manager:CLLocationManager!
var myLocations: [CLLocation] = []
func clearTrack(sender: UIButton){
//label.text = String(myLocations.count)
//stopTracking()
theMap.removeOverlay (polyline)
}
func stopTracking(sender: UIButton) {
manager.stopUpdatingLocation()
myLocations = []
println("Stop making a line")
}
func startTracking(sender: UIButton) {
manager.startUpdatingLocation()
myLocations = []
println("Making a line")
}
override func viewDidLoad() {
super.viewDidLoad()
//Setup our Location Manager
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()
//Setup our Map View
theMap.delegate = self
theMap.mapType = MKMapType.Hybrid
theMap.showsUserLocation = true
}
func locationManager(manager:CLLocationManager, didUpdateLocations locations:[AnyObject]) {
theLabel.text = "\(locations[0])"
myLocations.append(locations[0] as CLLocation)
let spanX = 0.002
let spanY = 0.002
var newRegion = MKCoordinateRegion(center: theMap.userLocation.coordinate, span: MKCoordinateSpanMake(spanX, spanY))
theMap.setRegion(newRegion, animated: true)
if (myLocations.count > 1){
var sourceIndex = myLocations.count - 1
var destinationIndex = myLocations.count - 2
let c1 = myLocations[sourceIndex].coordinate
let c2 = myLocations[destinationIndex].coordinate
var a = [c1, c2]
var polyline = MKPolyline(coordinates: &a, count: a.count)
theMap.addOverlay(polyline)
}
}
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
if overlay is MKPolyline {
var polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.yellowColor()
polylineRenderer.lineWidth = 3
return polylineRenderer
}
return nil
}
}
Have you tried using:
func clearTrack(sender: UIButton){
theMap.removeOverlays(theMap.overlays)
}
I've tried following simple CoreLocation examples using Swift, but I'm unable to get things working. I've extracted most of the code out, so it's just barebones in order to focus the question, and I'm hoping the answer jumps out quickly to someone.
import UIKit
import CoreLocation
class ViewController: UIViewController,CLLocationManagerDelegate {
#IBOutlet weak var txtLatitude: UITextField!
#IBOutlet weak var txtLongitude: UITextField!
#IBOutlet weak var cmdLocateMe: UIButton!
#IBOutlet weak var slider: UISlider!
#IBOutlet weak var txtSlider: UITextField!
#IBOutlet weak var power: UISwitch!
var locationManager: CLLocationManager!
override func viewDidLoad() {
locationManager = CLLocationManager();
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation();
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func valueChanged(sender: UISlider) {
if power.on{
var val = "\(slider.value)";
txtSlider.text = val;
}
}
#IBAction func cmdLocateMeClicked(sender: UIButton) {
}
//Deprecated
#IBAction func cmdLocateMePressed(sender: AnyObject) {
}
//CLLocationManagerDelegate
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var location:CLLocation = locations[locations.count-1] as CLLocation
println("locations = \(locations)")
txtLatitude.text = "\(location.coordinate.latitude)";
txtLongitude.text = "\(location.coordinate.longitude)";
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println(error)
txtLatitude.text = "Can't get your location!"
}
}
Figured it out -- I had to give permissions to my app to receive Location Information on the iOS Simulator (Settings -> Privacy -> Location). Once I did that, things worked perfectly.