Problem with reverse geocoder and passing data between view controllers Xcode - swift

I have a mapView in one view controller with an MKPointAnnotation. I've applied reverse Geocoder to get the street name from the coordinates and I'm trying to take that street name onto another view controller and place it into a label. But that label from the second view controller always shows the coordinates 0.0, instead of the street name.
func configureAddressNameTry() {
let vc = ViewController()
let lat = vc.annotation.coordinate.latitude
let long = vc.annotation.coordinate.longitude
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(CLLocation(latitude: lat, longitude: long)) { (placemarks, error) in
if let places = placemarks {
for place in places {
// This is the line that gives me the coordinates 0.0 (North Atlantic Ocean)
self.addressNameTry.text = place.name
}
}
}
I think I have all the necessary code for the user location and the information in the info.plist, so I don't know what I'm missing. I'm new to programming and I hope I'm not making a basic error.
Thank you for your replies :)

Related

Mapbox MGLAnnotations not rendering on MapView for Mapbox iOS

I have been testing out using MapBox for my SwiftUI application but I've run into issues where my annotations are not appearing on my MapView even though they appear to have been added. My code for my updateAnnotations command, which is called on updateUIView is:
private func updateAnnotations() {
if let currentAnnotations = mapView.annotations {
mapView.removeAnnotations(currentAnnotations)
}
for marker in devices.positions {
let annotation = MGLPointAnnotation(title: marker.name, coordinate: marker.coordinate)
mapView.addAnnotation(annotation)
print("ADDED \(annotation)")
print(mapView.annotations)
}
}
devices is a #ObservedObject containing a positions array of points with a title and coordinate to plot. My output from this code is:
ADDED <MGLPointAnnotation: 0x285abc9f0; title = "Test"; subtitle = (null); coordinate = -36.892800, 174.625000>
Optional([<MGLPointAnnotation: 0x2866b7c60; title = "Test"; subtitle = (null); coordinate = -36.892800, 174.625000>])
This doesn't make sense to me - the output suggests that the annotation has been created but it doesn't show up on the map. Any help would be greatly appreciated.
You need to pass in the MapView when using SwiftUI - e.g. change updateAnnotations() to updateAnnotations(_ mapView: MGLMapView)

Unable to remove previous polyline from last search

I have a slight problem, I am unable to remove the previous polyline created from the previous search.
I have looked at google documentation​ but i am unable to find the right answers.
let routes = json["routes"].arrayValue
for route in routes
{
let routeOverviewPolyline = route["overview_polyline"].dictionary
print("routesOVER:",routeOverviewPolyline)
let points = routeOverviewPolyline?["points"]?.stringValue
let path = GMSPath.init(fromEncodedPath: points!)
let polyline = GMSPolyline(path: path)
if polyline != nil {
print(polyline)
polyline.strokeColor = .black
polyline.strokeWidth = 10.0
polyline.map = self.googleMaps
}
}
}
catch let error as NSError {
print(error)
}
in the google maps, 2 polylines are shown. 1 from the previous search and another from the current search
Google Maps Image
You can clear the mapView before drawing to new polyline on the map.
self.googleMaps.clear()
But above code will clear pins on the map as well. your have to redraw your pins on the map as well

How to make a custom iconView in google maps with swift?

