I'm using Xcode Version 8.3.3 with Swift 3. My phone is running iOS 10.3.2.
This issue is happening while I'm out using the app.
I have an intermittent error occurring in my phone app. Once data has been uploaded to a web service, the following code is called to update the object in Core Data. I'm not seeing why the object is causing an error:
func uploadedMarker(_ oldRouteId: Int16, stepId: Double, newRouteId: Int16) {
do {
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "HoldMarkers")
let routePredicate = NSPredicate(format: "routeId = %i", oldRouteId)
let stepPredicate = NSPredicate(format: "stepId = %f", stepId)
request.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [routePredicate, stepPredicate])
request.returnsObjectsAsFaults = false
let markers = try self.context.fetch(request) as! [HoldMarkers]
if markers.count > 0 {
let marker = markers.first!
marker.uploaded = true
marker.routeId = newRouteId
do {
try marker.validateForUpdate()
self.appDelegate.saveContext()
}
catch {
let nserror = error as NSError
NSLog("uploadedMarker - Core Data Error - Updating HoldMarkers :\(nserror), \(nserror.userInfo)")
}
}
}
catch {
let nserror = error as NSError
NSLog("uploadedMarker - Core Data Error - Fetching HoldMarkers :\(nserror), \(nserror.userInfo)")
}
}
Context is defined as:
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
Like I said, this is an intermittent error:
-[MKPolyline _genericValueForKey:withIndex:flags:]: unrecognized selector sent to instance 0x17049a860
1 CoreFoundation __exceptionPreprocess + 124
2 libobjc.A.dylib objc_exception_throw + 52
3 CoreFoundation -[NSObject(NSObject) doesNotRecognizeSelector:] + 136
4 CoreFoundation ___forwarding___ + 912
5 CoreFoundation __forwarding_prep_0___ + 88
6 CoreData _PF_Handler_Public_GetProperty + 244
7 Foundation -[NSFunctionExpression expressionValueWithObject:context:] + 736
8 Foundation -[NSComparisonPredicate evaluateWithObject:substitutionVariables:] + 224
9 Foundation -[NSCompoundPredicateOperator evaluatePredicates:withObject:substitutionVariables:] + 440
10 Foundation -[NSCompoundPredicate evaluateWithObject:substitutionVariables:] + 272
11 CoreData -[NSManagedObjectContext executeFetchRequest:error:] + 2796
12 Parks-Tracker RouteViewController.uploadedMarker(Int16, stepId : Double, newRouteId : Int16) -> () (RouteViewController.swift:1371)
13 Parks-Tracker #objc RouteViewController.uploadedMarker(Int16, stepId : Double, newRouteId : Int16) -> () (RouteViewController.swift:0)
14 Parks-Tracker RouteViewController.(updateRoute(Double, longitude : Double, timestamp : Date, routeId : Int16, stepId : Double, segment : Int16, complete : Bool) -> ()).(closure #2) (RouteViewController.swift:1114)
15 Parks-Tracker thunk for #callee_owned (#owned NSDictionary, #owned NSError?, #unowned Int16, #unowned Double) -> () (RouteViewController.swift:0)
16 Parks-Tracker thunk for #callee_unowned #convention(block) (#unowned NSDictionary, #unowned NSError?, #unowned Int16, #unowned Double) -> () (RouteViewController.swift:0)
17 Parks-Tracker RouteViewController.(callRouteUpdate(Double, longitude : Double, complete : Bool, routeId : Int16, stepId : Double, segment : Int16, conditionDescription : String, markerImage : NSData?, routeName : String, destinationId : Int16, completion : (NSDictionary, NSError?, Int16, Double) -> ()) -> ()).(closure #1) (RouteViewController.swift:1262)
18 Parks-Tracker thunk for #callee_owned (#owned Data?, #owned URLResponse?, #owned Error?) -> () (LoginViewController.swift:0)
Related
When I try to fetch user data from Firebase a crash occurs for some users, I can't reproduce this crash myself but I do have the following crash log:
0 Ski Tracker 0x77bf0 closure #1 in HistoryPresenter.downloadHistory(completionHandler:) + 4340857840 (HistoryPresenter.swift:4340857840)
1 Ski Tracker 0x86c8 closure #1 in FetchFromDatabase.fetchUserHistoryFromDatabase(uid:completionHandler:) + 4340401864 (<compiler-generated>:4340401864)
2 Ski Tracker 0x8604 thunk for #escaping #callee_guaranteed (#guaranteed FIRDataSnapshot) -> () + 4340401668 (<compiler-generated>:4340401668)
3 FirebaseDatabase 0x1df28 __92-[FIRDatabaseQuery observeSingleEventOfType:andPreviousSiblingKeyWithBlock:withCancelBlock:]_block_invoke + 120
4 FirebaseDatabase 0xbf94 __43-[FChildEventRegistration fireEvent:queue:]_block_invoke.11 + 80
5 libdispatch.dylib 0x24b4 _dispatch_call_block_and_release + 32
6 libdispatch.dylib 0x3fdc _dispatch_client_callout + 20
7 libdispatch.dylib 0x127f4 _dispatch_main_queue_drain + 928
8 libdispatch.dylib 0x12444 _dispatch_main_queue_callback_4CF + 44
9 CoreFoundation 0x9a6f8 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16
10 CoreFoundation 0x7c058 __CFRunLoopRun + 2036
11 CoreFoundation 0x80ed4 CFRunLoopRunSpecific + 612
12 GraphicsServices 0x1368 GSEventRunModal + 164
13 UIKitCore 0x3a23d0 -[UIApplication _run] + 888
14 UIKitCore 0x3a2034 UIApplicationMain + 340
15 libswiftUIKit.dylib 0x35308 UIApplicationMain(_:_:_:_:) + 104
16 Ski Tracker 0x7160 main + 4340396384 (FriendView.swift:4340396384)
17 ??? 0x1f6938960 (Missing)
If I understand the crash log correctly the code which is causing the crash is within the fetchUserHistoryFromDatabase function:
func fetchUserHistoryFromDatabase(uid : String, completionHandler: #escaping([String : Any]?) -> Void ) {
ref?.child("users").child(uid).child("runData").observeSingleEvent(of: .value, with: { snapshot in
guard let result = snapshot.value as? [String:Any] else {
print("Error no rundata")
completionHandler(nil)
return
}
completionHandler(result)
})
}
This function is called from downloadHistory where potential nil values are handled:
private func downloadHistory(completionHandler: #escaping () -> Void) {
if let id = Auth.auth().currentUser?.uid {
FetchFromDatabase().fetchUserHistoryFromDatabase(uid : id, completionHandler: { [weak self] dict in
if dict != nil {
for run in dict! {
self?.determineTimeStamp(run : run)
}
if !(self!.tempDict.isEmpty) {
let sortedDict = self?.tempDict.keys.sorted(by: { $0 > $1 } )
self?.convertDictToArray(sortedDict: sortedDict!)
}
}
completionHandler()
}
)}
}
Any help here is greatly appreciated.
Remove the force unwrapping from your code. Every ! is an invitation for a crash.
private func downloadHistory(completionHandler: #escaping () -> Void) {
if let id = Auth.auth().currentUser?.uid {
FetchFromDatabase().fetchUserHistoryFromDatabase(uid : id, completionHandler: { [weak self] dict in
guard let self = self else {
completion()
return
}
if let dict = dict {
for run in dict {
self.determineTimeStamp(run : run)
}
if !self.tempDict.isEmpty {
let sortedDict = self.tempDict.keys.sorted(by: { $0 > $1 } )
self.convertDictToArray(sortedDict: sortedDict)
}
}
completionHandler()
}
)}
}
I notice a self! there dangerous, because a user could leave the calling context of the function and since the closure has a capture list of weak self, it should return nil but you are forcing it
try this
private func downloadHistory(completionHandler: #escaping () -> Void) {
if let id = Auth.auth().currentUser?.uid {
FetchFromDatabase().fetchUserHistoryFromDatabase(uid : id, completionHandler: { [weak self] dict in
guard let self = self else { completionHandler()
return }
if let safeDict = dict {
for run in dict {
self.determineTimeStamp(run : run)
}
if (self.tempDict.isEmpty) {
let sortedDict = self.tempDict.keys.sorted(by: { $0 > $1 } )
self.convertDictToArray(sortedDict: sortedDict)
}
}
completionHandler()
}
)}
}
I have an audio app and have implemented CarPlay, I've followed this guide to add CarPlay support: https://blog.fethica.com/add-carplay-support-to-swiftradio/#
The app uses the com.apple.developer.playable-content entitlement and Media Player framework, which as far as I know, has been the only way to add CarPlay to audio apps on iOS 13 and below, but is still backwards compatible with iOS 14 (despite there being a new carplay audio framework for iOS 14). All my CarPlay logic is written in an extension of my main AppDelegate (could this be problematic?)
In the simulator, everything has been working fine and the audio plays in the external simulated car display. But my team tested the app in a real car and the application crashes immediately when opened from the car display.
I have the crash log here when tested on iPhone 11 Pro on iOS 14.4:
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x00000001b88d13cc
Termination Signal: Trace/BPT trap: 5
Termination Reason: Namespace SIGNAL, Code 0x5
Terminating Process: exc handler [27455]
Triggered by Thread: 5
Thread 0 name:
Thread 0:
0 libsystem_kernel.dylib 0x00000001d6aa6f5c __ulock_wait + 8
1 libdispatch.dylib 0x00000001a8746794 _dlock_wait + 56 (lock.c:326)
2 libdispatch.dylib 0x00000001a87466c0 _dispatch_once_wait + 124 (lock.c:382)
3 UIKitCore 0x00000001ab1080f8 -[_UIApplicationConfigurationLoader _loadInitializationContext] + 152 (once.h:84)
4 UIKitCore 0x00000001ab108444 -[_UIApplicationConfigurationLoader applicationInitializationContext] + 32 (_UIApplicationConfigurationLoader.m:161)
5 UIKitCore 0x00000001ab0ef05c -[_UIScreenInitialDisplayConfigurationLoader initialDisplayContext] + 180 (UIScreen.m:371)
6 UIKitCore 0x00000001ab0ef348 +[UIScreen initialize] + 128 (UIScreen.m:626)
7 libobjc.A.dylib 0x00000001bdb67c58 CALLING_SOME_+initialize_METHOD + 24 (objc-initialize.mm:384)
8 libobjc.A.dylib 0x00000001bdb6e318 initializeNonMetaClass + 716 (objc-initialize.mm:554)
9 libobjc.A.dylib 0x00000001bdb6f910 initializeAndMaybeRelock(objc_class*, objc_object*, mutex_tt<false>&, bool) + 280 (objc-runtime-new.mm:2221)
10 libobjc.A.dylib 0x00000001bdb7e498 lookUpImpOrForward + 956 (objc-runtime-new.mm:2237)
11 libobjc.A.dylib 0x00000001bdb68524 _objc_msgSend_uncached + 68
12 UIKitCore 0x00000001ab33ef48 -[_UIRemoteKeyboards keyboardWindow] + 52 (_UIRemoteKeyboards.m:2036)
13 UIKitCore 0x00000001ab33cf6c -[_UIRemoteKeyboards allowedToShowKeyboard] + 96 (_UIRemoteKeyboards.m:1588)
14 UIKitCore 0x00000001ab33bda8 -[_UIRemoteKeyboards checkConnection] + 64 (_UIRemoteKeyboards.m:1315)
15 UIKitCore 0x00000001ab338b60 -[_UIRemoteKeyboards init] + 156 (_UIRemoteKeyboards.m:797)
16 UIKitCore 0x00000001ab338ab4 __43+[_UIRemoteKeyboards sharedRemoteKeyboards]_block_invoke + 20 (_UIRemoteKeyboards.m:785)
17 libdispatch.dylib 0x00000001a8745db0 _dispatch_client_callout + 20 (object.m:559)
18 libdispatch.dylib 0x00000001a87475c8 _dispatch_once_callout + 32 (once.c:52)
19 UIKitCore 0x00000001ab338a9c +[_UIRemoteKeyboards sharedRemoteKeyboards] + 176 (once.h:84)
20 UIKitCore 0x00000001ab50ccac _UIApplicationMainPreparations + 1348 (UIApplication.m:4644)
21 UIKitCore 0x00000001ab50c740 UIApplicationMain + 140 (UIApplication.m:4704)
22 MyAppName 0x000000010458fb04 main + 68 (UITextField+Extension.swift:22)
23 libdyld.dylib 0x00000001a87866b0 start + 4
Thread 1:
0 libsystem_pthread.dylib 0x00000001f4608764 start_wqthread + 0
Thread 2:
0 libsystem_pthread.dylib 0x00000001f4608764 start_wqthread + 0
Thread 3 name:
Thread 3:
0 libsystem_kernel.dylib 0x00000001d6a822d0 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x00000001d6a81660 mach_msg + 76 (mach_msg.c:103)
2 libdispatch.dylib 0x00000001a875e888 _dispatch_mach_send_and_wait_for_reply + 528 (mach.c:812)
3 libdispatch.dylib 0x00000001a875ec24 dispatch_mach_send_with_result_and_wait_for_reply + 56 (mach.c:1998)
4 libxpc.dylib 0x00000001f4626e68 xpc_connection_send_message_with_reply_sync + 240 (connection.c:848)
5 BoardServices 0x00000001c2599958 -[BSXPCServiceConnectionMessage _sendSynchronously:] + 332 (BSXPCServiceConnectionMessage.m:129)
6 BoardServices 0x00000001c259a2cc -[BSXPCServiceConnectionMessage sendSynchronouslyWithError:] + 256 (BSXPCServiceConnectionMessage.m:182)
7 BoardServices 0x00000001c2584afc __71+[BSXPCServiceConnectionProxy createImplementationOfProtocol:forClass:]_block_invoke + 824 (BSXPCServiceConnectionProxy.m:274)
8 UIKitServices 0x00000001acb7fc6c -[UISApplicationSupportClient applicationInitializationContextWithParameters:] + 272 (UISApplicationSupportClient.m:77)
9 UIKitCore 0x00000001ab108278 __63-[_UIApplicationConfigurationLoader _loadInitializationContext]_block_invoke_2 + 228 (_UIApplicationConfigurationLoader.m:135)
10 UIKitCore 0x00000001ab108188 __UIAPPLICATION_IS_LOADING_INITIALIZATION_INFO_FROM_THE_SYSTEM__ + 28 (_UIApplicationConfigurationLoader.m:30)
11 UIKitCore 0x00000001ab108160 __63-[_UIApplicationConfigurationLoader _loadInitializationContext]_block_invoke + 100 (_UIApplicationConfigurationLoader.m:106)
12 libdispatch.dylib 0x00000001a8745db0 _dispatch_client_callout + 20 (object.m:559)
13 libdispatch.dylib 0x00000001a87475c8 _dispatch_once_callout + 32 (once.c:52)
14 UIKitCore 0x00000001ab1080f8 -[_UIApplicationConfigurationLoader _loadInitializationContext] + 152 (once.h:84)
15 UIKitCore 0x00000001ab108408 __70-[_UIApplicationConfigurationLoader startPreloadInitializationContext]_block_invoke + 28 (_UIApplicationConfigurationLoader.m:154)
16 libdispatch.dylib 0x00000001a874424c _dispatch_call_block_and_release + 32 (init.c:1454)
17 libdispatch.dylib 0x00000001a8745db0 _dispatch_client_callout + 20 (object.m:559)
18 libdispatch.dylib 0x00000001a8756a68 _dispatch_root_queue_drain + 656 (inline_internal.h:2548)
19 libdispatch.dylib 0x00000001a8757120 _dispatch_worker_thread2 + 116 (queue.c:6777)
20 libsystem_pthread.dylib 0x00000001f46017d8 _pthread_wqthread + 216 (pthread.c:2223)
21 libsystem_pthread.dylib 0x00000001f460876c start_wqthread + 8
Thread 4:
0 libsystem_pthread.dylib 0x00000001f4608764 start_wqthread + 0
Thread 5 name:
Thread 5 Crashed:
0 FrontBoardServices 0x00000001b88d13cc -[FBSSceneParameters initWithSpecification:] + 228 (FBSSceneParameters.m:34)
1 FrontBoardServices 0x00000001b88d1320 -[FBSSceneParameters initWithSpecification:] + 56 (FBSSceneParameters.m:34)
2 FrontBoardServices 0x00000001b88d1dd8 -[FBSSceneParameters initWithXPCDictionary:] + 128 (FBSSceneParameters.m:150)
3 BaseBoard 0x00000001ad165af4 _BSXPCDecodeObject + 1892 (BSXPCCoder.m:583)
4 BaseBoard 0x00000001ad1639c0 _BSXPCDecodeObjectForKey + 268 (BSXPCCoder.m:459)
5 BoardServices 0x00000001c2585f30 +[BSXPCServiceConnectionProxy decodeArguments:outArgs:fromMessage:forConnection:] + 1608 (BSXPCServiceConnectionProxy.m:592)
6 BoardServices 0x00000001c2583ab0 -[BSXPCServiceConnectionProxy invokeMessage:onTarget:] + 276 (BSXPCServiceConnectionProxy.m:342)
7 BoardServices 0x00000001c258a994 __63-[BSXPCServiceConnectionEventHandler connection:handleMessage:]_block_invoke + 536 (BSXPCServiceConnectionEventHandler.m:261)
8 BoardServices 0x00000001c25a0284 BSXPCServiceConnectionExecuteCallOut + 316 (BSXPCServiceConnection.m:1049)
9 BoardServices 0x00000001c258a708 -[BSXPCServiceConnectionEventHandler connection:handleMessage:] + 172 (BSXPCServiceConnectionEventHandler.m:250)
10 BoardServices 0x00000001c259f668 -[BSXPCServiceConnection _connection_handleMessage:fromPeer:withHandoff:] + 572 (BSXPCServiceConnection.m:834)
11 libdispatch.dylib 0x00000001a874424c _dispatch_call_block_and_release + 32 (init.c:1454)
12 libdispatch.dylib 0x00000001a8745db0 _dispatch_client_callout + 20 (object.m:559)
13 libdispatch.dylib 0x00000001a874d10c _dispatch_lane_serial_drain + 580 (inline_internal.h:2548)
14 libdispatch.dylib 0x00000001a874dc90 _dispatch_lane_invoke + 460 (queue.c:3862)
15 libdispatch.dylib 0x00000001a874cfd8 _dispatch_lane_serial_drain + 272 (inline_internal.h:2589)
16 libdispatch.dylib 0x00000001a874dc90 _dispatch_lane_invoke + 460 (queue.c:3862)
17 libdispatch.dylib 0x00000001a8757d78 _dispatch_workloop_worker_thread + 708 (queue.c:6601)
18 libsystem_pthread.dylib 0x00000001f4601814 _pthread_wqthread + 276 (pthread.c:2210)
19 libsystem_pthread.dylib 0x00000001f460876c start_wqthread + 8
Thread 6 name:
Thread 6:
0 libsystem_kernel.dylib 0x00000001d6a822d0 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x00000001d6a81660 mach_msg + 76 (mach_msg.c:103)
2 IOKit 0x00000001b3b68340 io_hideventsystem_copy_property + 172 (IOHIDEventSystemMIGUser.c:3056)
3 IOKit 0x00000001b3b22c60 IOHIDEventSystemClientCopyProperty + 128 (IOHIDEventSystemClient.c:1097)
4 IOKit 0x00000001b3b22354 __IOHIDEventSystemClientRefresh + 1148 (IOHIDEventSystemClient.c:539)
5 IOKit 0x00000001b3b230cc IOHIDEventSystemClientCreateWithType + 856 (IOHIDEventSystemClient.c:749)
6 BackBoardServices 0x00000001ac0dda88 ___getHIDEventSystemClient_block_invoke + 288 (BKSHIDEvent.m:93)
7 libdispatch.dylib 0x00000001a8745db0 _dispatch_client_callout + 20 (object.m:559)
8 libdispatch.dylib 0x00000001a87475c8 _dispatch_once_callout + 32 (once.c:52)
9 BackBoardServices 0x00000001ac0dd964 BKSHIDEventRegisterEventCallbackOnRunLoop + 152 (once.h:84)
10 UIKitCore 0x00000001ab5babe4 -[UIEventFetcher threadMain] + 416 (UIEventFetcher.m:720)
11 Foundation 0x00000001a9ee7a34 __NSThread__start__ + 864 (NSThread.m:724)
12 libsystem_pthread.dylib 0x00000001f45ffcb0 _pthread_start + 320 (pthread.c:881)
13 libsystem_pthread.dylib 0x00000001f4608778 thread_start + 8
Thread 7:
0 libsystem_pthread.dylib 0x00000001f4608764 start_wqthread + 0
Thread 5 crashed with ARM Thread State (64-bit):
x0: 0x000000020ba16880 x1: 0x000000020ba16880 x2: 0x0000000000000000 x3: 0x00000000000008fd
x4: 0x0000000000000000 x5: 0x00000001bdb9873e x6: 0x000000000000006e x7: 0x0000000000000fb0
x8: 0x85f836c8121c001f x9: 0x85f836c8121c001f x10: 0x0000000000005403 x11: 0x0000000281a71540
x12: 0x00000000000000aa x13: 0x0000000000000001 x14: 0x00000000000000ac x15: 0x0000000000000182
x16: 0x00000002c6d90f88 x17: 0x0000000208ac3dc8 x18: 0x0000000000000000 x19: 0x0000000000000000
x20: 0x0000000281472eb0 x21: 0x0000000000000000 x22: 0x0000000000000000 x23: 0x00000001f75f31f5
x24: 0x000000020ba160d8 x25: 0x0000000000000000 x26: 0x00000001f7ff3288 x27: 0x000000020ba160b0
x28: 0x0000000000000000 fp: 0x000000016bb2e130 lr: 0x86106081b88d1320
sp: 0x000000016bb2e100 pc: 0x00000001b88d13cc cpsr: 0x60000000
esr: 0xf2000000 Address size fault
What could be causing the app to crash in a real car but work fine in the simulator? Here is part of my AppDelegate where I call a function to setup carplay:
import UIKit
import AVFoundation
import AVKit
import GoogleInteractiveMediaAds
import MediaPlayer
import GoogleMobileAds
import UserNotifications
import WebKit
import SafariServices
import Hero
import Firebase
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
static let reachable = "Reachable"
static let unReachable = "UnReachable"
let reachability = try! Reachability()
var iOSStream: String?
var preRolladUrl: String?
var window: UIWindow?
var adType: String?
var adServer: String?
var adFeed: String?
var miniPlayer: PlayerPopupControlViewController?
var selectedStation: Players!
// CarPlay
var playableContentManager: MPPlayableContentManager?
let carplayPlaylist = CarPlayPlaylist()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UINavigationBar.appearance().barTintColor = UIColor.black
UINavigationBar.appearance().tintColor = UIColor.black
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
UINavigationBar.appearance().isTranslucent = false
if UserDefaults.standard.object(forKey: UserDefaultsConstants.resumeRadioInBackground) == nil {
UserDefaults.standard.set(true, forKey: UserDefaultsConstants.resumeRadioInBackground)
UserDefaults.standard.synchronize()
}
self.setupBaseURL()
// Override point for customization after application launch.
self.startObservingReachability()
UIApplication.shared.beginReceivingRemoteControlEvents()
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
AppLogger.error(error)
}
UNUserNotificationCenter.current().delegate = self
UserDefaults.standard.set(false, forKey: UserDefaultsConstants.isMiniPlayerDisplayed)
UserDefaults.standard.synchronize()
SettingsDataManager.sharedInstance.selectedStation = SettingsDataManager.sharedInstance.getSelectedStationFromUserDefaults()
registerForPushNotifications()
setupCarPlay()
FirebaseApp.configure()
return true
}
AppDelegate+CarPlay.swift
import Foundation
import MediaPlayer
extension AppDelegate{
func setupCarPlay() {
playableContentManager = MPPlayableContentManager.shared()
playableContentManager?.delegate = self
playableContentManager?.dataSource = self
self.carplayPlaylist.setupCommandCenter()
}
}
extension AppDelegate: MPPlayableContentDelegate {
// This is called when user selects a 'playable' item (MPContentItem)
func playableContentManager(_ contentManager: MPPlayableContentManager, initiatePlaybackOfContentItemAt indexPath: IndexPath, completionHandler: #escaping (Error?) -> Void) {
self.carplayPlaylist.playerData = SettingsDataManager.sharedInstance.playerData ?? []
// guard let miniPlayer = self.miniPlayer else {return}
DispatchQueue.main.async {
// App should play music either from the radio stream or podcasts
if indexPath.count == 2 {
if(indexPath[0] == 0) {
// When user selects playable item within Radio tab
if (self.carplayPlaylist.playerData.count > 0) {
if let stationURL = URL(string: self.carplayPlaylist.playerData[indexPath[1]].streams?.iOS ?? "") {
self.carplayPlaylist.play(playURL: stationURL)
SettingsDataManager.sharedInstance.selectedStation = self.carplayPlaylist.playerData[indexPath[1]]
}
}
}
}
completionHandler(nil)
// Workaround to make the Now Playing working on the simulator:
#if targetEnvironment(simulator)
UIApplication.shared.endReceivingRemoteControlEvents()
UIApplication.shared.beginReceivingRemoteControlEvents()
#endif
}
}
func beginLoadingChildItems(at indexPath: IndexPath, completionHandler: #escaping (Error?) -> Void) {
carplayPlaylist.load { error in
completionHandler(error)
}
}
}
extension AppDelegate: MPPlayableContentDataSource {
func numberOfChildItems(at indexPath: IndexPath) -> Int {
if indexPath.indices.count == 0 {
// This returns the number of tabs at the top of the CarPlay display
return 1 // changed to 1 to allow only radio streams
} else if indexPath.indices.count == 1 {
// This returns the number of rows within each tab
if indexPath[0] == 0 {
// Radio Stations rows
return carplayPlaylist.playerData.count
} else {
// Podcasts feed rows
return 0 // Return 0 while podcasts are disabled
}
} else {
return 0
}
}
func contentItem(at indexPath: IndexPath) -> MPContentItem? {
let playerData = carplayPlaylist.playerData
// let podCastsFeeds = carplayPlaylist.podCastSettings?.podcasts_feeds
if indexPath.count == 1 {
// Tab section
let item: MPContentItem
if (indexPath[0] == 0) {
// Radio Stations Tab Section
item = MPContentItem(identifier: "Radio")
item.title = "Radio"
item.artwork = MPMediaItemArtwork(boundsSize: #imageLiteral(resourceName: "NavIcon-Broadcast").size, requestHandler: { _ -> UIImage in
return #imageLiteral(resourceName: "NavIcon-Broadcast")
})
} else {
// Podcast Tab Section
item = MPContentItem(identifier: "Podcasts")
item.title = "Podcasts"
item.artwork = MPMediaItemArtwork(boundsSize: #imageLiteral(resourceName: "NavIcon-Podcasts").size, requestHandler: { _ -> UIImage in
return #imageLiteral(resourceName: "NavIcon-Podcasts")
})
}
item.isContainer = true
item.isPlayable = false
return item
} else if indexPath.count == 2, indexPath.item < playerData.count, indexPath[0] == 0 {
// Radio station items section
let station = playerData[indexPath.item]
let item = MPContentItem(identifier: "\(station.name)")
item.title = station.name
item.subtitle = station.call_letters
item.isPlayable = true
item.isStreamingContent = true
item.downloadImageAndSetArtwork(from: station.logo ?? "", completion: {})
return item
} else {
return nil
}
}
}
///extension to downlaod the image from the api
extension MPContentItem {
func getData(from url: URL, completion: #escaping (Data?, URLResponse?, Error?) -> ()) {
URLSession.shared.dataTask(with: url, completionHandler: completion).resume()
}
func downloadImageAndSetArtwork(from address: String, completion: #escaping () -> Void) {
let defaultImage = #imageLiteral(resourceName: "NavIcon-Music")
let defaultArtwork = MPMediaItemArtwork(boundsSize: defaultImage.size, requestHandler: { _ -> UIImage in
return defaultImage
})
guard let url = URL(string: address) else {
self.artwork = defaultArtwork
return
}
getData(from: url) {
data, response, error in
guard let data = data, error == nil else {
AppLogger.error("Image Error")
self.artwork = defaultArtwork
return
}
DispatchQueue.main.async() {
guard let image = UIImage(data: data) else {
self.artwork = defaultArtwork
return
}
self.artwork = MPMediaItemArtwork(boundsSize: image.size, requestHandler: { _ -> UIImage in
return image
})
completion()
}
}
}
}
CarPlayPlaylist.swift
import Foundation
//import UIKit
import AVKit
import MediaPlayer
class CarPlayPlaylist {
let radioPlayer = FRadioPlayer.shared
var playerData: [Players] = []
var podCastItemsArray: [[Item]] = []
var podCastSettings: Podcast_settings?
var podCastFeedNameArray:[String] = []
var isFromCarPlay: Bool = false
var playButtonStatus: Bool = false
var currentPodcastItem: Item?
func load(_ completion: #escaping (Error?) -> Void) {
// if (self.podCastFeedNameArray.count == 0 && self.podCastItemsArray.count == 0) {
// getPodcastDataFromSettingsDataManager()
//
// let podcastFeedsCount = self.podCastSettings?.podcasts_feeds?.count ?? 0
// podCastItemsArray = [[Item]](repeating: [], count: podcastFeedsCount)
// }
self.playerData = SettingsDataManager.sharedInstance.playerData ?? []
completion(nil)
}
func play (playURL: URL) {
isFromCarPlay = true
self.radioPlayer.radioURL = playURL
self.radioPlayer.play()
}
func setupCommandCenter () {
MPNowPlayingInfoCenter.default().nowPlayingInfo = [MPMediaItemPropertyTitle: "Current Playing song"]
MPNowPlayingInfoCenter.default().nowPlayingInfo![MPNowPlayingInfoPropertyPlaybackRate] = 0.0
let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.playCommand.isEnabled = true
commandCenter.pauseCommand.isEnabled = true
commandCenter.playCommand.addTarget { [weak self] (event) -> MPRemoteCommandHandlerStatus in
self?.radioPlayer.play()
// NotificationCenter.default.post(name: NSNotification.Name(rawValue: NotificationCenterConstants.carPlayDidPlay), object: nil, userInfo: nil)
return .success
}
commandCenter.pauseCommand.addTarget { [weak self] (event) -> MPRemoteCommandHandlerStatus in
self?.radioPlayer.pause()
// NotificationCenter.default.post(name: NSNotification.Name(rawValue: NotificationCenterConstants.carPlayDidPause), object: nil, userInfo: nil)
return .success
}
}
}
extension CarPlayPlaylist {
func addCommandCenterNotificationObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(commandCenterDidPlay), name: NSNotification.Name(rawValue: NotificationCenterConstants.commandCenterDidPlay), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(commandCenterDidPause), name: NSNotification.Name(rawValue: NotificationCenterConstants.commandCenterDidPause), object: nil)
}
func removeCommandCenterObservers() {
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NotificationCenterConstants.commandCenterDidPlay), object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NotificationCenterConstants.commandCenterDidPause), object: nil)
}
#objc func commandCenterDidPlay() {
// Playback rate should change the playback status
MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPNowPlayingInfoPropertyPlaybackRate] = 0.0
}
#objc func commandCenterDidPause() {
// Playback rate should change the playback status
MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPNowPlayingInfoPropertyPlaybackRate] = 1.0
}
}
I run a mobile app project using Swift, SwiftUI and Cloud Firestore where I need to find users based on their different settings/preferences. I have solved this by using a collectionGroup query. But sometimes (maybe 1 out of 10 times) the query crashes without any (for me) understandable error message. The composite indexes have been created using the http links provided from XCode.
This is the function I use:
func getUsersFromActivityPrefs(genders:[String], activities:[Int],skillScore_min:Int, skillScore_max:Int,completion:#escaping ([String]) -> ()) {
var matchUsers = [String]()
var count = 0
let db = Firestore.firestore()
for gender in genders {
for activity in activities {
let dbRef = db.collectionGroup("activity_preferences")
.whereField("gender", isEqualTo: gender)
.whereField("activityid", isEqualTo: activity)
.whereField("status", isEqualTo: true)
.whereField("skill_score", isGreaterThanOrEqualTo: skillScore_min)
.whereField("skill_score", isLessThanOrEqualTo: skillScore_max)
.limit(to: 100)
dbRef.getDocuments {( snap, err) in
count+=1
if err != nil {
print(err!.localizedDescription)
}
for i in snap!.documentChanges{
let uid = i.document.get("uid") as? String ?? ""
if uid != "" && !matchUsers.contains(uid) {
matchUsers.append(uid)
if matchUsers.count == 100 {
count = genders.count * activities.count
completion(matchUsers) //escaping completion handler
return
}
}
}
if count == genders.count * activities.count {
completion(matchUsers)
return
}
}
}
}
}
I have attached the trace log and the crash message from XCode. Im using the latest version of Firebase SDK and deployment target is iOS14.
This is the trace log I get:
thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x4f)
frame #0: 0x00007fff4b80dd66 AttributeGraphAG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 322 frame #1: 0x00007fff4b81f1a5 AttributeGraphAGGraphGetValue + 203
frame #2: 0x00007fff55e7ffab SwiftUISwiftUI.DynamicBody.phase.getter : SwiftUI._GraphInputs.Phase + 27 frame #3: 0x00007fff55e80176 SwiftUISwiftUI.DynamicBody.updateValue() -> () + 294
frame #4: 0x00007fff55b9583a SwiftUIpartial apply forwarder for implicit closure #2 (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in implicit closure #1 (A1.Type) -> (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in closure #1 () -> (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in closure #1 (Swift.UnsafePointer<A1>) -> AttributeGraph.Attribute<A> in AttributeGraph.Attribute.init<A where A == A1.Value, A1: AttributeGraph.StatefulRule>(A1) -> AttributeGraph.Attribute<A> + 26 frame #5: 0x00007fff4b808d03 AttributeGraphAG::Graph::UpdateStack::update() + 505
frame #6: 0x00007fff4b809199 AttributeGraphAG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335 frame #7: 0x00007fff4b80d8e8 AttributeGraphAG::Graph::value_ref(AG::AttributeID, AGSwiftMetadata const*, bool*) + 130
frame #8: 0x00007fff4b81f1f3 AttributeGraphAGGraphGetValue + 281 frame #9: 0x00007fff561aeeb7 SwiftUISwiftUI.GraphHost.updatePreferences() -> Swift.Bool + 39
frame #10: 0x00007fff55c9a8cf SwiftUISwiftUI.ViewGraph.updateOutputs(at: SwiftUI.Time) -> () + 95 frame #11: 0x00007fff5611310c SwiftUIclosure #1 () -> () in (extension in SwiftUI):SwiftUI.ViewRendererHost.render(interval: Swift.Double, updateDisplayList: Swift.Bool) -> () + 1308
frame #12: 0x00007fff56112327 SwiftUI(extension in SwiftUI):SwiftUI.ViewRendererHost.render(interval: Swift.Double, updateDisplayList: Swift.Bool) -> () + 343 frame #13: 0x00007fff55ba07de SwiftUIclosure #1 () -> () in SwiftUI._UIHostingView.requestImmediateUpdate() -> () + 62
frame #14: 0x00007fff562739ae SwiftUIreabstraction thunk helper from #escaping #callee_guaranteed () -> () to #escaping #callee_unowned #convention(block) () -> () + 14 frame #15: 0x0000000112ebd8ac libdispatch.dylib_dispatch_call_block_and_release + 12
frame #16: 0x0000000112ebea88 libdispatch.dylib_dispatch_client_callout + 8 frame #17: 0x0000000112eccf23 libdispatch.dylib_dispatch_main_queue_callback_4CF + 1152
frame #18: 0x00007fff203a8276 CoreFoundation__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9 frame #19: 0x00007fff203a2b06 CoreFoundation__CFRunLoopRun + 2685
frame #20: 0x00007fff203a1b9e CoreFoundationCFRunLoopRunSpecific + 567 frame #21: 0x00007fff2b773db3 GraphicsServicesGSEventRunModal + 139
frame #22: 0x00007fff24660af3 UIKitCore-[UIApplication _run] + 912 frame #23: 0x00007fff24665a04 UIKitCoreUIApplicationMain + 101
frame #24: 0x000000010db84a5b Sparringmain at AppDelegate.swift:14:7 frame #25: 0x00007fff20257415 libdyld.dylibstart + 1
Attachments:
Crash in XCode 1
Composite index 2
func getUsersFromActivityPrefs(genders: [String], activities: [Int], skillScore_min: Int, skillScore_max: Int, completion: #escaping ([String]) -> Void) {
var matchUsers = [String]()
var count = 0
let db = Firestore.firestore()
let dispatch = DispatchGroup() // instantiate dispatch group outside loop
for gender in genders {
for activity in activities {
dispatch.enter() // enter group on each iteration
let dbRef = db.collectionGroup("activity_preferences")
.whereField("gender", isEqualTo: gender)
.whereField("activityid", isEqualTo: activity)
.whereField("status", isEqualTo: true)
.whereField("skill_score", isGreaterThanOrEqualTo: skillScore_min)
.whereField("skill_score", isLessThanOrEqualTo: skillScore_max)
.limit(to: 100)
dbRef.getDocuments {( snap, err) in
if let snap = snap {
count += 1
for doc in snap.documents {
if let uid = doc.get("uid") as? String,
!matchUsers.contains(uid) {
matchUsers.append(uid)
}
}
} else if let err = err {
print(err)
}
dispatch.leave() // always leave no matter what the db returned
}
}
}
/*
this is the group's completion handler and it's only
called once after all groups have entered and left
*/
dispatch.notify(queue: .main) {
completion(matchUsers)
}
}
The crash that has occurred is :-
Crashed: com.apple.main-thread
EXC_BREAKPOINT 0x00000001004c6514
Here is the stack race for the crash :-
Crashed: com.apple.main-thread
0 Quickride 0x1004c6514 specialized static HttpUtils.putJSONRequestWithBody(url:targetViewController:handler:body:) (HttpUtils.swift:173)
1 Quickride 0x100464958 specialized static UserRestClient.saveDeviceToken(targetViewController:requestBody:completionHandler:) (UserRestClient.swift:421)
2 Quickride 0x100746da8 DeviceRegistrationHelper.registerDeviceTokenWithQRServer() (DeviceRegistrationHelper.swift:33)
3 Quickride 0x1007fef14 specialized AppDelegate.application(_:didRegisterForRemoteNotificationsWithDeviceToken:) (AppDelegate.swift:315)
4 Quickride 0x1007f3714 #objc AppDelegate.application(_:didRegisterForRemoteNotificationsWithDeviceToken:) (AppDelegate.swift)
5 FBSDKCoreKit 0x101b350f4 fb_swizzledMethod_4 + 140
6 libdispatch.dylib 0x2284a56c8 _dispatch_call_block_and_release + 24
7 libdispatch.dylib 0x2284a6484 _dispatch_client_callout + 16
8 libdispatch.dylib 0x2284529b4 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1068
9 CoreFoundation 0x2289fbdd0 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
10 CoreFoundation 0x2289f6c98 __CFRunLoopRun + 1964
11 CoreFoundation 0x2289f61cc CFRunLoopRunSpecific + 436
12 GraphicsServices 0x22ac6d584 GSEventRunModal + 100
13 UIKitCore 0x255af1054 UIApplicationMain + 212
14 Quickride 0x10043568c main (AppDelegate.swift:29)
15 libdyld.dylib 0x2284b6bb4 start + 4
The code where the crash had occurred is :-
static func putJSONRequestWithBody(url: String, targetViewController: UIViewController?, handler: #escaping RiderRideRestClient.responseJSONCompletionHandler,body : Dictionary<String, String>){
AppDelegate.getAppDelegate().log.debug("")
var authHeader = [String: String]()
if SharedPreferenceHelper.getJWTAuthenticationToken() != nil{
authHeader[Authorization] = SharedPreferenceHelper.getJWTAuthenticationToken()!
}
}
Here is the code for the app delegate didRegisterForremoteNotification from whre the above part of code is called internally :-
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
AppDelegate.getAppDelegate().log.debug("")
let deviceTokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
AppDelegate.getAppDelegate().log.debug("\(deviceTokenString)")
userDefaults.setValue(deviceTokenString, forKey: "deviceTokenString")
let phone = QRSessionManager.getInstance()?.getUserId()
if phone != nil && (phone!.count) > 1 && deviceTokenString != nil && !deviceTokenString.isEmpty{
DeviceRegistrationHelper(sourceViewController: nil, phone: phone!, deviceToken: deviceTokenString).registerDeviceTokenWithQRServer()
}
}
I am trying to get data from multiple apis and saving it to my coredata database. Earlier it comes once in ten times. but now i am getting it every time.
I have created a DispatchGroup and trying to hit api one by one. Below is my code.
let group = DispatchGroup()
group.enter()
SharedFunctions.getCourseSessions {
print("Course Session Done")
group.leave()
}
group.enter()
SharedFunctions.getCourseContent {
print("Course Content Done")
group.leave()
}
group.enter()
SharedFunctions.getCourseQuiz {
print("Course Quiz Done")
group.leave()
}
group.notify(queue: DispatchQueue.global(qos: .background)) {
print("All async calls were run!")
DispatchQueue.main.async {
ACProgressHUD.shared.hideHUD()
completrion()
}
}
Below is my fetching and saving data from api
class func getCourseSessions(completion: #escaping () -> ()) {
let param = "module=getCourseSessions&userid=\(User.uId)&Akey=\(User.akey)&schedule_course_id=\(User.scheduleCourseId)"
SharedFunctions.callWebServices(url: URLS.Base_URL, methodName: "POST", parameters: param, istoken: false, tokenval: "", completion: { (jsonDict) in
print(jsonDict)
DispatchQueue.main.async {
if ((jsonDict.value(forKey: "message") as! NSDictionary).value(forKey: "success") as! String) == "true" {
SharedGlobalVariables.arrayCourseSessions = (((jsonDict.value(forKey: "message") as AnyObject).value(forKey: "data") as AnyObject).value(forKey: "result")) as! NSMutableArray
print(SharedGlobalVariables.arrayCourseSessions.count)
// DispatchQueue.main.async {
SharedGlobalVariables.LoginBool = true
// get a reference to the app delegate
if #available(iOS 10.0, *) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
print(SharedGlobalVariables.arrayCourseSessions.count)
for j in 0...SharedGlobalVariables.arrayCourseSessions.count - 1 {
let managedContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Course_Sessions", in: managedContext)
let courseSessionsScreen = Course_Sessions(entity: entity!, insertInto: managedContext)
if let arrData = SharedGlobalVariables.arrayCourseSessions[j] as? NSDictionary {
if let courseId = arrData.value(forKey: "course_id") as? Int16 {
courseSessionsScreen.course_id = courseId
}
if let userId = arrData.value(forKey: "user_id") as? Int16 {
courseSessionsScreen.user_id = userId
}
if let enableNextScreenSequence = arrData.value(forKey: "enable_nextscreen_sequence") as? Int16 {
courseSessionsScreen.enable_nextscreen_sequence = enableNextScreenSequence
}
}
do {
try managedContext.save()
// getCourseSessionProperties()
} catch let error as NSError {
print(error)
}
}
} else {
// Fallback on earlier versions
}
//}
}
completion()
}
})
}
There is no perticular place to crash app crash. it crash any where like above methode i am passing all apis.
Getting This error:
Error Domain=NSCocoaErrorDomain Code=132001 "(null)" UserInfo={message=attempt to recursively call -save: on the context aborted, stack trace=(
0 CoreData 0x0000000111ff3892 -[NSManagedObjectContext save:] + 306
1 Tuneem 0x000000010f64046c _TFFFZFC6Tuneem15SharedFunctions26getCourseSessionPropertiesFT10completionFT_T__T_U_FCSo12NSDictionaryT_U_FT_T_U_FT_T_ + 60
2 Tuneem 0x000000010f629197 _TTRXFo___XFdCb___ + 39
3 CoreData 0x000000011200cb52 developerSubmittedBlockToNSManagedObjectContextPerform + 178
4 libdispatch.dylib 0x000000011bf0205c _dispatch_client_callout + 8
5 libdispatch.dylib 0x000000011bee094f _dispatch_queue_serial_drain + 221
6 libdispatch.dylib 0x000000011bee1669 _dispatch_queue_invoke + 1084
7 libdispatch.dylib 0x000000011bee1b32 _dispatch_queue_override_invoke + 654
8 libdispatch.dylib 0x000000011bee3ec4 _dispatch_root_queue_drain + 634
9 libdispatch.dylib 0x000000011bee3bef _dispatch_worker_thread3 + 123
10 libsystem_pthread.dylib 0x000000011c299712 _pthread_wqthread + 1299
11 libsystem_pthread.dylib 0x000000011c2991ed start_wqthread + 13
)}
Error Domain=NSCocoaErrorDomain Code=132001 "(null)" UserInfo=. {message=attempt to recursively call -save: on the context aborted, stack trace=(
0 CoreData 0x0000000111ff3892 -[NSManagedObjectContext save:] + 306
1 Tuneem 0x000000010f64046c _TFFFZFC6Tuneem15SharedFunctions26getCourseSessionPropertiesFT10completionFT_T__T_U_FCSo12NSDictionaryT_U_FT_T_U_FT_T_ + 60
2 Tuneem 0x000000010f629197 _TTRXFo___XFdCb___ + 39
3 CoreData 0x000000011200cb52 developerSubmittedBlockToNSManagedObjectContextPerform + 178
4 libdispatch.dylib 0x000000011bf0205c _dispatch_client_callout + 8
5 libdispatch.dylib 0x000000011bee094f _dispatch_queue_serial_drain + 221
6 libdispatch.dylib 0x000000011bee1669 _dispatch_queue_invoke + 1084
7 libdispatch.dylib 0x000000011bee1b32 _dispatch_queue_override_invoke + 654
8 libdispatch.dylib 0x000000011bee3ec4 _dispatch_root_queue_drain + 634
9 libdispatch.dylib 0x000000011bee3bef _dispatch_worker_thread3 + 123
10 libsystem_pthread.dylib 0x000000011c299712 _pthread_wqthread + 1299
11 libsystem_pthread.dylib 0x000000011c2991ed start_wqthread + 13
)}
Trying to solve it from last couple of days getting no idea, any help will be appreciate.