Good afternoon, I'd like to get detailed information about the price usage of the Apple Map in my app in IOS (Swiftui for Iphone and Ipad). I'd like to establish a future price for the app subscription and to do that I need to obtain the precise prices for opening the map, consulting Map items, creating routes, the price of each consulting, and any other price that is related to the map usage process.
I have been searching for this information and it has not been easy to find answers. I appreciate it if I could get the information.
Best regards,
Marcello Lima
MapKit
RSS for tagDisplay 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
145 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hi there,
I am trying to develop a country guessing game using MapKit and GeoJSON data. I have verified that my data creates the outline of the country properly using other methods, but I run into an error where the map clips and does not show portions of the countries or islands when zooming at certain levels of the map. I receive the warnings in the terminal "Mismatching number of indices, indexCount: 30, triangulatedIndexCount: 27" and "Triangulator failed to fully triangulate polygon: (0.1296, 0.303328), (0.108053, 0.296605), (0.0671644, 0.289883), (0.0586311, 0.281121), (0.0397156, 0.27289), (0.0323911, 0.262393), (0.0610489, 0.260732), (0.102507, 0.284671), (0.140053, 0.292602), (0.133511, 0.291167), (0.137707, 0.293659), (0.138489, 0.29872)" I am not sure what these tuple values are, or how to fix the errors, as I have adjusted my data (removing duplicate coordinates, refreshing the map, etc). How am I able to counteract these warnings, or at least get a sense of what they are asking?
Is it possible to programmatically force iphone to use cellular internet during WIFI connection?
I am connected via WIFI to a device with no internet connection. But I need to use MapKit
Hello, I have a question.
I have a LookAroundPreview, that loads correctly a scene, and when I tap on it, it natively shows a view I can navigate in, and that I can close. All that is ok.
However, when I want to display that same LookAroundPreview in a fullScreenCover (because my app needs it for navigation purposes), it directly shows the navigatable View with the closeButton. That I don't want.
Is there an option to pass, that I missed? Is this a bug of the LookAroundPreview? Or is this wanted by Apple devs?
Thank you very much for your help,
Sincerely
import SwiftUI
struct ContentView: View {
@State private var displayFullScreen = false
//AppleLookAroundView is just a wrapper around native LookAroundPreview, that loads a NYC coordinate
var body: some View {
VStack {
AppleLookAroundView()
Spacer()
Button("Display fullScreen cover") {
displayFullScreen = true
}
Spacer()
}
.fullScreenCover(isPresented: $displayFullScreen) {
VStack {
AppleLookAroundView()
Text("⬆ It somehow detects it is in a fullScreenCover and unwantingly change its display")
}
}
}
}
import SwiftUI
import MapKit
import CoreLocation
struct AppleLookAroundView: View {
@State private var scene: MKLookAroundScene?
let coordinate = CLLocationCoordinate2D(latitude: 40.651238394229324, longitude: -73.96432239237737)
var body: some View {
LookAroundPreview(scene: $scene, allowsNavigation: true, badgePosition: .bottomTrailing)
.task {
do {
scene = try await fetchScene(for: coordinate)
} catch {
print("Couldn't fetch scene")
}
}
.frame(height: 300)
}
private func fetchScene(for coordinate: CLLocationCoordinate2D) async throws -> MKLookAroundScene? {
let lookAroundScene = MKLookAroundSceneRequest(coordinate: coordinate)
let scene = try await lookAroundScene.scene
return scene
}
}
![]("https://developer.apple.com/forums/content/attachment/a10a7701-dd8c-4d83-9a03-848cf0373417" "title=Capture d’écran 2024-04-24 à 12.56.46.png;width=898;height=1860")
``
![]("https://developer.apple.com/forums/content/attachment/d54f7fe1-aac8-4280-ab97-663f0bdd440f" "title=Capture d’écran 2024-04-24 à 12.56.34.png;width=924;height=1882")
`
On iPhone 14 Pro running iOS 17.4.1, tapping on MKMapView triggers a dozen or more additional hitTest calls. At the moment, only one device has encountered this issue.Not sure if it's a hardware issue or a bug with MKMapView.
Adding MKMapView to the app could potentially cause multiple hitTest calls on views across other pages.
I'm developing an iOS app that displays store locations on a map using Apple Maps (MapKit). I've limit the number of icons that can be displayed on the map to 100, but there's still huge performance issues and the app is very laggy even on modern iPhone models. What's the best practice when displaying a large number of icons on a map, should the icons be in PNG format with a small resolution (~10kb) or should the icons be vector (SVG) for best performance? Should I use the MapKit framework for iOS 17 or the UIKit approach?
I have a problem getting cg point from coordinate with MKsnapshotter.
It works well with .flyover or .satellite map type but when using .satelliteFlyover cg point gets invalid value.
Can you guys help me to get correct value?
I attach screenshot here.
Using SwiftUI, MapKit and the Map() view in iOS 17, I'm adding markers and annotations to the map instance. However it seems regardless of what order they are added, they are rendered with random Z-index values. I've not found any modifiers to specify any kind of priority.
Is there a way to declare Z-index priority of Marker and Annotation views?
I have more than 2000 location pins in SwiftData.
My model like this:
@Model
class HaritaModel {
let id: Int
let sto_title: String
let sto_latitude: Double
let sto_longitude: Double
let sto_address: String
let sto_city: String
let sto_country: String
init(id: Int, sto_title: String, sto_latitude: Double, sto_longitude: Double, sto_address: String, sto_city: String, sto_country: String) {
self.id = id
self.sto_title = sto_title
self.sto_latitude = sto_latitude
self.sto_longitude = sto_longitude
self.sto_address = sto_address
self.sto_city = sto_city
self.sto_country = sto_country
}
}
I want to take the user's location and show them the pins at a certain distance. I want these pins to be dynamically updated when the user pan or zoom the map.
The code I am trying to write is as follows:
//
// HaritaTest.swift
//
import SwiftUI
import MapKit
import SwiftData
struct HaritaTest: View {
@Environment(\.modelContext) private var contextHarita
@Query private var harita: [HaritaModel]
@State private var userPosition: MapCameraPosition = .userLocation(fallback: .automatic)
@State private var userCoordinate: CLLocationCoordinate2D?
var body: some View {
Text("Total Boutique \(harita.count)")
Map(initialPosition: { userPosition }) { haritaView in
ForEach(harita) { point in
if let userCoordinate = userCoordinate,
let stoLatitude = point.sto_latitude,
let stoLongitude = point.sto_longitude,
let latitude = Double(stoLatitude),
let longitude = Double(stoLongitude) {
let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
if haritaView.contains(coordinate: coordinate) {
MapPin(coordinate: coordinate)
}
}
}
}
.onAppear {
CLLocationManager().requestWhenInUseAuthorization()
getUserLocation()
}
}
private func getUserLocation() {
if let userLocation = CLLocationManager().location {
userCoordinate = userLocation.coordinate
}
}
}
struct HaritaTest_Previews: PreviewProvider {
static var previews: some View {
HaritaTest()
}
}
can you support me?
thanks in advance
Is there a possibility to enable the public transport layer like in the Maps app?
We're recently requested a Mapkit JS / Mapkit Server api limit increase request and are waiting to hear back before we push an important update to our app which switches to mapkit via server apis.
We don't often go over the 25k daily limit, but there can be spikes where the app goes very viral and we'll need well over 25k – likely above 50k based on historic usage.
I was wondering if there's any way to expedite our limit request? Or how do we get notified if our limit has been approved, is there any way to check?
Would using one of our Code-level support requests (TSIs) be a good idea here?
Thanks!
Any suggestions on how to display multi-polygons within MapKit for SwiftUI(https://developer.apple.com/documentation/mapkit/mappolygon)?
At the moment it is not supported and only supported by MapKit for UIKit(https://developer.apple.com/documentation/mapkit/mkmultipolygon) . Any idea on how to bridge these over?
The code in this example to add a gradient to a map polyline from WWDC doesn't work.
https://developer.apple.com/videos/play/wwdc2023/10043/?time=1360
The polyline is rendered as a solid colour from as the first colour in the given array. Does anyone have any suggestions?
Code for convenience:
let coordinates = [
CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194),
CLLocationCoordinate2D(latitude: 37.3352, longitude: -122.0322),
CLLocationCoordinate2D(latitude: 34.0522, longitude: -118.2437)
]
let gradient = LinearGradient(colors: [.red, .green, .blue], startPoint: .leading, endPoint: .trailing)
let stroke = StrokeStyle(lineWidth: 5, lineCap: .round, lineJoin: .round, dash: [10, 10])
var body: some View {
Map {
MapPolyline(coordinates: coordinates)
.stroke(gradient, style: stroke)
}
}
If I load a map while my device is online, I can access this map offline via the default caching mechanism. I need to be able to identify if a map cache is unavailable when my device is offline and react accordingly. For example, if I am offline and I load a map and the cache is unavailable i.e the map tiles are greyed out, I want to display a message to the user. The AppKit delegate had a method to identify when a map loaded but I do not see an equivilient way of doing this in Map. Any ideas?
I need to mark areas on a map, but I have only the points and want to have map circles around the points, how is it possible to make the circles not overlap in color, just look as they were one form.
What I am trying to accomplish:
Navigate to MapView defined in ProfileMapView. - This works
In ProfileMapView, when calloutAccessoryControlTapped method is called Navigate from ProfileMapView when to another view: ProfileDetailsView- This is does not work
//Calling ProfileMapview like this:
@State var pins = [GpsData.MyEndPt]()
ProfileMapView(locationPins: $pins)
// ProfileMapView defined
struct ProfileMapView: View {
@Environment(\.managedObjectContext) private var viewContext
@Environment(\.dismiss) var dismiss
@State var tracking:MapUserTrackingMode = .follow
@Environment(\.presentationMode) var presentationMode
@Binding var locationPins: [GpsData.MyEndPt]
var body: some View {
TabView {
NavigationView {
ZStack {
VStack (alignment: .leading){
MapView(locationPins: $locationPins)
.ignoresSafeArea()
}
}
//.edgesIgnoringSafeArea(.all)
.safeAreaInset(edge: .bottom) {
Color.clear
.frame(height: 0)
.background(.white)
}
}
}
struct MapView: UIViewRepresentable {
@Binding var locationPins: [GpsData.MyEndPt]
func makeUIView(context: Context) -> MKMapView {
//...
}
func updateUIView(_ uiView: MKMapView, context: Context) {
//...
}
func makeCoordinator() -> MapViewDelegate{
var del = MapViewDelegate()
del.addEndPoints(endPoints: locationPins)
return del
}
class MapViewDelegate: MKMapView, MKMapViewDelegate {
let PINID:String = "MyEndPoint"
var mylocationPins: [GpsData.MyEndPt] = []
@State var locationId: String?
@State var providerType: String?
public func addEndPoints(endPoints: [GpsData.MyEndPt]) {
self.mylocationPins = endPoints
self.removeAnnotations(endPoints)
self.addAnnotations(endPoints)
self.showAnnotations(endPoints, animated: true)
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
var mPin: MKMarkerAnnotationView? = nil
let subtitleView = UILabel()
for pin in self.mylocationPins {
if (mPin == nil ) {
mPin = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: PINID)
mPin?.canShowCallout = true
} else{
mPin?.annotation = annotation
}
mPin?.rightCalloutAccessoryView = UIButton(type: UIButton.ButtonType.detailDisclosure)
subtitleView.text = "Target: "
subtitleView.text! += String(pin.target)
}
mPin!.detailCalloutAccessoryView = subtitleView
return mPin!
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
DispatchQueue.main.async {
if let thumbnailImageButton = view.leftCalloutAccessoryView as? UIButton,
let url = (view.annotation as? GpsData.MyEndPt)?.thumbnailUrl
{
print("URL: \(url)")
do{
let imageData: Data = try Data(contentsOf: url as URL)
let image = UIImage(data: imageData)
thumbnailImageButton.setImage(image, for: UIControl.State.normal)
}catch{
print("Unable to load image data: \(error)")
}
}
}
}
//MARK:- delegate method
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
if control == view.rightCalloutAccessoryView {
mapView.deselectAnnotation(view.annotation, animated: true)
for detail in self.mylocationPins {
locationId = detail.locationId
providerType = detail.providerType
NavigationLink(value: control) {
ProfileDetailsView(locationId: $locationId, providerType: $providerType)
}
break
}
}
}
}
}
}
ProfileDetailsView defined like this:
@StateObject var manager = LocationManager()
@State var tracking:MapUserTrackingMode = .follow
@Environment(\.presentationMode) var presentationMode
@Binding var locationId: String?
@Binding var providerType: String?
var body:some View {
VStack (alignment: .leading){
Text("Details here...")
Button {
}
label: {
Text("Share")
.foregroundColor(.blue)
}
.buttonStyle(.bordered)
Button {
}
label: {
Text("Update consumption")
.foregroundColor(.blue)
}
.buttonStyle(.bordered)
}
}
}
I get warning: "Accessing State's value outside of being installed on a View. This will result in a constant Binding of the initial value and will not update." inside ProfileMapView line wheer I define @Binding var locationPins: [GpsData.MyEndPt]. That value is being passed into ProfileMapView - so I dont know why then warning.
However, ProfileMapView gets called, the mapview is displayed and the marker pin appears and when I click on the disclosure the navigation to other view ProfileDetailsView does not work. I tried NavigationStack and could not make it work because it threw lot of errors. How to fix the code in calloutAccessoryControlTapped method, so I can navigate to other view: ProfileDetailsView. I have spent a week on this trying various things but it hasn't worked.
Two separate app projects need maps or navigation:
Offline map: offline vector map of small city needed within the app (avoiding any online connection after the app's install). Apple Maps requires map tile download after installation. What is an alternative solution?
Navigation: An app with a list of locations where we don't want to build-in maps or navigation. Would it be possible to allow the user to click on a location, app copies GPS coordinates, and opens default iOS navigation app and navigates from there instead?
Working in Xcode with Swift and SwiftUI.
I'm trying to adapt my current production ready iOS/iPadOS 17 app to visionOS and I'm trying it directly running the app for the Apple Vision Pro (Designed for iPad) target.
I have a bottom sheet to show Map items detail by tapping on the Map Annotations. The bottom sheet is opening properly with a normal Button action but it's not opening by Annotation which wrapped Button action. It pops up as expected on iOS/iPadOS but on VisionOS it doesn't.
Annotation("", coordinate: result.coordinate) {
Button(action: { ... } )
})
From core data I generate data for map marker pins. When user selects a marker pin I display the data in a popup label with multiple rows, when I click on the pin. This is working for one marker pin. Now, I need to iterate over a list and generate several of those markers each with unique popup label data.
The code:
struct MapView: UIViewRepresentable {
var annotationOnTap: (_ title: String) -> Void
@Binding var pins: [GpsData.MyEndPt]
let key: String
private static var mapViewStore = [String : MKMapView]()
func makeUIView(context: Context) -> MKMapView {
if let mapView = MapView.mapViewStore[key] {
mapView.delegate = context.coordinator
return mapView
}
let mapView = MKMapView(frame: .zero)
mapView.delegate = context.coordinator
MapView.mapViewStore[key] = mapView
return mapView
}
func updateUIView(_ uiView: MKMapView, context: Context) {
uiView.addAnnotations(pins)
}
func makeCoordinator() -> MapCoordinator {
MapCoordinator(self)
}
final class MapCoordinator: NSObject, MKMapViewDelegate {
var parent: MapView
init(_ parent: MapView) {
self.parent = parent
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let PINID:String = "MyEndPoint"
var mPin: MKMarkerAnnotationView? = nil
let subtitleView = UILabel()
subtitleView.font = subtitleView.font.withSize(12)
subtitleView.numberOfLines = 0
if (mPin == nil ) {
mPin = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: PINID)
mPin?.canShowCallout = true
} else{
mPin?.annotation = annotation
}
mPin?.leftCalloutAccessoryView = nil
let btn = UIButton(type: .detailDisclosure)
mPin?.rightCalloutAccessoryView = btn
let zip:String = "77065"
let formattedSalesStr:String = "100"
let totalTargetText:String = "500"
let paddedLoad = formattedSalesStr.padding(toLength: 50, withPad: " ", startingAt: 0)
let paddedCapacity = totalTargetText.padding(toLength: 50, withPad: " ", startingAt: 0)
subtitleView.text = "Total sales: "
subtitleView.text! += paddedLoad
subtitleView.text! += " \r\n"
subtitleView.text! += "Total Target: "
subtitleView.text! += paddedCapacity
subtitleView.text! += " \r\n"
subtitleView.text! += paddedzip
mPin!.detailCalloutAccessoryView = subtitleView
return mPin!
}
}
}
As you can see in the above method I have hardcoded values for my popup marker label. So I tried to iterate over the @Binding pins, populate each mPin, and return an array of MKAnnotationView, like this:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> [MKAnnotationView] {
let PINID:String = "MyEndPoint"
var i:Int = 1
var mPins = [MKAnnotationView]()
for detail in self.parent.pins {
var mPin: MKMarkerAnnotationView? = nil
let subtitleView = UILabel()
subtitleView.font = subtitleView.font.withSize(12)
subtitleView.numberOfLines = 0
if (mPin == nil ) {
mPin = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: PINID)
mPin?.canShowCallout = true
} else{
mPin?.annotation = annotation
}
mPin?.leftCalloutAccessoryView = nil
let btn = UIButton(type: .detailDisclosure)
mPin?.rightCalloutAccessoryView = btn
subtitleView.text! += String(i)
subtitleView.text = "Total Load: "
subtitleView.text! += String(detail.sales)
subtitleView.text! += " \r\n"
subtitleView.text! += "Total Target: "
subtitleView.text! += String(detail.target)
subtitleView.text! += " \r\n"
i += 1
// }
mPin!.detailCalloutAccessoryView = subtitleView
mPins.append(mPin!)
}
return mPins
}
The marker pins show up, but then the label does not popup. How to fix this?
I have a LookAroundPrewiew in a frame which itself is already small. On top of that is the LookAroundPreview automatically appended onto the preview. In fact it doesn’t really bother me per se, but it’s that my view doesn’t have much space. So is it possible customize the view by removing the text ? And the Apple Maps text at the bottom of the image which is fairly small isn’t a problem for me.