pauljohanneskraft / Map

MKMapView wrapper for SwiftUI as drop-in to MapKit's SwiftUI view. Easily extensible annotations and overlays, iOS 13 support and backwards compatible with MKAnnotation and MKOverlay!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

User location not showed

Nickbarbieri1 opened this issue · comments

Hi, I'm developing an application in SwifUI to estimate the power consumption of an e-bike based on the track chosen by the user; I'm implementing a Map initializing it as showed in the example file, but when I try to show also user position the map doesn't show the location.
I have implemented a CLLocationManager to manage user position and it works correctly, but in the example is not specified very well how to link the two components.

commented

The approaches are very similar to how the Apple implementation works and therefore do not necessarily need specific documentation here imho. If you feel different about this, feel free to open a pull request with a more extensive explanation.

There are two possible approaches on how to display the current user position.

1. The 'default' way:

You can simply use the MapInformationVisibility parameter when initializing the map:

Map(
    coordinateRegion: $region, // you can also use mapRect here, does not make a difference for this example
    informationVisibility: .default.union(.userLocation)
)

This will show the user location as it does in the Maps app. The appearance is hereby fixed - if you need a custom appearance, please look at the following option:

2. The 'custom' way:

Specify an annotation as you normally would that reflects the user location by first defining an annotation item type:

struct UserLocationAnnotation: Identifiable {
    var id = UUID()
    let coordinate: CLLocationCoordinate2D
    // of course, you can add more properties here that might be helpful when creating the annotation itself from this annotation item (e.g. color, text, etc)
}

Not let's plug it into a Map:

struct MyMapView: View {
    
    @State private var annotationItems = [UserLocationAnnotation]()

    var body: some View {
        Map(
            coordinateRegion: $region, // you can also use mapRect here, does not make a difference for this example
            annotationItems: annotationItems
        ) { annotationItem in
            MapMarker(coordinate: annotationItem.coordinate, tint: .red) 
            // This could be any kind of annotation, e.g. ViewMapAnnotation, MapPin and MapMarker
        }
    }

}

Now you would only need to somehow set the state according to the locations received from your CLLocationManager. You could also use an @Published property inside an ObservableObject using the ObservedObject/StateObject/EnvironmentObject property wrappers. One thing you will need to make sure is to not create the identifiable objects inside the body, since they would be removed and added on each redraw of the map, which would be quite costly performance-wise (this is the case in Apple's Map SwiftUI implementation as well btw).

Thank you for your answer, but I'm still having problems with user position visualization, especially with the "default" way: when the map appears on the view is centered on the user position, but it doesn't show a dot/mark on the map (as Apple Maps does); furthermore, the Location manager, that at the beginning of the app it was working good starts to raise errors (managed by callback function didFailWithError).
I'm also sure that Location Manager class works well because using a standard Map object from MapKit I get rid of the errors.

commented

You will still need to handle authorization, maybe this is the issue? This library is simply setting showsUserLocation on MKMapView, so there should not really be an issue in any way. I sadly don't have the time to dig into this deeper at the moment, but I remember that this definitely worked a couple of weeks ago.

Which version of this library are you using? Could you maybe try the latest main commit?

I tried to add the package inside my Xcode project specifying the main branch rather than the default version proposed by Xcode and it starts to work correctly.
Thank you very much for your help and I', very sorry for wasting your time for a stupid thing.

commented

great! not a waste of time at all - it tells me that I will need to release a new version soon, so that this bug does not appear for new users of this library.

@pauljohanneskraft i also noticed that there is one reported bug left, about the name clash of UserTrackingMode inside the main branch.
I noticed it now, trying to adapt the Map to the new initialization inside my app.