I need to do something like this
a marker with a static label in google maps sdk for iOS
If there is gonna be a lot of markers, I do not recommend using iconView because it makes UI so laggy, but here it goes:
Create a UIView file as "MarkerInfoView", which will be created as MarkerInfoView.xib
Then design your UI in there, add your imageView for your icon, then add other necessary views to complete your iconView. Also include marker in the design as an imageView. Because Im not 100% sure but I think you cant use both iconView and icon in google maps.
Then create a swift file called "MarkerInfoView.swift", go to MarkerInfoView.xib and select it's class as MarkerInfoView.
Then create another swift file, lets call it PlaceMarker, inside that file you will create a class which will conform to GMSMarker, then you will initialize your view to set it equal to iconView in PlaceMarker class. Lets do it as following:
class PlaceMarker: GMSMarker {
//Initialize with lat and long, then set position equal to the coordinate.
// 'position' comes from inheriting from GMSMarker, which is google marker.
init(latitude: Double, longitude: Double, distance: Double, placeName: String) {
super.init()
if let lat: CLLocationDegrees = latitude,
let long: CLLocationDegrees = longitude {
let coordinate = CLLocationCoordinate2D(latitude: lat, longitude: long)
position = coordinate
}
let view = Bundle.main.loadNibNamed("MarkerInfoView", owner: nil, options: nil)?.first as! MarkerInfoView
// you can set your view's properties here with data you are sending in initializer.
// Remember if you need to pass more than just latitude and longitude, you need
// to update initializer.
// lets say you created 2 outlet as placeNameLabel, and distanceLabel, you can set
// them like following:
view.placeNameLabel.text = placeName
view.distanceLabel.text = distance
// Once your view is ready set iconView property coming from inheriting to
// your view as following:
iconView = view
appearAnimation = .pop //not necessarily but looks nice.
}
}
Then when you have your data and your googlemaps view in a ViewController you can set like:
let latitude = 101.432432 //arbitrary, should come from your source
let longitude = 34.432124
let distance = 4
let placeName = "My place".
let marker = PlaceMarker(latitude: latitude, longitude: longitude, distance: distance, placeName: placeName)
marker.map = self.mapView // your google maps set your marker's map to it.

Display current location without using CLLocationManager

I am new to iOS and I have a question about finding the current user location. I am reading in Apple documentation:
Displaying the User’s Current Location on the Map Map Kit includes
built-in support for displaying the user’s current location on the
map. To show this location, set the showsUserLocation property of your
map view object to YES. Doing so causes the map view to use Core
Location to find the user’s location and add an annotation of type
MKUserLocation to the map.
The addition of the MKUserLocation annotation object to the map is
reported by the delegate in the same way that custom annotations are.
If you want to associate a custom annotation view with the user’s
location, you should return that view from your delegate object’s
mapView:viewForAnnotation: method. If you want to use the default
annotation view, return nil from that method. To learn more about
adding annotations to a map, see Annotating Maps.
And it sounds great. But then...
import UIKit
import MapKit
class ViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
//set initial location in Honolulu
//let initialLocation = CLLocation(latitude: 21.282778, longitude: -157.829444)
mapView.showsUserLocation = true
let initialLocation = mapView.userLocation.location
centerMapOnLocation(initialLocation)
// let artwork = Artwork(title: "King David Kalakaua", locationName: "Waikiki Gateway Park", discipline: "Sculpture", coordinate: CLLocationCoordinate2D(latitude: 21.283921, longitude: -157.831661))
// mapView.addAnnotation(artwork)
//
// mapView.delegate = self
}
let regionRadius: CLLocationDistance = 1000
func centerMapOnLocation(location: CLLocation){
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, regionRadius * 2.0, regionRadius * 2.0)
mapView.setRegion(coordinateRegion,animated:true)
}
}
And I have a fatal error: unexpectedly found nil while unwrapping an Optional value. I don't get why. If I set the location manually - of course it is fine. But in the documentation it is written that it will add an annotation on the map. No annotation is added and it crashes. Isn't it possible to get the user coordinates without using the CLLocationManager?
Have you asked permissions to the user to let your app use the location services? The docs at Apple can help you with this. Look at the sample code below to get you started:
private func beginLocationUpdates() {
// Request location access permission
_locationManager!.requestWhenInUseAuthorization()
// Start observing location
_locationManager!.startUpdatingLocation()
}

MKLaunchOptionsMapSpanKey & Apple MapKit

What is the correct way to auto zoom an iOS MapKit MKMapItem generated map when it first displays using the option MKLaunchOptionsMapSpanKey:?
Specifically, how should the zoom factor be entered for MKLaunchOptionsMapSpanKey:??? (i.e. MKLaunchOptionsMapSpanKey:0.1).
Or, alternatively, is there another way programmatically to auto zoom the map when it first displays which I am not aware of?
#IBAction func getDirections(sender: AnyObject) {
let mapItem = MKMapItem.mapItemForCurrentLocation()
let coords = CLLocationCoordinate2DMake(latitude, longitude)
mapItem.name = "User Location"
let options = [MKLaunchOptionsMapSpanKey:???,MKLaunchOptionsMapCenterKey:location, ]
let place = MKPlacemark(coordinate: coords, addressDictionary:nil)
mapItem.openInMapsWithLaunchOptions(options)
}