In reference to this webpage, I'm turning my iPad to an iBeacon device.
class BeaconViewModel: NSObject, ObservableObject, CBPeripheralManagerDelegate {
private var peripheralManager: CBPeripheralManager?
private var beaconRegion: CLBeaconRegion?
private var beaconIdentityConstraint: CLBeaconIdentityConstraint?
//private var beaconCondition: CLBeaconIdentityCondition?
override init() {
super.init()
if let uuid = UUID(uuidString: "abc") {
beaconIdentityConstraint = CLBeaconIdentityConstraint(uuid: uuid, major: 123, minor: 456)
beaconRegion = CLBeaconRegion(beaconIdentityConstraint: beaconIdentityConstraint!, identifier: "com.example.myDeviceRegion")
peripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: nil)
}
}
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
switch peripheral.state {
case .poweredOn:
startAdvertise()
case .poweredOff:
peripheralManager?.stopAdvertising()
default:
break
}
}
func startAdvertise() {
guard let beaconRegion = beaconRegion else { return }
let peripheralData = beaconRegion.peripheralData(withMeasuredPower: nil)
peripheralManager?.startAdvertising(((peripheralData as NSDictionary) as! [String: Any]))
}
func stopAdvertise() {
peripheralManager?.stopAdvertising()
}
}
In Line 10, I'm using CLBeaconidentityConstraint to constrain the beacon. Xcode says that this class is deprecated and suggests that we use CLBeaconIdentityCondition. But if I try to use it, Xcode says
Cannot find type 'CLBeaconIdentityCondition' in scope
I've just updated Xcode to 16.4. I still get the same error. So how do we use CLBeaconIdentityCondition to constrain the beacon? My macOS version is Sequoia 15.5. Thanks.
Maps & Location
RSS for tagLearn how to integrate MapKit and Core Location to unlock the power of location-based features in your app.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I'm building a weather map that shows the rain on the map. I'm able to retrieve PNG images that are used as tiles to put onto the map. I then reload all the tiles on the map with each timeframe (tile set for every 10 minutes).
I'm able to get the map loaded up and I'm able to place the tiles and reload the data for each time slot. But I'm getting a ton of spam on the console every time the tiles are reloaded.
Failed to locate resource named "sky20Grey0@2x.png"
Failed to locate resource named "sky20Grey0@2x.png"
Compiler failed to build request
Compiler failed to build request
Compiler failed to build request
Compiler failed to build request
Compiler failed to build request
Compiler failed to build request
Compiler failed to build request
Compiler failed to build request
Compiler failed to build request
Yet the images are showing on the map just fine. But I feel like it's a bit sluggish due to all the spam coming out as I'm reloading this every 0.5 seconds with a timer.
I've tried to load the data from a remote server on demand by overriding the - (void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *tileData, NSError *error))result function. But due to the timer this can lead to the data not getting loaded fully before it switches to the next time slot of data. I therefore pre-load everything. I can then store the NSData in memory and use loadTileAtPath or the NSURL to a stored file and use - (NSURL *)URLForTilePath:(MKTileOverlayPath)path. Both cases work. But both cases have this spam.
I've further refined things such that the MKTileOverlayRenderer is reused but that didn't help. Here's the function for that..
- (MKOverlayRenderer*)mapView:(MKMapView*)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
if ([overlay isKindOfClass:[MKTileOverlay class]]) {
if (!self.rainRenderer) {
self.rainRenderer = [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay];
self.rainRenderer.alpha = 0.5;
}
return self.rainRenderer;
}
return nil;
}
I'm using one MKOverlay and then just reloading the tiles as needed. Otherwise there is quite a pronounced flicker. Here's that function which is triggered by the NSTimer to happen every 0.5 seconds.
- (void) updateRainFrame {
self.currentFrameIndex = (self.currentFrameIndex + 1) % self.timestamps.count;
if ((self.currentFrameIndex >= 0) && (self.timestamps.count > self.currentFrameIndex)) {
NSLog (@"self.currentFrameIndex = %lu", self.currentFrameIndex);
NSString *timestamp = self.timestamps[self.currentFrameIndex];
[self.overlay setTimestamp:timestamp];
[self.rainRenderer reloadData];
}
}
In that function I'm updating the "timestamp" in the overlay which is the time slot that contains all the tiles for that time. This way my overridden MKTileOverlay can then pass the correct path for the tiles. For example for loading from a file:
- (NSURL *)URLForTilePath:(MKTileOverlayPath)path {
return [self getWeatherTileFileURLForPath:path];
}
Or NSData stored in memory
- (void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *tileData, NSError *error))result
{
return [self getWeatherTileDataForPath:path];
}
But no matter which way I use I keep getting this spam and unfortunately there is no error or anything to point to why it is spamming out.
Also the tiles themselves are PNG files either 256x256 or 512x512 in pixel size.
I saw that this could be something to do with Metal but I'm assuming that's something that MapKit uses.
Very much welcome any thoughts to what could be causing this?
Hi, I am using Location Push Service Extension in my app but as soon as my app gets an update Location Extension fails to launch. From the console I can see OS is terminating this process. What could be the reason ? When user launches the app after update the extension starts to work as expected.
I have a Nissan Rogue 2021 and iPhone 14 Pro Max. Carplay was working fine until I decided to update to the new beta program and now my carplay does not seem to want to operate at all. I do the fixes online suggest in rebooting both systems, forgetting entirely and reconnecting. In the process of doing so, I can get the prompts to start with "Allow while unlocked?" But once selecting that I am unable to actually use the Carplay from the phone. It doesn't even give option to switch to it when I attempt to change audio output.
Hello,
I'm currently implementing code to track routes and determine if users have arrived at their destination using CLServiceSession, CLBackgroundActivitySession, and CLLocationUpdate.liveUpdates.
I want to obtain location data across all app states: foreground, background, and terminated.
I have two questions:
Background Location Indicator Issue: I'm using CLBackgroundActivitySession to get location updates in the background. Normally, the background location indicator (blue bar) doesn't appear at the top left of the screen for my app. However, when another app (e.g., LiveUpdatesSample) activates CLBackgroundActivitySession, my app's background location indicator suddenly becomes visible. Can you explain why this happens? or Can I Control showsBackgroundLocationIndicator in CLBackgroundActivitySession
Session Management: Is there a way to terminate all currently active CLBackgroundActivitySessions? I understand that when CLBackgroundActivitySession is activated and the app is terminated and then relaunched, a new CLBackgroundActivitySession needs to be created. In this case, are the previously created and running CLBackgroundActivitySessions automatically released when the app is relaunched?
Hi,
I am creating a Driving Behaviour Monitoring app in which I range beacons and I require location updates in foreground, background and in terminated state all the time.
I am using CLServiceSession with "Always Authorisation" to get location events. I create CLServiceSession object in the foreground and start monitoring driving and then re-create it when the app is relaunched after termination. Doing this works fine.
But sometimes when app is terminated and is not opened again, the app runs on its own even when the device is stationary ( I can see the app is using Location in the Control Centre) and after that Location updates are not received and I am not able to track the driving behaviour. I tried to add diagnostics to know the cause and found "Insufficiently In Use" and then "Service Session Required" in the diagnostics.
It would be of great help if the proper usage of CLServiceSession is provided.
Important Question: When does the CLServiceSession gets invalidated or destroyed that was created when the app was in foreground ? What happens to the CLServiceSession which was created in the foreground if the app is not opened for long duration, let's say a day or two?
Hi Team,
when our customers turn on bluetooth connectivity whether Apple creates a profile of the user or their locations and if it is used for any other purpose.
Could you please clarify this?
we are getting the below message in the Bluetooth permissions popup below the map "Information from Bluetooth devices can be used to determine your location and create a profile of you."
What is this profile? and what is the purpose of creating it while the user uses Bluetooth in ios app.
Topic:
App & System Services
SubTopic:
Maps & Location
I'm currently testing the CLMonitor API and have a question about CLServiceSession management.
When my app is relaunched from a terminated state in the background due to CLMonitor events, do I still need to create and maintain a CLServiceSession instance?
I'm wondering if CLServiceSession is necessary even when I don't need to continuously receive GPS updates through liveUpdates. Since CLMonitor can trigger app launches for region monitoring events without requiring constant location updates, I'm unclear about whether the CLServiceSession is still required in this scenario.
Any clarification on the proper implementation would be greatly appreciated.
Thanks!
As GeoCoder is now deprecated I am struggling to get the country only information from the new MKReverseGeocoding.
Maybe someone can guide me or give me direction? Or is this just not possible anymore?
let request = MKReverseGeocodingRequest(location: self.lastLocation ?? fallbackLocation)
request?.getMapItems { items, error in
guard let items = items else { return }
self.cityName = items.first?.addressRepresentations?.cityWithContext ?? ""
self.countryName = items.first?.addressRepresentations?.regionName ?? ""
}
I couldn't find anything here, sure you can get the full Address but I need single values to store so the user can search for (example City, Country)
In case the structure is always the same, let us say the country is always third part, sure I could split the string but it is not a reliable way to do this, at least for me.
Any help would be much appreciated.
I have a sample that stop working on IOS 26, using the latest XCode and IOS sdk, the onTapGesture event is no longer happening. Maybe this is no longer the way to drop pins on the map.
Also not working on the iPhone 17 sim or iPhone 16 max pro device upgrading to IOS 26
Thanks, any help
Sample:
import SwiftUI
import MapKit
import CoreLocation
import Foundation
struct Pin: Identifiable {
let id = UUID()
let coordinate: CLLocationCoordinate2D
}
struct ContentTestPinDropView: View {
@State private var pins: [Pin] = []
var body: some View {
MapReader { reader in
Map(selection: .constant(nil)) {
ForEach(pins) { pin in
Marker("Pin", coordinate: pin.coordinate)
}
}
.onTapGesture { screenPoint in
if let coordinate = reader.convert(screenPoint, from: .local) {
pins.append(Pin(coordinate: coordinate))
}
}
}
}
}
Hello,
We are a software and hardware development company for the forestry and environmental sectors. We have been based in Quebec (Canada) for over 30 years now. Our Canadian market covers Quebec, Ontario, and the Maritime provinces in the east. We are currently expanding across Canada and into the northern United States. We are on Android platforms with several map and data entry applications.
To ensure the success of our expansion, we aim to become part of the Apple family, which is why we are contacting you today.
We have developed our own GNSS receiver to increase the location accuracy of our users. It uses Bluetooth BLE to communicate with mobile devices and a high-precision GPS that transmits its position using the NMEA protocol. We would like this device to be compatible with an iPhone/iPad. We have developed a mock location application in MAUI (multi-platform). Based on our interpretation of your documentation, we understand that the concept of mock location does not exist at Apple. How can we ensure that our Bluetooth GNSS device is compatible with your iPhone/iPad devices and that they can use the position of the Bluetooth device rather than the internal GPS of your devices?
We are a reseller for Juniper Systems, and we know that they have an app on the App Store that has the same features as our product.
https://junipersys.com/index.php/support/article/14709
We look forward to your follow-up and recommendations.
Hello,
We are a software and hardware development company for the forestry and environmental sectors. We have been based in Quebec (Canada) for over 30 years now. Our Canadian market covers Quebec, Ontario, and the Maritime provinces in the east. We are currently expanding across Canada and into the northern United States. We are on Android platforms with several map and data entry applications.
To ensure the success of our expansion, we aim to become part of the Apple family, which is why we are contacting you today.
We have developed our own GNSS receiver to increase the location accuracy of our users. This device is called GSFGPS. It uses Bluetooth BLE to communicate with mobile devices and a high-precision GPS that transmits its position using the NMEA protocol. We would like this device to be compatible with an iPhone/iPad. We have developed a mock location application in MAUI (multi-platform). Based on our interpretation of your documentation, we understand that the concept of mock location does not exist at Apple. How can we ensure that our Bluetooth GNSS device is compatible with your iPhone/iPad devices and that they can use the position of the Bluetooth device rather than the internal GPS of your devices?
We are a reseller for Juniper Systems, and we know that they have an app on the App Store that has the same features as our product.
https://junipersys.com/index.php/support/article/14709
We look forward to your follow-up and recommendations.
I want to use MapKit with App Intents, but the map does not show up.(See attached image)
Can anyone help me solve this?
import SwiftUI
import MapKit
struct ContentView: View {
@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 37.334_900,
longitude: -122.009_020),
latitudinalMeters: 750,
longitudinalMeters: 750
)
var body: some View {
VStack {
Map(coordinateRegion: $region).frame(width:300, height:300)
.disabled(true)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
import AppIntents
import SwiftUI
import MapKit
struct test20220727bAppIntentsExtension: AppIntent {
static var title: LocalizedStringResource = "test20220727bAppIntentsExtension"
func perform() async throws -> some IntentResult {
return .result(value: "aaa", view: ContentView())
}
}
struct testShortcuts:AppShortcutsProvider{
@available(iOS 16.0, *)
static var appShortcuts: [AppShortcut]{
AppShortcut(
intent: test20220727bAppIntentsExtension(),
phrases: ["test20220727bAppIntentsExtension" ]
)
}
}
Topic:
App & System Services
SubTopic:
Maps & Location
Tags:
App Intents
wwdc2022-10032
wwdc2022-10170
I set the location permission to Always but it changes back to “when shared” after a few days. Is this a bug?
This is my first post here. Please guide me, if I need to provide more information to answer this post.
I write a simple application, that monitors GPS position (location). I followed Apple documentation for LiveUpdates: https://developer.apple.com/documentation/corelocation/supporting-live-updates-in-swiftui-and-mac-catalyst-apps
My app can monitor location in foreground, background or it can completely stop monitoring location. Background location, if needed, is switched on when application changes scenePhase to .background. But it is in the foreground, that memory leaks occur (according to Instruments/Leaks. Namely Leaks points to the instruction:
let updates = CLLocationUpdate.liveUpdates()
every time I start location and then stop it, by setting updatesStarted to false.
Leaks claims there are 5x leaks there:
Malloc 32 Bytes 1 0x6000002c1d00 32 Bytes libswiftDispatch.dylib OS_dispatch_queue.init(label:qos:attributes:autoreleaseFrequency:target:)
CLDispatchSilo 1 0x60000269e700 96 Bytes CoreLocation 0x184525c64
Malloc 48 Bytes 1 0x600000c8f2d0 48 Bytes Foundation +[NSString stringWithUTF8String:]
NSMutableSet 1 0x6000002c4240 32 Bytes LocationSupport 0x18baa65d4
dispatch_queue_t (serial) 1 0x600002c69c80 128 Bytes libswiftDispatch.dylib OS_dispatch_queue.init(label:qos:attributes:autoreleaseFrequency:target:)
I tried [weak self] in Task, but it doesn't solve the leaks problem and causes other issues, so I dropped it. Anyway, Apple doesn't use it either.
Just in case this is my function, which has been slightly changed comparing to Apple example, to suit my needs:
func startLocationUpdates() {
Task() {
do {
self.updatesStarted = true
let updates = CLLocationUpdate.liveUpdates()
for try await update in updates {
// End location updates by breaking out of the loop.
if !self.updatesStarted {
self.location = nil
self.mapLocation = nil
self.track.removeAll()
break
}
if let loc = update.location {
let locationCoordinate = loc.coordinate
let location2D = CLLocationCoordinate2D(latitude: locationCoordinate.latitude, longitude: locationCoordinate.longitude)
self.location = location2D
if self.isAnchor {
if #available(iOS 18.0, *) {
if !update.stationary {
self.track.append(location2D)
}
} else {
// Fallback on earlier versions
if !update.isStationary {
self.track.append(location2D)
}
}
}
}
}
} catch {
//
}
return
}
}
Can anyone help me locating these leaks?
The code below using LookAroundPreview works fine on iOS (showing the preview image with a button saying "Look Around" at the top to enter full screen with navigation), but on macOS (15.3) there is no button and no way to navigate the view. Is this a bug or is there something I need to do differently on macOS? I have also tried using AppKit with MKLookAroundViewController and I don't seem get the button to launch full screen there either.
import SwiftUI
import MapKit
struct ContentView: View {
var body: some View {
LookAroundPreviewView(coordinate: CLLocationCoordinate2D(latitude: 37.33182, longitude: -122.03118))
.frame(width: 300, height: 200)
}
}
struct LookAroundPreviewView: View {
let coordinate: CLLocationCoordinate2D
@State private var scene: MKLookAroundScene?
@State private var errorMessage: String?
var body: some View {
Group {
if scene != nil {
LookAroundPreview(scene: $scene, allowsNavigation: true)
} else if let errorMessage = errorMessage {
Text("Error: \(errorMessage)")
.foregroundColor(.red)
} else {
ProgressView("Loading Look Around Preview...")
}
}
.task {
do {
let request = MKLookAroundSceneRequest(coordinate: coordinate)
let fetchedScene = try await request.scene
scene = fetchedScene
} catch {
errorMessage = error.localizedDescription
print("Error loading Look Around scene: \(error)")
}
}
}
}
We (at the NYC MTA) are building a new subway/bus app and diving deep into location tracking on iOS. We’re encountering an issue with how Core Location functions in the subway, specifically regarding how long it takes to update a passenger’s location as they travel from station to station.
As an example, please see this video: https://drive.google.com/file/d/1yaddkjyPEETvTEmClPAJ2wks8b-_whqB/view?usp=sharing
The red dot is set manually (via a tap gesture) and represents the ground truth of where the phone actually is at that moment. The most critical moment to observe is when the train physically arrives at a station (i.e., when I can see the platform outside my window). At this moment, I update the red dot to the center of the station on the map. Similarly, I adjust the red dot when the train departs a station, placing it just outside the station in the direction of travel.
The trip shown is from Rector St to 14 St. All times are in EST.
I’d like to investigate this issue further since providing a seamless underground location experience is crucial for customers. As a point of comparison, Android phones exhibit near-perfect behavior, proving that this is technically feasible. We want to ensure the iOS experience is just as smooth.
Note: I have had issues with CMAltimeter since whats seems to have been a major undocumented modification since iOS 17.4.
So I'm using the CMAltimeter absolute locations delivery.
Sometimes, the altimeter seems to be in an uncalibrated mode and therefore, no altitude delivery happens.
Is there a way to be inform of such state? Currently, it just doesn't work and I can't inform the user about this. They just think the app is broken
What message should I give to the users to accelerate the calibration such that the CMAltimeter will work again?
Also, users have reported that the CMAltimeter can temporarily stop delivering altitude updates, even though it should.
So I guess my question resumes to this:
Whats the best practice to handle an uncalibrated CMAltimeter?
Thanks!
I'm currently developing an app with mapkit which I may submit to the Swift Student Challenge. So anyways, the app will be used completely offline. I was wondering if there was any way to include very low resolution map tiles with the app files. That way, the app never needs wifi. However, I'm not sure if this is possible, especially since the map would need to be under 20 mb. Thanks.
Topic:
App & System Services
SubTopic:
Maps & Location
When I quit the app from the background task list, CLLocationUpdate.liveUpdates does not resume properly and start location updates. However, if I kill the app directly, it can recover and start location updates.
Topic:
App & System Services
SubTopic:
Maps & Location