简体   繁体   中英

How can I write code that compiles with Xcode 9.x(iOS11) and Xcode10.x(iOS12) when using UNAuthorizationStatus.provisional?

Hello I have some switch case code that handles UNAuthorizationStatus, since iOS12 a new status has been added: .provisional . In C or other old style compiler stuff I would write a precompiler directive to surround .provisional handling code however in swift that seems to lead to errors.

private func checkNotificationSettings() {
    UNUserNotificationCenter.current().getNotificationSettings { settings in
        switch settings.authorizationStatus {
        if #available(iOS 12.0, *) { // ERROR here
        case .provisional: // ERROR here too
            // Do my thing
        }
        case .authorized:
            // Do my thing
        case .notDetermined:
            // Request authorization and if granted do my thing
        case .denied:
            // Do not do my thing
        }
    }
}

Errors:

Switch must be exhaustive
All statements inside a switch must be covered by a 'case' or 'default'

Is there any smart way of handling this? I would like to avoid this because it is too long and repetitive:

if #available(iOS 12.0, *) {
    NUserNotificationCenter.current().getNotificationSettings { settings in 
        switch settings.authorizationStatus {
        case .provisional:
        ...
    }
} else {
    NUserNotificationCenter.current().getNotificationSettings { settings in 
        switch settings.authorizationStatus {
        ...
    }
}

You could do all common cases as normal and add the available checks in the default part like this

NUserNotificationCenter.current().getNotificationSettings { settings in 
    switch settings.authorizationStatus {
        case .stateX:
         //do stuff
        default:
          if #available(iOS 12.0, *) {
               if settings.authorizationStatus == .provisional {
                //Handle case
               }
          }
    }
}

This isn't the most elegant solution, but it's simple to use if else instead of switch . In my case I remap .provisional to .authorized . Something like:

func didTapNotificationsCell(authorizationStatus: UNAuthorizationStatus) {
    if #available(iOS 12.0, *), authorizationStatus == .provisional {
        handleCommonStatus(.authorized)
    } else {
        handleCommonStatus(authorizationStatus)
    }
}

private func handleCommonStatus(_ status: UNAuthorizationStatus) {
    if status == .authorized {
        // Do something

    } else if status == .notDetermined {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (_, _) in
        }

    } else if status == .denied {

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM