Advanced-NSOperations/Earthquakes/Operations/UserNotificationCondition.swift
2022-02-16 22:16:09 -08:00

122 lines
4.2 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
Copyright (C) 2015 Apple Inc. All Rights Reserved.
See LICENSE.txt for this samples licensing information
Abstract:
This file shows an example of implementing the OperationCondition protocol.
*/
#if os(iOS)
import UIKit
/**
A condition for verifying that we can present alerts to the user via
`UILocalNotification` and/or remote notifications.
*/
struct UserNotificationCondition: OperationCondition {
enum Behavior {
/// Merge the new `UIUserNotificationSettings` with the `currentUserNotificationSettings`.
case Merge
/// Replace the `currentUserNotificationSettings` with the new `UIUserNotificationSettings`.
case Replace
}
static let name = "UserNotification"
static let currentSettings = "CurrentUserNotificationSettings"
static let desiredSettings = "DesiredUserNotificationSettigns"
static let isMutuallyExclusive = false
let settings: UIUserNotificationSettings
let application: UIApplication
let behavior: Behavior
/**
The designated initializer.
- parameter settings: The `UIUserNotificationSettings` you wish to be
registered.
- parameter application: The `UIApplication` on which the `settings` should
be registered.
- parameter behavior: The way in which the `settings` should be applied
to the `application`. By default, this value is `.Merge`, which means
that the `settings` will be combined with the existing settings on the
`application`. You may also specify `.Replace`, which means the `settings`
will overwrite the exisiting settings.
*/
init(settings: UIUserNotificationSettings, application: UIApplication, behavior: Behavior = .Merge) {
self.settings = settings
self.application = application
self.behavior = behavior
}
func dependencyForOperation(operation: Operation) -> NSOperation? {
return UserNotificationPermissionOperation(settings: settings, application: application, behavior: behavior)
}
func evaluateForOperation(operation: Operation, completion: OperationConditionResult -> Void) {
let result: OperationConditionResult
let current = application.currentUserNotificationSettings()
switch (current, settings) {
case (let current?, let settings) where current.contains(settings):
result = .Satisfied
default:
let error = NSError(code: .ConditionFailed, userInfo: [
OperationConditionKey: self.dynamicType.name,
self.dynamicType.currentSettings: current ?? NSNull(),
self.dynamicType.desiredSettings: settings
])
result = .Failed(error)
}
completion(result)
}
}
/**
A private `Operation` subclass to register a `UIUserNotificationSettings`
object with a `UIApplication`, prompting the user for permission if necessary.
*/
private class UserNotificationPermissionOperation: Operation {
let settings: UIUserNotificationSettings
let application: UIApplication
let behavior: UserNotificationCondition.Behavior
init(settings: UIUserNotificationSettings, application: UIApplication, behavior: UserNotificationCondition.Behavior) {
self.settings = settings
self.application = application
self.behavior = behavior
super.init()
addCondition(AlertPresentation())
}
override func execute() {
dispatch_async(dispatch_get_main_queue()) {
let current = self.application.currentUserNotificationSettings()
let settingsToRegister: UIUserNotificationSettings
switch (current, self.behavior) {
case (let currentSettings?, .Merge):
settingsToRegister = currentSettings.settingsByMerging(self.settings)
default:
settingsToRegister = self.settings
}
self.application.registerUserNotificationSettings(settingsToRegister)
}
}
}
#endif