2

我有一个在启动时崩溃的应用程序。我已经确定了问题的根源,但我似乎无法弄清楚如何解决它。让我先解释一下我的工作:

我有一个 LocationManager 来检查用户是否进入某个区域(使用 startRegionMonitoring)。如果是这样,则计划在 5 分钟内触发本地通知。但是,如果此人在 5 分钟内再次离开,则本地通知将被取消。我这样做是因为用户可以通过建筑物而无需实际进入它。当用户自己打开应用程序时,它还会取消任何待处理的通知(在这 5 分钟内)。

发生这种情况时,应用程序会在启动时崩溃。崩溃报告表明了这一点:

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x000000010098b38c
Triggered by Thread:  0

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   GetReminded                     0x000000010098b38c closure #1 in closure #1 in AppDelegate.applicationWillEnterForeground(_:) + 3388300 (AppDelegate.swift:1300)
1   GetReminded                     0x00000001006be738 thunk for @escaping @callee_guaranteed () -> () + 452408 (<compiler-generated>:0)
2   libdispatch.dylib               0x00000001b6448a38 0x1b63e9000 + 391736
3   libdispatch.dylib               0x00000001b64497d4 0x1b63e9000 + 395220
4   libdispatch.dylib               0x00000001b63f7004 0x1b63e9000 + 57348
5   CoreFoundation                  0x00000001b699ac1c 0x1b68f1000 + 695324
6   CoreFoundation                  0x00000001b6995b54 0x1b68f1000 + 674644
7   CoreFoundation                  0x00000001b69950b0 0x1b68f1000 + 671920
8   GraphicsServices                0x00000001b8b9579c 0x1b8b8b000 + 42908
9   UIKitCore                       0x00000001e31c4978 0x1e2908000 + 9161080
10  GetReminded                     0x0000000100681f4c main + 204620 (ExerciseStatistics.swift:219)
11  libdyld.dylib                   0x00000001b645a8e0 0x1b6459000 + 6368

起初,我没有在主线程上执行取消操作——我认为这是导致崩溃的原因。所以我使用了 Dispatch Queue 并认为问题会得到解决,但它仍然存在。我的代码willEnterForeground

UNUserNotificationCenter.current().getDeliveredNotifications { (notifications: [UNNotification]) in

    DispatchQueue.main.async {
        for notification in notifications {
            if(notification.request.content.userInfo["notificationType"] as! String == "exitReminder" || notification.request.content.userInfo["notificationType"] as! String == "enterReminder") {
                let notificationID = notification.request.identifier
                UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [notificationID])
                UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [notificationID])

            }
        }
    }

}

我不确定如何解决这个问题。知道这个提醒是从后台发送的可能很重要,所以当应用程序不在前台时。我在后台打开了定位服务,当我留在该位置时一切正常,但是当我在这 5 分钟内再次退出时出现问题,因此需要取消通知。

有任何想法吗?

4

1 回答 1

1

notification.request.content.userInfo["notificationType"] as! Stringnil如果 notificationType 键返回(或字符串以外的其他内容),则会崩溃。没有充分的理由,你不应该使用强制向下转换。

使用防御性编码:

for notification in notifications {
        if let notificationType = notification.request.content.userInfo["notificationType"] as? String { 
             if notificationType == "exitReminder" || notificationType == "enterReminder" {
                let notificationID = notification.request.identifier
                UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [notificationID])
                UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [notificationID])

        }
    }
}
于 2019-07-14T12:29:14.717 回答