// Copyright © 2020 Metabolist. All rights reserved. import Foundation import Combine import UserNotifications public class UserNotificationService: NSObject { private let userNotificationCenter: UNUserNotificationCenter public init(userNotificationCenter: UNUserNotificationCenter = .current()) { self.userNotificationCenter = userNotificationCenter super.init() userNotificationCenter.delegate = self } } public extension UserNotificationService { func isAuthorized() -> AnyPublisher { getNotificationSettings() .map(\.authorizationStatus) .flatMap { [weak self] status -> AnyPublisher in if status == .notDetermined { return self?.requestProvisionalAuthorization() .eraseToAnyPublisher() ?? Empty().eraseToAnyPublisher() } return Just(status == .authorized || status == .provisional) .setFailureType(to: Error.self) .eraseToAnyPublisher() } .eraseToAnyPublisher() } } private extension UserNotificationService { func getNotificationSettings() -> AnyPublisher { Future { [weak self] promise in self?.userNotificationCenter.getNotificationSettings { promise(.success($0)) } } .eraseToAnyPublisher() } func requestProvisionalAuthorization() -> AnyPublisher { Future { [weak self] promise in self?.userNotificationCenter.requestAuthorization( options: [.alert, .sound, .badge, .provisional]) { granted, error in if let error = error { return promise(.failure(error)) } return promise(.success(granted)) } } .eraseToAnyPublisher() } } extension UserNotificationService: UNUserNotificationCenterDelegate { public func userNotificationCenter( _ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { print(notification.request.content.body) completionHandler(.banner) } }