I am trying to implement a background fetch for location, it works perfect inside of the iOS simulator, but when I build it on my phone, it does not appear to work. Here is my current code:
import UIKit
import CoreLocation
class CurrentConditonsViewController: UIViewController, CLLocationManagerDelegate {
lazy var locationManager: CLLocationManager! = {
let manager = CLLocationManager()
manager.desiredAccuracy = kCLLocationAccuracyHundredMeters
manager.delegate = self
manager.requestAlwaysAuthorization()
manager.distanceFilter = 2000
if #available(iOS 9.0, *) {
manager.allowsBackgroundLocationUpdates = true
} else {
// Fallback on earlier versions
};
return manager
}()
var seenError : Bool = false
var locationFixAchieved : Bool = false
var locationStatus : NSString = "Not Started"
var userLocation : String!
var userLatitude : Double!
var userLongitude : Double!
var userTemperatureCelsius : Bool!
override func viewDidLoad() {
locationManager.startUpdatingLocation();
refresh()
}
func refresh(){
initLocationManager()
}
func initLocationManager() {
seenError = false
locationFixAchieved = false
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func displayLocationInfo(placemark: CLPlacemark?) {
if let containsPlacemark = placemark {
//stop updating location to save battery life
locationManager.stopUpdatingLocation()
let locality = (containsPlacemark.locality != nil) ? containsPlacemark.locality : ""
let administrativeArea = (containsPlacemark.administrativeArea != nil) ? containsPlacemark.administrativeArea : ""
//println(locality)
//println(postalCode)
//println(administrativeArea)
//println(country)
}
}
// MARK: - CLLocationManagerDelegate
func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation) {
// Add another annotation to the map.
let coords = newLocation.coordinate
userLatitude = coords.latitude
userLongitude = coords.longitude
if UIApplication.sharedApplication().applicationState == .Active {
NSLog("App is in foreground. New location is %#", newLocation)
CLGeocoder().reverseGeocodeLocation(newLocation, completionHandler: {(placemarks, error) -> Void in
if error != nil {
print("Reverse geocoder failed with error" + error!.localizedDescription)
return
}
if placemarks!.count > 0 {
let pm = placemarks![0]
self.displayLocationInfo(pm);
} else {
print("Problem with the data received from geocoder")
}
})
} else {
NSLog("App is backgrounded. New location is %#", newLocation)
let coord = newLocation.coordinate
let lat = coord.latitude.description;
let lng = coord.longitude.description;
let localNotification:UILocalNotification = UILocalNotification()
localNotification.alertAction = "Project RainMan"
localNotification.alertBody = "Location Updated: " + lat + ", " + lng
localNotification.fireDate = NSDate(timeIntervalSinceNow: 8)
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
}
func locationManager(manager: CLLocationManager,
didChangeAuthorizationStatus status: CLAuthorizationStatus) {
var shouldIAllow = false
var locationStatus = ""
switch status {
case CLAuthorizationStatus.Restricted:
locationStatus = "Restricted Access to location"
case CLAuthorizationStatus.Denied:
locationStatus = "User denied access to location"
case CLAuthorizationStatus.NotDetermined:
locationStatus = "Status not determined"
default:
locationStatus = "Allowed to location Access"
shouldIAllow = true
}
NSNotificationCenter.defaultCenter().postNotificationName("LabelHasbeenUpdated", object: nil)
if (shouldIAllow == true) {
NSLog("Location to Allowed")
// Start location services
if #available(iOS 9.0, *) {
locationManager.allowsBackgroundLocationUpdates = true
} else {
// Fallback on earlier versions
};
locationManager.startUpdatingLocation()
} else {
NSLog("Denied access: \(locationStatus)")
}
}
} // END OF CLASS
I do not receive any notification on my actual device, and it is worth noting this morning the code only updates the app when the app is running. I have spent a couple days on this code and am sure it's something simple, any help would be greatly appreciated!
Related
In my main view MainView() I load weather data from WeatherKit asynchronously via .task() which runs whenever the user's location changes:
.task(id: locationManager.currentLocation){
if let location = locationManager.currentLocation{
weather = try await weatherService.weather(for: location)
}
}
However, the user's location may not change for a long period of time or even never and I would like for the weather data to be at least updated once every hour.
How would I update WeatherKit data every hour AND update every single time their location changes.
Obviously I can’t rely on the WeatherKit weather object within the ‘.task(id:)’ to update as that is the object that I’d need to update.
for fetching location after every few mins what approach I have used is
class BackgroundLocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
static let shared = BackgroundLocationManager()
private var locationManager: CLLocationManager!
private var timer: DispatchSourceTimer?
private var counter: Int = 0
#Published var location: LocationModel? = nil
private override init() {
super.init()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.allowsBackgroundLocationUpdates = true
locationManager.requestAlwaysAuthorization()
}
private func startTimer(delay: Int = 15) {
let queue = DispatchQueue(label: "com.example.timer", qos: .background)
timer = DispatchSource.makeTimerSource(queue: queue)
timer?.schedule(deadline: .now(), repeating: .seconds(delay))
timer?.setEventHandler { [weak self] in
self?.locationManager.startUpdatingLocation()
self?.counter = 0
}
timer?.resume()
}
func fetchLocation(interval: Int? = nil) {
if let interval = interval {
startTimer(delay: interval)
} else {
self.locationManager.startUpdatingLocation()
}
}
func stopFetchingLocation() {
timer?.cancel()
timer = nil
}
}
extension BackgroundLocationManager {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
break
case .restricted, .denied:
// do something when permission is denied
case .authorizedAlways, .authorizedWhenInUse, .authorized:
// do something when permission is given
break
#unknown default:
return
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
if let error = error as? CLError, error.code == .denied {
// do something when unable to fetch location
return
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.counter += 1
locationManager.stopUpdatingLocation()
let currentLocation = locations.last?.coordinate
let long = String(currentLocation?.longitude ?? 0)
let lat = String(currentLocation?.latitude ?? 0)
let verticalAcc = String(locations.last?.verticalAccuracy ?? 0)
let horizontalAcc = String(locations.last?.horizontalAccuracy ?? 0)
let altitude = String(locations.last?.altitude ?? 0)
let location = LocationModel(longitude: long, latitude: lat,
verticalAccuracy: verticalAcc,
horizontalAccuracy: horizontalAcc, alitude: altitude)
if counter <= 1 {
self.location = location
}
}
}
To use it according to my need
struct MainView: View {
#StateObject var vm = MainViewModel()
init() {
BackgroundLocationManager.shared.fetchLocation() // when needed once
BackgroundLocationManager.shared.fetchLocation(interval: 15) // needed after how many seconds
}
var body: some View {
ZStack {
MyCustomeView()
}
.onReceive(BackgroundLocationManager.shared.$location) { location in
vm.doSomething(location: location)
}
}
}
Use a timer inside your view.
struct WeatherView: View {
let weatherService: WeatherService
let location: Location
#State var weather: Weather?
let timer = Timer.publish(every: 3600, on: .main, in: .common).autoconnect()
var body: some View {
Text(weather.description)
.onReceive(timer) { _ in
fetch()
}
}
func fetch() {
Task {
weather = try await weatherService.weather(for: location)
}
}
}
I'm a beginner, have been working on a weather project, trying to get the lat and long from LocationManager in WeatherViewModel class and pass it the API so i can get the user location based data. but can't get the lattitude and longitude in the WeatherViewModel. the simulator shows a random temperature and city as globe.(SwiftUI and Xcode 11.6)
here's the LocationManager class
import Foundation
import CoreLocation
import Combine
class LocationManager: NSObject, CLLocationManagerDelegate, ObservableObject {
private let manager: CLLocationManager
#Published var lastKnownLocation: CLLocation?
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .denied{
print("denied")
}
else{
print("athorized")
manager.requestLocation()
}
}
func start() {
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
}
init(manager: CLLocationManager = CLLocationManager()) {
self.manager = manager
super.init()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error.localizedDescription)
}
func startUpdating() {
self.manager.delegate = self
self.manager.requestWhenInUseAuthorization()
self.manager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
lastKnownLocation = locations.last
print("\((lastKnownLocation?.coordinate.latitude)!)")
print("\((lastKnownLocation?.coordinate.longitude)!)")
}
}
Here's the WeatherViewModel class
import SwiftUI
import Combine
import CoreLocation
class WeatherViewModel: ObservableObject {
#ObservedObject var location = LocationManager()
let client = OpenWeatherAPI()
var stateView: StateView = StateView.loading{
willSet{
objectWillChange.send() }
}
var currentWeather = CurrentWeather.emptyInit(){
willSet{
objectWillChange.send()
}
}
var todayWeather = ForecastWeather.emptyInit(){
willSet{
objectWillChange.send()
}
}
var hourlyWeathers: [ForecastWeather] = [] {
willSet{
objectWillChange.send()
}
}
var dailyWeathers: [ForecastWeather] = [] {
willSet{
objectWillChange.send()
}
}
var currentDescription = ""{
willSet{
objectWillChange.send()
}
}
private var stateCurrentWeather = StateView.loading
private var stateForecastWeather = StateView.loading
var latitude: String{
return "\(location.lastKnownLocation?.coordinate.latitude ?? 0.0)"
}
var longitude: String{
return "\(location.lastKnownLocation?.coordinate.longitude ?? 0.0)"
}
func printLatlon(){
print("WeatherViewModel")
print(latitude )
print(longitude )
}
init (){
getData()
printLatlon()
}
func retry(){
stateView = .loading
stateCurrentWeather = .loading
stateForecastWeather = .loading
}
private func getData() {
client.getCurrentWeather(at: latitude, at: longitude) { [weak self] currentWeather, error in
guard let ws = self else { return }
if let currentWeather = currentWeather {
ws.currentWeather = currentWeather
ws.todayWeather = currentWeather.getForecastWeather()
ws.currentDescription = currentWeather.description()
ws.stateCurrentWeather = .success
} else {
ws.stateCurrentWeather = .failed
}
ws.updateStateView()
}
client.getForecastWeather(at: latitude, at: longitude) { [weak self] forecastWeatherResponse, error in
guard let ws = self else { return }
if let forecastWeatherResponse = forecastWeatherResponse {
ws.hourlyWeathers = forecastWeatherResponse.list
ws.dailyWeathers = forecastWeatherResponse.dailyList
ws.stateForecastWeather = .success
} else {
ws.stateForecastWeather = .failed
}
ws.updateStateView()
}
}
private func updateStateView() {
if stateCurrentWeather == .success, stateForecastWeather == .success {
stateView = .success
}
if stateCurrentWeather == .failed, stateForecastWeather == .failed {
stateView = .failed
}
}
}
I'm passing the data in this
private func getData() {
client.getCurrentWeather(at: latitude, at: longitude) { }
client.getForecastWeather(at: latitude, at: longitude) { }
}
if i use this
var latitude: String{
return "\(location.lastKnownLocation?.coordinate.latitude ?? 0.0)"
}
var longitude: String{
return "\(location.lastKnownLocation?.coordinate.longitude ?? 0.0)"
}
Then i get this output in the simulator
the console shows this
the console shows that it didnt get the lat and lon
but if i give a string of lat and lon like this
var latitude = "36.778259"
var longitude = "-119.417931"
Then i get expected output in the simulator
console output
because I pass the string location and thats why showing my string values
Good afternoon Community,
I am having trouble plotting the Poly Line within my application, I already tried calling it in the func method locationManager (_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {}
but nothing is generated, just as I would like each step that I take the polyline to be marked and not at the end of my journey. I leave my code below:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate,MKMapViewDelegate {
#IBOutlet var Maps: MKMapView!
var locationManager = CLLocationManager()
var coordenadas = CLLocationCoordinate2D()
var startPoint = MKDirections.Request()
var ArrayDeCoordenadas: [CLLocationCoordinate2D] = []
var tap: Int = 0
func getDirections(){
let request = MKDirections.Request()
request.source = MKMapItem.forCurrentLocation()
request.requestsAlternateRoutes = true
let directions = MKDirections(request: request)
directions.calculate { (response, error) in
if error != nil {
print("Error \(error)")
} else {
//self.dispLayRout(response)
var overlays = self.Maps.overlays
self.Maps.removeOverlays(overlays)
for route in response!.routes as! [MKRoute] {
self.Maps.addOverlay(route.polyline,
level: MKOverlayLevel.aboveRoads)
var instructionNumber = 0
for next in route.steps {
instructionNumber += 1
print(next.instructions)
}
}
}
}
}
func alertLocation(title: String, Message:String){
let alert = UIAlertController(title: title, message: Message, preferredStyle: .alert)
let actionAlert = UIAlertAction(title: "Acept", style: .default, handler: nil)
alert.addAction(actionAlert)
self.present(alert, animated: true,completion: nil)
}
func LocalizationInit(){
let autorization = CLLocationManager.authorizationStatus()
switch autorization{
case .notDetermined, .restricted:
locationManager.requestLocation()
break;
case .restricted, .denied:
alertLocation(title: "We have a Error", Message: "You have your localization restricted.")
case .authorizedAlways,.authorizedWhenInUse:
break;
default:
break;
}
}
#IBAction func Share(_ sender: UIButton) {
let compartir = UIActivityViewController(activityItems: ["Share baby" as Any],
applicationActivities: nil)
compartir.popoverPresentationController?.sourceView = self.view
present(compartir,animated: true,completion: nil)
}
#IBAction func recordButton(_ sender: UIButton) {
if sender.isSelected != true {
tap += 1
print("tap -> :\(tap)")
if tap == 1{
let annotation = MKPointAnnotation()
annotation.title = "My route"
annotation.subtitle = "I Hoppe"
annotation.coordinate = coordenadas
let annotation2 = MKPointAnnotation()
annotation2.title = "My ride"
annotation2.subtitle = "I Hoppe"
annotation.coordinate = locationManager.location?.coordinate as! CLLocationCoordinate2D
self.Maps.addAnnotation(annotation)
}else if tap == 2 {
tap = 0
locationManager.stopMonitoringSignificantLocationChanges()
}
}
}
#IBAction func mapOptions(_ sender: UISegmentedControl) {
switch sender.selectedSegmentIndex{
case 0:
Maps.mapType = MKMapType.standard
break;
case 1:
Maps.mapType = MKMapType.satellite
break;
case 2:
Maps.mapType = MKMapType.hybrid
break;
default:
break;
}
}
override func viewDidLoad() {
super.viewDidLoad()
LocalizationInit()
let polyLineMake = MKPolyline(coordinates: ArrayDeCoordenadas, count: ArrayDeCoordenadas.count)
self.Maps.addOverlay(polyLineMake, level: .aboveRoads)
Maps.showsUserLocation = true
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
DispatchQueue.main.async {
self.locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
coordenadas = manager.location?.coordinate as! CLLocationCoordinate2D
ArrayDeCoordenadas.append(locations.last!.coordinate)
print("Array de coordenadas : -> \(ArrayDeCoordenadas)")
let region = MKCoordinateRegion(center: locations.last!.coordinate, latitudinalMeters: 200,
longitudinalMeters: 200)
self.Maps.setRegion(region, animated: false)
let distancia = locations.distance(from: Int(manager.location!.coordinate.latitude), to:
Int((locations.last?.coordinate.latitude)!))
print("distancia \(distancia)")
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation{
return nil
}
let pin = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "My personal pin")
pin.pinTintColor = UIColor.green
return pin
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKPolyline{
let polyline = overlay
let polyLineRender = MKPolylineRenderer(overlay: polyline)
print(" se esta generando \(polyline)")
polyLineRender.strokeColor = UIColor.red
polyLineRender.lineWidth = 6.0
return polyLineRender
}
print(" no se esta generando")
return MKPolylineRenderer()
} }
I have read the documentation a bit and apparently my code is fine, if someone could help me, it would be of great help! Like someone if you have any method that can help me to know when I did and how many steps I walked since I did not see that CLLocation had an option for that type of information.
the problem is not set Map delegate object, also I made some changes to add polyline overlay. Simple but it is working. Good luck.
Maps.delegate = self
Code file:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate,MKMapViewDelegate {
#IBOutlet var Maps: MKMapView!
var locationManager = CLLocationManager()
var coordenadas = CLLocationCoordinate2D()
var startPoint = MKDirections.Request()
var ArrayDeCoordenadas: [CLLocationCoordinate2D] = []
var tap: Int = 0
var journeyPolyline: MKPolyline?
func getDirections(){
let request = MKDirections.Request()
request.source = MKMapItem.forCurrentLocation()
request.requestsAlternateRoutes = true
let directions = MKDirections(request: request)
directions.calculate { (response, error) in
if error != nil {
print("Error \(error)")
} else {
//self.dispLayRout(response)
var overlays = self.Maps.overlays
self.Maps.removeOverlays(overlays)
for route in response!.routes as! [MKRoute] {
self.Maps.addOverlay(route.polyline,
level: MKOverlayLevel.aboveRoads)
var instructionNumber = 0
for next in route.steps {
instructionNumber += 1
print(next.instructions)
}
}
}
}
}
func alertLocation(title: String, Message:String){
let alert = UIAlertController(title: title, message: Message, preferredStyle: .alert)
let actionAlert = UIAlertAction(title: "Acept", style: .default, handler: nil)
alert.addAction(actionAlert)
self.present(alert, animated: true,completion: nil)
}
func LocalizationInit(){
let autorization = CLLocationManager.authorizationStatus()
switch autorization{
case .notDetermined, .restricted:
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
break;
case .restricted, .denied:
alertLocation(title: "We have a Error", Message: "You have your localization restricted.")
case .authorizedAlways,.authorizedWhenInUse:
locationManager.startUpdatingLocation()
break;
default:
break;
}
}
#IBAction func Share(_ sender: UIButton) {
let compartir = UIActivityViewController(activityItems: ["Share baby" as Any],
applicationActivities: nil)
compartir.popoverPresentationController?.sourceView = self.view
present(compartir,animated: true,completion: nil)
}
#IBAction func recordButton(_ sender: UIButton) {
if sender.isSelected != true {
tap += 1
print("tap -> :\(tap)")
if tap == 1{
let annotation = MKPointAnnotation()
annotation.title = "My route"
annotation.subtitle = "I Hoppe"
annotation.coordinate = coordenadas
let annotation2 = MKPointAnnotation()
annotation2.title = "My ride"
annotation2.subtitle = "I Hoppe"
annotation.coordinate = locationManager.location?.coordinate as! CLLocationCoordinate2D
self.Maps.addAnnotation(annotation)
}else if tap == 2 {
tap = 0
locationManager.stopMonitoringSignificantLocationChanges()
}
}
}
#IBAction func mapOptions(_ sender: UISegmentedControl) {
switch sender.selectedSegmentIndex{
case 0:
Maps.mapType = MKMapType.standard
break;
case 1:
Maps.mapType = MKMapType.satellite
break;
case 2:
Maps.mapType = MKMapType.hybrid
break;
default:
break;
}
}
override func viewDidLoad() {
super.viewDidLoad()
LocalizationInit()
// let polyLineMake = MKPolyline(coordinates: ArrayDeCoordenadas, count: ArrayDeCoordenadas.count)
// self.Maps.addOverlay(polyLineMake, level: .aboveRoads)
Maps.showsUserLocation = true
Maps.delegate = self
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
coordenadas = locations.first!.coordinate as! CLLocationCoordinate2D
ArrayDeCoordenadas.append(locations.last!.coordinate)
print("Array de coordenadas : -> \(ArrayDeCoordenadas)")
let region = MKCoordinateRegion(center: locations.last!.coordinate, latitudinalMeters: 200,
longitudinalMeters: 200)
self.Maps.setRegion(region, animated: false)
let distancia = locations.distance(from: Int(manager.location!.coordinate.latitude), to:
Int((locations.last?.coordinate.latitude)!))
print("distancia \(distancia)")
let polyline = MKPolyline(coordinates: ArrayDeCoordenadas, count: ArrayDeCoordenadas.count)
Maps.addOverlay(polyline)
//remove old polyline
if let oldPolyline = journeyPolyline {
Maps.removeOverlay(oldPolyline)
}
journeyPolyline = polyline
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation{
return nil
}
let pin = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "My personal pin")
pin.pinTintColor = UIColor.green
return pin
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKPolyline{
let polyline = overlay
let polyLineRender = MKPolylineRenderer(overlay: polyline)
print(" se esta generando \(polyline)")
polyLineRender.strokeColor = UIColor.red
polyLineRender.lineWidth = 6.0
return polyLineRender
}
print(" no se esta generando")
return MKPolylineRenderer()
}
}
I am using swift and I am working on a project, where I have to show a draggable map with changing location. and below the map I have subview and it have a button, on button click the subview will appear and on same button click I will disappear.
But the problem is sometime its working fine some time this view is go down and not coming on screen. and specially when I use button title change code.
class LocationMAP: UIViewController,CLLocationManagerDelegate,MKMapViewDelegate {
#IBOutlet weak var locationLabel: UILabel!
#IBOutlet weak var selectAnyoneButton: UIButton!
#IBOutlet weak var selectingView: UIView!
var changingText:Bool = false
#IBOutlet weak var map: MKMapView!
var locationManger = CLLocationManager()
let geoCoder = CLGeocoder()
var myLocation: CLLocation!
override func viewDidLoad() {
super.viewDidLoad()
self.locationManger.delegate = self
locationManger.desiredAccuracy = kCLLocationAccuracyBest
locationManger.requestWhenInUseAuthorization()
locationManger.startUpdatingLocation()
if( CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedWhenInUse ||
CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedAlways){
}
self.map.showsUserLocation = true
self.map.delegate = self
self.map.setUserTrackingMode(MKUserTrackingMode.Follow, animated: true)
let location = CLLocationCoordinate2DMake(20.59368, 78.96288)
let span = MKCoordinateSpanMake(0.2, 0.2)
_ = MKCoordinateRegionMake(location, span)
let annotation = MKPointAnnotation()
annotation.coordinate = (location)
selectAnyoneButton.setTitle("Submit", forState: .Normal)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//MARK:- MapView Delegates
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case .Authorized, .AuthorizedWhenInUse:
manager.startUpdatingLocation()
self.map.showsUserLocation = true
default: break
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.myLocation = locations.last! as CLLocation
let userLocation:CLLocation = locations.last!
let long = userLocation.coordinate.longitude
let lat = userLocation.coordinate.latitude
print(long , lat)
// locationManger.stopUpdatingLocation()
self.map.centerCoordinate = myLocation.coordinate
let reg = MKCoordinateRegionMakeWithDistance(myLocation.coordinate, 1500, 1500)
self.map.setRegion(reg, animated: true)
geoCode(myLocation)
}
func geoCode(location : CLLocation!){
geoCoder.cancelGeocode()
self.locationManger.stopUpdatingLocation()
geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemark, error) -> Void in
guard let placeMarks = placemark as [CLPlacemark]! else {
return
}
let loc: CLPlacemark = placeMarks[0]
let addressDict : [NSString:NSObject] = loc.addressDictionary as! [NSString: NSObject]
let addrList = addressDict["FormattedAddressLines"] as! [String]
let address = (addrList.joinWithSeparator(", "))
self.locationLabel.text = address
let lat = loc.location!.coordinate.latitude
let long = loc.location!.coordinate.longitude
print(lat , long)
SharedPreferenceManager.sharedInstance.userLatitude = lat
SharedPreferenceManager.sharedInstance.userLongitude = long
SharedPreferenceManager.sharedInstance.userAddress = address
})
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print(error.localizedDescription)
}
func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
let location = CLLocation(latitude: mapView.centerCoordinate.latitude, longitude: mapView.centerCoordinate.longitude)
geoCode(location)
self.map.removeAnnotations(mapView.annotations)
let annotation = MKPointAnnotation()
annotation.coordinate = map.centerCoordinate
annotation.title = "title"
annotation.subtitle = "subtitle"
self.map.addAnnotation(annotation)
}
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = MKPinAnnotationView()
if #available(iOS 9.0, *) {
annotationView.pinTintColor = UIColor.blueColor()
annotationView.center = CGPointMake(160, 200)
} else {
}
return annotationView
}
func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, didChangeDragState
newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
if (newState == MKAnnotationViewDragState.Starting) {
view.dragState = MKAnnotationViewDragState.Dragging
}
else if (newState == MKAnnotationViewDragState.Ending || newState == MKAnnotationViewDragState.Canceling){
view.dragState = MKAnnotationViewDragState.None
}
}
//MARK:- Button Action Methods
#IBOutlet weak var downBtn: UILabel!
#IBAction func chooseButtonAction(sender: AnyObject) {
if (changingText == false) {
let newCenter:CGPoint = CGPointMake(selectingView.center.x, selectingView.center.y - 230)
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationDuration(0.55)
selectingView.center = newCenter
UIView.commitAnimations()
selectAnyoneButton.setTitle("Select a service", forState: .Normal)
changingText = true
} else {
let newCenter:CGPoint = CGPointMake(selectingView.center.x, selectingView.center.y + 230)
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationDuration(0.55)
selectingView.center = newCenter
UIView.commitAnimations()
selectAnyoneButton.setTitle("Submit", forState: .Normal)
changingText = false
}
}
in button's action methods, add:
super.bringSubviewToFront(UIView)
towards the end.
I am assuming your view in question is a direct child of superview.
I'm making an application with MapKit. Here's an image of how it looks:
And I want to change (Current location) title of the symbol current location from that pin.
Here's code:
import UIKit
import CoreLocation
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var theMap: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad()
{
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
let location = self.locationManager.location
var latitude: Double = location.coordinate.latitude
var longitude: Double = location.coordinate.longitude
println("GPS Súradnice :: \(latitude), \(longitude)")
theMap.delegate = self
theMap.mapType = MKMapType.Standard
theMap.showsUserLocation = true
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
//--- Find Address of Current Location ---//
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
{
//--- CLGeocode to get address of current location ---//
CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: {(placemarks, error)->Void in
if (error != nil)
{
println("Reverse geocoder failed with error" + error.localizedDescription)
return
}
if placemarks.count > 0
{
let pm = placemarks[0] as! CLPlacemark
self.displayLocationInfo(pm)
}
else
{
println("Problem with the data received from geocoder")
}
})
}
func displayLocationInfo(placemark: CLPlacemark?)
{
if let Placemark = placemark
{
//Stop updating kvôli vydrži baterke
locationManager.stopUpdatingLocation()
let adresa = (Placemark.thoroughfare != nil) ? Placemark.thoroughfare : "Ulica: "
let cislo = (Placemark.subThoroughfare != nil) ? Placemark.subThoroughfare : "Číslo ulice:"
let mesto = (Placemark.locality != nil) ? Placemark.locality : "Mesto: "
let stat = (Placemark.country != nil) ? Placemark.country : "Štát: "
var coordinates:CLLocationCoordinate2D = placemark!.location.coordinate
var pointAnnotation:MKPointAnnotation = MKPointAnnotation()
pointAnnotation.coordinate = coordinates
pointAnnotation.title = "\(adresa) \(cislo)"
pointAnnotation.subtitle = "\(adresa) \(cislo), \(mesto), \(stat)"
self.theMap.addAnnotation(pointAnnotation)
self.theMap.centerCoordinate = coordinates
self.theMap.selectAnnotation(pointAnnotation, animated: true)
println(mesto)
println(adresa)
println(cislo)
println(stat)
}
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!)
{
println("Chyba pri aktualizovaní lokácie " + error.localizedDescription)
}
}
If I get it right. You want to change blue dot. Try this.
let theLocation: MKUserLocation = theMap.userLocation
theLocation.title = "I'm here!"
//swift 3
let annotation = MKPointAnnotation()
annotation.coordinate = center
annotation.title = "title"
Annotation.subtitle = “Subtitle”
mapView.addAnnotation(annotation)
I think,http://swift3devlopment.blogspot.in/ here you get more details of MapKit
For Show blue circle mapkit in swift 2.0:
override func viewDidLoad() {
super.viewDidLoad()
//this line show blue circle location user
Mapa.showsUserLocation = true
locationManager.requestWhenInUseAuthorization();
if CLLocationManager.locationServicesEnabled(){
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
else{
print("Location service disabled");
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
let region = MKCoordinateRegion(center: locValue, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
print("locations = \(locValue.latitude) \(locValue.longitude)")
Mapa.setRegion(region, animated: true)
}