13

顯然,這是現在可以通過ios10:獲取本地通知顯示,而應用程序是在前臺斯威夫特3

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

這個答案基本上是說所需要的工具來做到這一點:

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

我只是不太瞭解如何把它放在一起。

我不知道這是多麼重要,但我無法保留可選的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!!!") 
     } 
    } 
} 

回答

42

當應用程序在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]) 

    } 

如果您希望您的通知旗幟應在整個應用無處不顯示,那麼您可以在AppDelegateUNUserNotificationDelegate委託,使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

+0

真棒,真棒的答案。謝謝。 – user6820041

+0

現在假設我想從NSURL設置圖像意味着網頁,那麼我該如何設置? –

+0

非常好的答案! – Maybe1

6

鍵,讓你的通知顯示,而你的應用程序是在前臺還設置:

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

在您的UNNotificationRequest。至於其餘的,請看Rajan Maheshwari的優秀答案。

+0

如果「UNUserNotificationCenterDelegate」的委託和操作類別的註冊設置正確,則不應該設置此項。代理中的第一個方法是處理這個app-in-foreground的情況。設置這個值是沒有文檔的,可能會受到應用商店準則的限制。 – James

8

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文檔僅供參考。

+0

真棒兄弟真棒!查理辛恩會說你是一個搖滾明星!如果您有前臺通知,只需複製並粘貼這段代碼即可完成! – Mikhail