ios 在应用程序处于前台 Swift 3 时显示本地通知

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39713605/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 10:22:14  来源:igfitidea点击:

Getting local notifications to show while app is in foreground Swift 3

iosswiftswift3uilocalnotificationunusernotificationcenter

提问by user6820041

Apparently this is now possible with ios10 :

显然,现在可以使用 ios10 实现:

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

This answer basically says the tools needed to do it:

这个答案基本上说明了执行此操作所需的工具:

Displaying a stock iOS notification banner when your app is open and in the foreground?

当您的应用程序打开并处于前台时显示股票 iOS 通知横幅?

I'm just not really understanding how to put it all together.

我只是不太明白如何把它们放在一起。

I dont know how important this is, but I'm not able to keep the optional func and xcode wants me to switch it to private.

我不知道这有多重要,但我无法保留可选的 func 并且 xcode 希望我将其切换为私有。

I'm trying to show the badge, and the docs provide

我正在尝试显示徽章,并且文档提供

static var badge: UNNotificationPresentationOptions { get }

Little lost here.

一点点迷失在这里。

And then I'm assuming if I want to exclude a certain view controller from getting these badges and I'm not using a navigation controller this code I found would work? : var window:UIWindow?

然后我假设如果我想从获取这些徽章中排除某个视图控制器并且我没有使用导航控制器,我发现这个代码会起作用吗?:var 窗口:UIWindow?

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

回答by Rajan Maheshwari

There is a delegate method to display the notification when the app is open in iOS 10. You have to implement this in order to get the rich notifications working when the app is open.

当应用程序在 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()
    }

}

In order to schedule a notification in iOS 10 and providing a badge

为了在 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 ?? "some unknown error")
        }     
        print("Notification Register Success")
    }
}

In order to register in AppDelegate we have to write this piece of code in didFinishLaunchingWithOptions

为了在 AppDelegate 中注册,我们必须在 didFinishLaunchingWithOptions

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

I have defined actions also here. You may skip them

我也在这里定义了动作。你可以跳过它们

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])

    }

If you want that your notification banner should be shown everywhere in the entire application, then you can write the delegate of UNUserNotificationDelegatein AppDelegateand make the UNUserNotificationCentercurrent delegate to AppDelegate

如果您希望您的通知横幅应显示在整个应用程序的任何地方,那么您可以编写UNUserNotificationDelegatein的委托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]) 
    }
}

Check this link for more details
https://www.youtube.com/watch?v=Svul_gCtzck

查看此链接了解更多详情
https://www.youtube.com/watch?v=Svul_gCtzck

Github Sample
https://github.com/kenechilearnscode/UserNotificationsTutorial

Github 示例
https://github.com/kenechilearnscode/UserNotificationsTutorial

Here is the output

这是输出

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

回答by Derek Soike

Swift 3 | iOS 10+

斯威夫特 3 | iOS 10+

Assuming you know how to schedule a local notification:

假设您知道如何安排本地通知:

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
        }
    }
}

You need to make your AppDelegateimplement the UNUserNotificationCenterDelegateprotocol, and set it as the notification center's delegate with UNUserNotificationCenter.current().delegate = self.

您需要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)
    }
}

Now your local notifications will appear when your app is in the foreground.

现在,当您的应用程序处于前台时,您的本地通知将出现。

See the UNUserNotificationCenterDelegatedocs for reference.

请参阅UNUserNotificationCenterDelegate文档以供参考。

回答by brown

Key to getting your notifications to show up while your app is in the foreground is also setting:

在您的应用程序处于前台时让您的通知显示的关键还设置:

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

in your UNNotificationRequest. As for the rest, see the excellent answer by Rajan Maheshwari.

在您的UNNotificationRequest. 至于其余的,请参阅Rajan Maheshwari的出色回答。

回答by Sourabh Kumbhar

When your app is open in the foreground userNotificationCenter method call

当您的应用在前台打开时 userNotificationCenter 方法调用

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