Display map or satellite imagery from your app's interface, call out points of interest, and determine placemark information for map coordinates using MapKit.

Posts under MapKit tag

143 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

how to update SwiftUI Map via MapCamera approach with data from @Observable? (see code)
Anyone able to see how to use the new SwiftUI Map and WWDC @Observable concept to dynamically update my SwiftUI Map position and rotation based on the dynamic changes it picks up from my @Observable object. Note the updates are coming through as the Text labels show this. But how to get the Map position referencing the same values and updating them? The "onAppear" approach doesn't seem to work. import SwiftUI import MapKit @Observable final class NewLocationManager : NSObject, CLLocationManagerDelegate { var location: CLLocation? = nil var direction: CLLocationDirection = 0 private let locationManager = CLLocationManager() func startCurrentLocationUpdates() async throws { if locationManager.authorizationStatus == .notDetermined { locationManager.requestWhenInUseAuthorization() } for try await locationUpdate in CLLocationUpdate.liveUpdates() { guard let location = locationUpdate.location else { return } print("NewLocationManager: \(location.coordinate.latitude), \(location.coordinate.longitude)") self.location = location self.direction = self.direction + 1 } } } struct ContentView: View { var locationMgr = NewLocationManager() @State private var mapCamPos: MapCameraPosition = .automatic private let bigBen = CLLocationCoordinate2D(latitude: 51.500685, longitude: -0.124570) var body: some View { ZStack { Map(position: $mapCamPos) .onAppear { // Does NOT work - how to get position/direction updates working to Map (map should be moving/rotating) mapCamPos = .camera(MapCamera( centerCoordinate: self.locationMgr.location?.coordinate ?? bigBen, distance: 800, heading: self.locationMgr.direction )) } VStack (alignment: .leading) { Text("Location from observable: \(locationMgr.location?.description ?? "NIL")") // This works (they get updates regularly) Text("Direction from observable: \(locationMgr.direction)") // This works (they get updates regularly) Spacer() } } .task { try? await locationMgr.startCurrentLocationUpdates() } } } #Preview { ContentView() } Tag: wwdc2023-10043
2
0
1.7k
Jan ’24
Is it free to use MapKit's MKLocalSearchCompleter and MKLocalSearch on iOS currently?
Is it free to use MapKit's MKLocalSearchCompleter and MKLocalSearch on iOS currently? I would like to use them for getting geocode. I found this forum. https://developer.apple.com/forums/thread/127493 According to this forum, using MapKit for native app development, there is no cost beyond my Apple Developer Program membership. Is it the same now? sincerely
0
0
537
Jan ’24
SwiftUI creating MapCameraPosition from CLLocationManager initialiser/self error when trying to tie them? (see code)
Trying to use new Swift @Observable to monitor GPS position within SwiftUI content view. But how do I tie the latest locations to the SwiftUI Map's mapCameraPosition? Well ideally the answer could cover: How to fix this error - So get map tracking along with the User Position, but also How to include facility to turn on/off the map moving to track the user position (which I'll need to do next). So could be tracking, then disable, move map around and have a look at things, then click button to start syncing the mapcameraposition to the GPS location again Refer to error I'm embedded in the code below. import SwiftUI import MapKit @Observable final class NewLocationManager : NSObject, CLLocationManagerDelegate { var location: CLLocation? = nil private let locationManager = CLLocationManager() func startCurrentLocationUpdates() async throws { if locationManager.authorizationStatus == .notDetermined { locationManager.requestWhenInUseAuthorization() } for try await locationUpdate in CLLocationUpdate.liveUpdates() { guard let location = locationUpdate.location else { return } self.location = location } } } struct ContentView: View { var newlocationManager = NewLocationManager() @State private var cameraPosition: MapCameraPosition = .region(MKCoordinateRegion( center: newlocationManager.location?.coordinate ?? <#default value#>, span: MKCoordinateSpan(latitudeDelta: 0.25, longitudeDelta: 0.25) )) // GET ERROR: Cannot use instance member 'newlocationManager' within property initializer; property initializers run before 'self' is available var body: some View { ZStack { Map(position: $cameraPosition) Text("New location manager: \(newlocationManager.location?.description ?? "NIL" )") // works } .task { try? await newlocationManager.startCurrentLocationUpdates() } } } #Preview { ContentView() }
1
0
1k
Jan ’24
Map In TabView
In SwitUI when using a map within a tabview the tab bar color is translucent when the map tab is selected. All of the other tabs the tab bar is opaque. In the view that contains the map, if the map is commented out the tab display is opaque, only when the map is displayed. I have an init in the tabview to set the tab bar parameters: // Set Tab Bar appearance let tabbarAppearance = UITabBarAppearance() tabbarAppearance.configureWithOpaqueBackground() tabbarAppearance.backgroundColor = .blue UITabBar.appearance().standardAppearance = tabbarAppearance UITabBar.appearance().scrollEdgeAppearance = tabbarAppearance In the view with the map I use a ZStack to set the entire screen color: ZStack(alignment: Alignment(horizontal: .center, vertical: .top)) { Color(.blue) .ignoresSafeArea(.all) .foregroundColor(.black) VStack(alignment: .center, spacing: 5) { Spacer() Map() Spacer() } } I've tried using .padding(), frame, removing ignoresSafeArea but the tab bar still becomes translucent when the tab is selected. Selecting another tab the color becomes opaque. Any suggestions on how to correct this behavior so the tab bar is opaque for all tabs?
0
0
456
Jan ’24
App store alert to download Apple maps appears twice
I have a code that redirects the user to Google Maps or Apple Maps by pressing the map , when Apple Maps is uninstalled, an alert appears asking the user to download Apple Maps and redirects the user to the App Store, when I select Show in App Store, the user is redirected to App Store, and then the alert is shown again. func openMaps() { let coordinate = CLLocationCoordinate2D(latitude: 52.5162746, longitude: 13.3755153) let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: coordinate)) mapItem.name = "Test" mapItem.openInMaps(launchOptions: [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDefault]) }
0
0
320
Dec ’23
MapKit animations on tvOS result in hang
Hardware: Apple TV 4K (1st gen) OS: tvOS 17.1 I have been attempting to create a simple dashboard using MapKit for my company's devices located around the globe. As of now, we only have 7-8 attached to the main database, so I'm using an API client I created to load that many Map markers after the View is loaded. My issue is that despite this being a relatively low-intensity task, the Map view crashes after about 15 minutes, with no errors or any indications of memory leaks or other problems that would indicate something is wrong. GPU usage spikes on initial load, but remains in the green throughout the process. I tried the same code in swift playgrounds and was able to get the globe to spin indefinitely, probably because it's using the extra resources available on my M2 Max chip. But again, I am well below the memory and CPU usage limits available for tvOS. other than initially loading 7-8 objects asynchornously on initial load, no other work is being done. MRE: import SwiftUI import MapKit struct ContentView: View { let timer = Timer.publish(every: 0.1, on: .main, in: .default).autoconnect() @State var viewport: MapCameraPosition = .region(MKCoordinateRegion(center: .init(latitude: 0, longitude: 0), span: .init(latitudeDelta: 90, longitudeDelta: 180))) @State var longitude: Double = 0 { didSet { viewport = .region(MKCoordinateRegion(center: .init(latitude: 20, longitude: longitude), span: .init(latitudeDelta: 90, longitudeDelta: 180))) } } private func shiftLongitude(by: Double) { if self.longitude >= 180 { self.longitude -= 360 } else { self.longitude += by } } var body: some View { Map(position: $viewport) { } .mapStyle(.imagery(elevation: .realistic)) .onReceive(timer) { _ in withAnimation { self.shiftLongitude(by: 1.0) } } } }
1
0
543
Dec ’23
MapKit billing policy on native apps
Thank you all in advance. I've checked the terms and the pre-posted forum related to the same question. https://developer.apple.com/forums/thread/127493 I have plans to use MapSDK in my native app and is critical to know that it really is free to use. Though I've checked the answers, I was wondering if there's a written document that says it's free to use on native apps.
1
0
407
Dec ’23
MKMapView crashes in iOS 17.1 and later
I'm experiencing crashes in our Application when displaying an MKMapView. The crash seems to be happening at a pretty low level and it's difficult to diagnose what the issue is. It's only happening on devices running iOS 17.1 or later, not happening in the simulator. All we are doing in the code is initializing and MKMapView and adding to a ViewController view, causes the crash. Our App has been around for a while and was working prior to the roll out of iOS 17.1. Replaced the App name in the crash report for privacy. My analysis is that in thread 35 you can see GeoServices and VectorKit libraries being called, VectorKit appears to trying to be calling string length on an null string. Crash Report crasher.txt Crashing thread from report Thread 35 name: Thread 35 Crashed: 0 libsystem_platform.dylib 0x000000021d94f244 _platform_strlen + 4 (:-1) 1 VectorKit 0x00000001d06aafcc std::__1::__constexpr_strlen[abi:v160006](char const*) + 28 2 VectorKit 0x00000001d06a5f58 std::__1::char_traits::length(char const*) + 28 3 VectorKit 0x00000001d06aae70 std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator>::basic_string[abi:v160006]std::nullptr_t(char const*) + 60 4 VectorKit 0x00000001d0aaa1c8 invocation function for block in md::TiledGEOResourceFetcher::fetchResources(std::__1::unordered_map<gdc::ResourceKey, unsigned long long, gdc::ResourceKeyHash, std::__1::equal_togdc::ResourceKey... + 1364 (MDTiledGEOResourceFetcher.mm:290) 5 GeoServices 0x00000001ba77f9b0 __143-[GEOTileLoader loadKey:additionalInfo:priority:forClient:auditToken:options:reason:qos:signpostID:createTime:callbackQ:beginNetwork:callback:]_block_invoke + 276 (GEOTileLoader.mm:1066) 6 GeoServices 0x00000001ba78b8b4 invocation function for block in -[GEOTileLoader _loadedTileForLocalKey:preliminary:quickly:tileDecoder:data:disburseTile:]::$_7::operator()(LoadItem::Requester const&) const + 96 (GEOTileLoader.mm:2167) 7 libdispatch.dylib 0x00000001bbf6c250 _dispatch_block_async_invoke2 + 148 (queue.c:555) 8 libdispatch.dylib 0x00000001bbf5d300 _dispatch_client_callout + 20 (object.m:561) 9 libdispatch.dylib 0x00000001bbf607b8 _dispatch_continuation_pop + 600 (queue.c:306) 10 libdispatch.dylib 0x00000001bbf5fdd4 _dispatch_async_redirect_invoke + 584 (queue.c:830) 11 libdispatch.dylib 0x00000001bbf6ebe4 _dispatch_root_queue_drain + 392 (queue.c:7051) 12 libdispatch.dylib 0x00000001bbf6f3ec _dispatch_worker_thread2 + 156 (queue.c:7119) 13 libsystem_pthread.dylib 0x000000021d9f9928 _pthread_wqthread + 228 (pthread.c:2642) 14 libsystem_pthread.dylib 0x000000021d9f9a04 start_wqthread + 8 (:-1)
3
0
611
Dec ’23
MapKit UI - Marker / Protocol help
Hi , I'm trying to teach myself the new Mapkit code. Can someone help me fix the code below: I'm getting the following error on Line 19: Initializer 'init(coordinateRegion:interactionModes:showsUserLocation:userTrackingMode:annotationItems:annotationContent:)' requires that 'Marker' conform to 'MapAnnotationProtocol' import MapKit struct IdentifiableAnnotation: Identifiable { let id = UUID() var annotation: MKPointAnnotation } struct ContentView: View { @ObservedObject var locationManager: LocationManager @State private var showUserProfile = false @State private var showNotifications = false @State private var showFriendz = false @State private var courtAnnotations: [IdentifiableAnnotation] = [] var body: some View { NavigationView { ZStack(alignment: .bottom) { Map(coordinateRegion: $locationManager.region, interactionModes: .all, showsUserLocation: true, userTrackingMode: .none, annotationItems: courtAnnotations) { item in Marker(<#LocalizedStringKey#>, coordinate: item.annotation.coordinate) } .edgesIgnoringSafeArea(.all)
2
1
644
Jan ’24
MapKit in List Breaks Top/Bottom Bar FadeIn/Out Effect
I've encountered a weird issue with the new Map for iOS 17. In my list, which includes a MapView among other elements, I've observed that with the new initializer, the top and bottom bars are persistently displayed. They don't hide and only appear when scrolling, as they should. This problem doesn't occur with the old, now-deprecated initializer. To illustrate this, I have two screenshots: one with the map enabled and the other with the map disabled, demonstrating the issue. Here is also my new Map code: struct MapListRowView: View { @Binding internal var location: LocationModel @State internal var user: Bool = true private var position: CLLocationCoordinate2D { .init(latitude: location.latitude, longitude: location.longitude) } private var isPad: Bool { UIDevice.current.userInterfaceIdiom == .pad ? true : false } var body: some View { Map(bounds: .init(minimumDistance: 1250)) { if user { UserAnnotation() } Annotation("", coordinate: position) { ZStack { Circle().fill().foregroundColor(.white).padding(1) Image(systemName: "mappin.circle.fill") .resizable() .foregroundColor(.indigo) }.frame(width: 20, height: 20).opacity(user ? .zero : 1.0) } } .frame(height: isPad ? 200 : 100) .cornerRadius(8) .listRowInsets(.init(top: -5, leading: .zero, bottom: -5, trailing: .zero)) .padding(.vertical, 5) .disabled(true) } }
1
0
478
4w
Random Look Around Coordinates
I want to generate randomised MKLookAroundScene for my world exploration app (think geogussr functionality). How can i achieve that with MapKit? I have tried struct LookAroundView: View { @State private var lookAroundScene: MKLookAroundScene? @State private var yOffset: CGFloat = 0 func generateRandomCoordinate() { let minLatitude = -90.0 let maxLatitude = 90.0 let minLongitude = -180.0 let maxLongitude = 180.0 let randomCoordinate = CLLocationCoordinate2D( latitude: Double.random(in: minLatitude...maxLatitude), longitude: Double.random(in: minLongitude...maxLongitude) ) checkLookAroundAvailability(coordinate: randomCoordinate) } func checkLookAroundAvailability(coordinate: CLLocationCoordinate2D) { Task { let request = MKLookAroundSceneRequest(coordinate: coordinate) if let scene = try? await request.scene { DispatchQueue.main.async { self.lookAroundScene = scene } } else { generateRandomCoordinate() } } } var body: some View { Group { if let scene = lookAroundScene { LookAroundPreview(initialScene: scene) } else { Button(action: { generateRandomCoordinate() }) { Text("Generate Random Coordinate") } .offset(y: yOffset) } } } } but it didn't work. I put the yOffset change there to debug, and it seems that self.lookAroundScene = scene never gets executed. If there are any other options, please let me know!
1
1
645
Dec ’23
MapKit elevation information for a route
Hello all, I am playing with MapKit for SwiftUI, so far so good. There is one thing I have not seen any documentations, or sample codes around and that's elevation data, e.g. My questions are: Is there a way to get this information from an MKRoute? Is it possible to get the elevation gain/drop at a given point in the route? Many thank in advance for your help.
1
1
473
Oct ’24
MapProxy conversion from screen to coords is wrong on macOS
Try the following code on macOS, and you'll see the marker is added in the wrong place, as the conversion from screen coordinates to map coordinates doesn't work correctly. The screenCoord value is correct, but reader.convert(screenCoord, from: .local) offsets the resulting coordinate by the height of the content above the map, despite the .local parameter. struct TestMapView: View { @State var placeAPin = false @State var pinLocation :CLLocationCoordinate2D? = nil @State private var cameraProsition: MapCameraPosition = .camera( MapCamera( centerCoordinate: .denver, distance: 3729, heading: 92, pitch: 70 ) ) var body: some View { VStack { Text("This is a bug demo.") Text("If there are other views above the map, the MapProxy doesn't convert the coordinates correctly.") MapReader { reader in Map( position: $cameraProsition, interactionModes: .all ) { if let pl = pinLocation { Marker("(\(pl.latitude), \(pl.longitude))", coordinate: pl) } } .onTapGesture(perform: { screenCoord in pinLocation = reader.convert(screenCoord, from: .local) placeAPin = false if let pinLocation { print("tap: screen \(screenCoord), location \(pinLocation)") } }) .mapControls{ MapCompass() MapScaleView() MapPitchToggle() } .mapStyle(.standard(elevation: .automatic)) } } } } extension CLLocationCoordinate2D { static var denver = CLLocationCoordinate2D(latitude: 39.742043, longitude: -104.991531) } (FB13135770)
4
0
994
Mar ’24
SwiftUI Map: is it possible to add an inset to the map visible rectangle?
In UIKit, we can add an insets to a MKMapView with setVisibleMapRect to have additional space around a specified MKMapRect. It's useful for UIs like Apple Maps or FlightyApp (see first screenshot attached). This means we can have a modal sheet above the map but still can see all the content added to the map. I'm trying to do the same for a SwiftUI Map (on iOS 17) but I can't find a way to do it: see screenshot 2 below. Is it possible to obtain the same result or should I file a feedback for an improvement?
2
0
1.5k
Feb ’24
SwiftUI - Adjust Map() scale/zoom
Hi, I'm looking through SwiftUI Map for SwiftUI documentation (including IOS17 Beta) for way to adjust Map() scale, or zoom level, while simultaneously showing user's location and heading, for which I'm doing this @State var position = MapCameraPosition = .userLocation(followsHeading: true, fallback: .automatic) Map(position: $position) It does not appear to be possible so am looking for confirmation. Thanks everyone.
3
1
2.9k
Jan ’24
How to handle thousands of map annotations (+100K) in a MKMapView?
According to the MKMapview, all annotations should be added to the map: https://developer.apple.com/documentation/mapkit/mkmapview When configuring your map interface, be sure to add all of your annotation objects right away. The map view uses the coordinate data in each annotation object to determine when the corresponding annotation view needs to appear onscreen. When an annotation moves onscreen, the map view asks its delegate to create a corresponding annotation view. If your app has different types of annotations, it can define different annotation view classes to represent each type. But this has a very low performance when the map is zoomed out and all annotations are visible (although market already filters out most of the annotations and only displays a few). As fas as I've seen, the suggestion from the documentation doesn't scale properly when the number of annotations is very large. Grouping doesn't help, neither using reusable annotations. Is the only option here, handling manually the add/remove annotations as the map rect changes?
2
0
1.1k
Feb ’24