Reputation: 1496
I have a very simple iOS App (Swift 5 and XCode 12.3) here. It just has two buttons to start and stop a CLLocationManager. Everything seems to work fine while the App is in the foreground. The problem is I would like to continue receiving updates even if the App is not in the foreground. I activated the checkmark "Background Modes", "Location updates". But it does not work. As soon as I put the application to the background (swiping up from the bottom of my iPhone XR) it crashes with the following error:
libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: mutex lock failed: Invalid argument
terminating with uncaught exception of type std::__1::system_error: mutex lock failed: Invalid argument
I also provided the keys for "Privacy - Location Always and When In Use Usage Description" and "Privacy - Location When In Use Usage Description" in Info.plist. The code for my view controller is as follows:
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
var locationManager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.showsBackgroundLocationIndicator = true
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.activityType = .other
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.distanceFilter = kCLDistanceFilterNone
}
@IBAction func play(_ sender: UIButton) {
locationManager.requestAlwaysAuthorization()
self.locationManager.startUpdatingLocation()
}
@IBAction func stop(_ sender: UIButton) {
locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
locations.forEach { (location) in
print(location)
}
print("\n")
}
}
The stack trace looks like and reports a SIGABRT:
libsystem_kernel.dylib`__pthread_kill:
0x1c153240c <+0>: mov x16, #0x148
0x1c1532410 <+4>: svc #0x80
-> 0x1c1532414 <+8>: b.lo 0x1c1532434 ; <+40>
0x1c1532418 <+12>: pacibsp
0x1c153241c <+16>: stp x29, x30, [sp, #-0x10]!
0x1c1532420 <+20>: mov x29, sp
0x1c1532424 <+24>: bl 0x1c150ec20 ; cerror_nocancel
0x1c1532428 <+28>: mov sp, x29
0x1c153242c <+32>: ldp x29, x30, [sp], #0x10
0x1c1532430 <+36>: retab
0x1c1532434 <+40>: ret
Sometimes it also crashes with EXC_BAD_ACCESS and the following lengthy stack trace:
libobjc.A.dylib`objc_msgSend:
0x1a85f40e0 <+0>: cmp x0, #0x0 ; =0x0
0x1a85f40e4 <+4>: b.le 0x1a85f41a4 ; <+196>
0x1a85f40e8 <+8>: ldr x13, [x0]
0x1a85f40ec <+12>: and x16, x13, #0x7ffffffffffff8
0x1a85f40f0 <+16>: xpacd x16
0x1a85f40f4 <+20>: mov x15, x16
-> 0x1a85f40f8 <+24>: ldr x11, [x16, #0x10]
0x1a85f40fc <+28>: tbnz w11, #0x0, 0x1a85f4158 ; <+120>
0x1a85f4100 <+32>: and x10, x11, #0xffffffffffff
0x1a85f4104 <+36>: eor x12, x1, x1, lsr #7
0x1a85f4108 <+40>: and x12, x12, x11, lsr #48
0x1a85f410c <+44>: add x13, x10, x12, lsl #4
0x1a85f4110 <+48>: ldp x17, x9, [x13], #-0x10
0x1a85f4114 <+52>: cmp x9, x1
0x1a85f4118 <+56>: b.ne 0x1a85f4128 ; <+72>
0x1a85f411c <+60>: eor x10, x10, x1
0x1a85f4120 <+64>: eor x10, x10, x16
0x1a85f4124 <+68>: brab x17, x10
0x1a85f4128 <+72>: cbz x9, 0x1a85f44e0 ; _objc_msgSend_uncached
0x1a85f412c <+76>: cmp x13, x10
0x1a85f4130 <+80>: b.hs 0x1a85f4110 ; <+48>
0x1a85f4134 <+84>: add x13, x10, x11, lsr #44
0x1a85f4138 <+88>: add x12, x10, x12, lsl #4
0x1a85f413c <+92>: ldp x17, x9, [x13], #-0x10
0x1a85f4140 <+96>: cmp x9, x1
0x1a85f4144 <+100>: b.eq 0x1a85f411c ; <+60>
0x1a85f4148 <+104>: cmp x9, #0x0 ; =0x0
0x1a85f414c <+108>: ccmp x13, x12, #0x0, ne
0x1a85f4150 <+112>: b.hi 0x1a85f413c ; <+92>
0x1a85f4154 <+116>: b 0x1a85f44e0 ; _objc_msgSend_uncached
0x1a85f4158 <+120>: and x10, x11, #0x7ffffffffffffe
0x1a85f415c <+124>: autdb x10, x16
0x1a85f4160 <+128>: adrp x9, 235816
0x1a85f4164 <+132>: add x9, x9, #0x4fa ; =0x4fa
0x1a85f4168 <+136>: sub x12, x1, x9
0x1a85f416c <+140>: lsr x17, x11, #55
0x1a85f4170 <+144>: lsr w9, w12, w17
0x1a85f4174 <+148>: lsr x17, x11, #60
0x1a85f4178 <+152>: mov x11, #0x7fff
0x1a85f417c <+156>: lsr x11, x11, x17
0x1a85f4180 <+160>: and x9, x9, x11
0x1a85f4184 <+164>: ldr x17, [x10, x9, lsl #3]
0x1a85f4188 <+168>: cmp x12, w17, uxtw
0x1a85f418c <+172>: b.ne 0x1a85f4198 ; <+184>
0x1a85f4190 <+176>: sub x17, x16, x17, lsr #32
0x1a85f4194 <+180>: br x17
0x1a85f4198 <+184>: ldursw x9, [x10, #-0x8]
0x1a85f419c <+188>: add x16, x16, x9
0x1a85f41a0 <+192>: b 0x1a85f40f8 ; <+24>
0x1a85f41a4 <+196>: b.eq 0x1a85f41c8 ; <+232>
0x1a85f41a8 <+200>: and x10, x0, #0x7
0x1a85f41ac <+204>: asr x11, x0, #55
0x1a85f41b0 <+208>: cmp x10, #0x7 ; =0x7
0x1a85f41b4 <+212>: csel x12, x11, x10, eq
0x1a85f41b8 <+216>: adrp x10, 319023
0x1a85f41bc <+220>: add x10, x10, #0x820 ; =0x820
0x1a85f41c0 <+224>: ldr x16, [x10, x12, lsl #3]
0x1a85f41c4 <+228>: b 0x1a85f40f4 ; <+20>
0x1a85f41c8 <+232>: mov x1, #0x0
0x1a85f41cc <+236>: movi d0, #0000000000000000
0x1a85f41d0 <+240>: movi d1, #0000000000000000
0x1a85f41d4 <+244>: movi d2, #0000000000000000
0x1a85f41d8 <+248>: movi d3, #0000000000000000
0x1a85f41dc <+252>: ret
I have no clue what these traces mean and I did not found a conclusive explanation on the Web. Can someone provide me with some insights (or really just the most basic example of running CLLocationManager in the background? Thanks.
Upvotes: 0
Views: 466
Reputation: 1496
Ok. I've found the problem after some additional experiments. Everything actually works as advertised. However you should never use print
calls in a function while testing background modes on a physical device. The example I posted above does work as long as a simulator is used. But the print
statements do crash on a real device. I guess, the reason is that the real device has no terminal attached.
Upvotes: 1