Подтвердить что ты не робот

Получение локальных уведомлений, пока приложение находится на переднем плане Swift 3

По-видимому, теперь это возможно с помощью ios10:

optional func userNotificationCenter(_ center: UNUserNotificationCenter, 
                 willPresent notification: UNNotification, 
  withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void)

В этом ответе в основном говорится о необходимых инструментах:

Отображение подписного баннера уведомлений iOS, когда ваше приложение открыто и на переднем плане?

Я просто не понимаю, как собрать все это.

Я не знаю, насколько это важно, но я не могу удержать дополнительный func, и xcode хочет, чтобы я переключил его на приватный.

Я пытаюсь показать значок, а документы предоставляют

static var badge: UNNotificationPresentationOptions { get }

Немного потерял здесь.

И затем я предполагаю, что если я хочу исключить определенный контроллер представления из этих значков, и я не использую контроллер навигации, этот код, который я нашел, будет работать?:   var window: UIWindow?

if let viewControllers = window?.rootViewController?.childViewControllers {
for viewController in viewControllers {
    if viewController.isKindOfClass(MyViewControllerClass) {
        print("Found it!!!")
        }
    }
}
4b9b3361

Ответ 1

Существует метод делегирования для отображения уведомления, когда приложение открыто в iOS 10. Вам нужно реализовать это, чтобы получать богатые уведомления, когда приложение открыто.

extension ViewController: UNUserNotificationCenterDelegate {

    //for displaying notification when app is in foreground
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

        //If you don't want to show notification when app is open, do something here else and make a return here. 
        //Even you you don't implement this delegate method, you will not see the notification on the specified controller. So, you have to implement this delegate and make sure the below line execute. i.e. completionHandler.

        completionHandler([.alert, .badge, .sound]) 
    }

    // For handling tap and user actions
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

        switch response.actionIdentifier {
        case "action1":
            print("Action First Tapped")
        case "action2":
            print("Action Second Tapped")
        default:
            break
        }
        completionHandler()
    }

}

Чтобы запланировать уведомление в iOS 10 и предоставить значок

override func viewDidLoad() {
    super.viewDidLoad()

    // set UNUserNotificationCenter delegate to self
    UNUserNotificationCenter.current().delegate = self
    scheduleNotifications()
}

func scheduleNotifications() {

    let content = UNMutableNotificationContent()
    let requestIdentifier = "rajanNotification"

    content.badge = 1
    content.title = "This is a rich notification"
    content.subtitle = "Hello there, I am Rajan Maheshwari"
    content.body = "Hello body"
    content.categoryIdentifier = "actionCategory"
    content.sound = UNNotificationSound.default()

    // If you want to attach any image to show in local notification
    let url = Bundle.main.url(forResource: "notificationImage", withExtension: ".jpg")
    do {
        let attachment = try? UNNotificationAttachment(identifier: requestIdentifier, url: url!, options: nil)
        content.attachments = [attachment!]
    }      

    let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 3.0, repeats: false)

    let request = UNNotificationRequest(identifier: requestIdentifier, content: content, trigger: trigger)
    UNUserNotificationCenter.current().add(request) { (error:Error?) in

        if error != nil {
            print(error?.localizedDescription)
        }     
        print("Notification Register Success")
    }
}

Чтобы зарегистрироваться в AppDelegate, мы должны написать этот фрагмент кода в didFinishLaunchingWithOptions

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        registerForRichNotifications()
        return true
    }

Я также определил действия здесь. Вы можете пропустить их

func registerForRichNotifications() {

       UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.badge,.sound]) { (granted:Bool, error:Error?) in
            if error != nil {
                print(error?.localizedDescription)
            }
            if granted {
                print("Permission granted")
            } else {
                print("Permission not granted")
            }
        }

        //actions defination
        let action1 = UNNotificationAction(identifier: "action1", title: "Action First", options: [.foreground])
        let action2 = UNNotificationAction(identifier: "action2", title: "Action Second", options: [.foreground])

        let category = UNNotificationCategory(identifier: "actionCategory", actions: [action1,action2], intentIdentifiers: [], options: [])

        UNUserNotificationCenter.current().setNotificationCategories([category])

    }

Если вы хотите, чтобы ваше уведомление баннер должен быть показаны везде во всем приложении, то вы можете написать делегатый UNUserNotificationDelegate в AppDelegate и сделать UNUserNotificationCenter текущего делегата AppDelegate

extension AppDelegate: UNUserNotificationCenterDelegate {

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        print(response.notification.request.content.userInfo)
        completionHandler()
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert, .badge, .sound]) 
    }
}

Проверьте эту ссылку для получения более подробной информации.
https://www.youtube.com/watch?v=Svul_gCtzck

Образец Github
https://github.com/kenechilearnscode/UserNotificationsTutorial

Вот результат

enter image description here

enter image description here

Ответ 2

Ключ к тому, чтобы ваши уведомления отображались во время вашего приложения на переднем плане, также устанавливает:

content.setValue(true, forKey: "shouldAlwaysAlertWhileAppIsForeground")

в UNNotificationRequest. Что касается остальных, см. Отличный ответ Раджан Махешвари.

Ответ 3

Swift 3 | iOS 10 +

Предполагая, что вы знаете, как планировать локальное уведомление:

func scheduleLocalNotification(forDate notificationDate: Date) {

    let calendar = Calendar.init(identifier: .gregorian)

    let requestId: String = "123"
    let title: String = "Notification Title"
    let body: String = "Notification Body"

    // construct notification content
    let content = UNMutableNotificationContent()
    content.title = NSString.localizedUserNotificationString(forKey: title, arguments: nil)
    content.body = NSString.localizedUserNotificationString(forKey: body, arguments: nil)
    content.sound = UNNotificationSound.default()
    content.badge = 1
    content.userInfo = [
        "key1": "value1"
    ]

    // configure trigger
    let calendarComponents: [Calendar.Component] = [.year, .month, .day, .hour, .minute]
    let dateComponents = calendar.dateComponents(calendarComponents, from: notificationDate)
    let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)

    // create the request
    let request = UNNotificationRequest.init(identifier: requestId, content: content, trigger: trigger)

    // schedule notification
    UNUserNotificationCenter.current().add(request) { (error: Error?) in
        if let error = error {
            // handle error
        }
    }
}

Вам нужно сделать AppDelegate реализовать протокол UNUserNotificationCenterDelegate и установить его как делегата центра уведомлений с помощью UNUserNotificationCenter.current().delegate = self.

// AppDelegate.swift

import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions 
        launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        // set app delegate as notification center delegate
        UNUserNotificationCenter.current().delegate = self
    }
}

extension AppDelegate: UNUserNotificationCenterDelegate {

    // called when user interacts with notification (app not running in foreground)
    func userNotificationCenter(_ center: UNUserNotificationCenter, 
        didReceive response: UNNotificationResponse, withCompletionHandler 
        completionHandler: @escaping () -> Void) {

        // do something with the notification
        print(response.notification.request.content.userInfo)

        // the docs say you should execute this asap
        return completionHandler()
    }

    // called if app is running in foreground
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent 
        notification: UNNotification, withCompletionHandler completionHandler: 
        @escaping (UNNotificationPresentationOptions) -> Void) {

        // show alert while app is running in foreground
        return completionHandler(UNNotificationPresentationOptions.alert)
    }
}

Теперь ваши локальные уведомления появятся, когда ваше приложение находится на переднем плане.

Смотрите UNUserNotificationCenterDelegate документы для справки.

Ответ 4

Когда ваше приложение открыто в вызове метода userNotificationCenter переднего плана

func userNotificationCenter(_ center: UNUserNotificationCenter,
   willPresent notification: UNNotification, 
   withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) 
{
completionHandler(.alert)
}