如何创建本地通知?

Posted

技术标签:

【中文标题】如何创建本地通知?【英文标题】:How to create local notifications? 【发布时间】:2011-05-18 15:20:43 【问题描述】:

如何设置本地通知,以便在我设置的时间,我的应用生成带有自定义消息的通知/警报?

【问题讨论】:

【参考方案1】:

这是适用于我的项目的 LocalNotification 示例代码。

目标-C:

AppDelegate 文件中的此代码块:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    
        [launchOptions valueForKey:UIApplicationLaunchOptionsLocalNotificationKey];
        // Override point for customization after application launch.
        return YES;
    

    // This code block is invoked when application is in foreground (active-mode) 
 -(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification 

        UIAlertView *notificationAlert = [[UIAlertView alloc] initWithTitle:@"Notification"    message:@"This local notification" 
        delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];

        [notificationAlert show];
       // NSLog(@"didReceiveLocalNotification");
    

任何ViewController的.m文件中的此代码块:

-(IBAction)startLocalNotification   // Bind this method to UIButton action
    NSLog(@"startLocalNotification");

    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:7];
    notification.alertBody = @"This is local notification!";
    notification.timeZone = [NSTimeZone defaultTimeZone];
    notification.soundName = UILocalNotificationDefaultSoundName;
    notification.applicationIconBadgeNumber = 10;

    [[UIApplication sharedApplication] scheduleLocalNotification:notification];    

当按下绑定startLocalNotification 的按钮时,上面的代码会在7 秒的时间间隔后显示一个AlertView 如果应用程序在后台,那么它会将BadgeNumber 显示为10,并带有默认通知声音。

此代码适用于 ios 7.x 及以下版本,但对于 iOS 8,它将在控制台上提示以下错误

尝试安排带有警报的本地通知,但尚未获得用户显示警报的权限

这意味着您需要注册本地通知。这可以通过以下方式实现:

if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)])

    [application registerUserNotificationSettings [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];

您也可以参考blog 获取本地通知。

斯威夫特:

您的AppDelegate.swift 文件应如下所示:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool     
    // Override point for customization after application launch.
    application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: UIUserNotificationType.Sound | UIUserNotificationType.Badge | UIUserNotificationType.Alert, categories: nil))

    return true

您要在其中创建本地通知的 swift 文件(例如 ViewController.swift)应包含以下代码:

//MARK: - Button functions
func buttonIsPressed(sender: UIButton) 
    println("buttonIsPressed function called \(UIButton.description())")

    var localNotification = UILocalNotification()
    localNotification.fireDate = NSDate(timeIntervalSinceNow: 3)
    localNotification.alertBody = "This is local notification from Swift 2.0"
    localNotification.timeZone = NSTimeZone.localTimeZone()
    localNotification.repeatInterval = NSCalendarUnit.CalendarUnitMinute
    localNotification.userInfo = ["Important":"Data"];
    localNotification.soundName = UILocalNotificationDefaultSoundName
    localNotification.applicationIconBadgeNumber = 5
    localNotification.category = "Message"

    UIApplication.sharedApplication().scheduleLocalNotification(localNotification)



//MARK: - viewDidLoad

class ViewController: UIViewController 

    var objButton : UIButton!
    . . .

    override func viewDidLoad() 
        super.viewDidLoad()

        . . .

        objButton = UIButton.buttonWithType(.Custom) as? UIButton
        objButton.frame = CGRectMake(30, 100, 150, 40)
        objButton.setTitle("Click Me", forState: .Normal)
        objButton.setTitle("Button pressed", forState: .Highlighted)

        objButton.addTarget(self, action: "buttonIsPressed:", forControlEvents: .TouchDown)

        . . .
    

    . . .

您在 iOS 9 及更低版本中使用本地通知的方式在 iOS 10 中完全不同。

来自 Apple 发行说明的屏幕截图描述了这一点。

您可以参考apple reference document 获取 UserNotification。

以下是本地通知的代码:

目标-C:

    App-delegate.h文件中使用@import UserNotifications;

    App-delegate 应符合UNUserNotificationCenterDelegate 协议

    didFinishLaunchingOptions 中使用以下代码:

    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert)
           completionHandler:^(BOOL granted, NSError * _Nullable error) 
                  if (!error) 
                      NSLog(@"request authorization succeeded!");
                      [self showAlert];
                  
    ];
    
    -(void)showAlert 
        UIAlertController *objAlertController = [UIAlertController alertControllerWithTitle:@"Alert" message:@"show an alert!" preferredStyle:UIAlertControllerStyleAlert];
    
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"OK"
          style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) 
            NSLog(@"Ok clicked!");
        ];
    
        [objAlertController addAction:cancelAction];
    
    
        [[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController] presentViewController:objAlertController animated:YES completion:^            
        ];
    
    
    

    现在在任何视图控制器中创建一个按钮,并在 IBAction 中使用以下代码:

    UNMutableNotificationContent *objNotificationContent = [[UNMutableNotificationContent alloc] init];
    
    objNotificationContent.title = [NSString localizedUserNotificationStringForKey:@“Notification!” arguments:nil];
    
    objNotificationContent.body = [NSString localizedUserNotificationStringForKey:@“This is local notification message!“arguments:nil];
    
    objNotificationContent.sound = [UNNotificationSound defaultSound];
    
    // 4. update application icon badge number
    objNotificationContent.badge = @([[UIApplication sharedApplication] applicationIconBadgeNumber] + 1);
    
    // Deliver the notification in five seconds.
    UNTimeIntervalNotificationTrigger *trigger =  [UNTimeIntervalNotificationTrigger                                             triggerWithTimeInterval:10.f repeats:NO];       
    
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@“ten”                                                                            content:objNotificationContent trigger:trigger];
    
    // 3. schedule localNotification
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    
    [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) 
        if (!error) 
            NSLog(@“Local Notification succeeded“);
         else 
            NSLog(@“Local Notification failed“);
        
    ];
    

斯威夫特 3:

    AppDelegate.swift 文件中使用import UserNotifications Appdelegate 应符合UNUserNotificationCenterDelegate 协议

    didFinishLaunchingWithOptions 使用下面的代码

    // Override point for customization after application launch.
    let center = UNUserNotificationCenter.current()
    center.requestAuthorization(options: [.alert, .sound])  (granted, error) in
        // Enable or disable features based on authorization.
        if error != nil 
            print("Request authorization failed!")
         else 
            print("Request authorization succeeded!")
            self.showAlert()
        
    
    
    
    func showAlert() 
        let objAlert = UIAlertController(title: "Alert", message: "Request authorization succeeded", preferredStyle: UIAlertControllerStyle.alert)
    
        objAlert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
        //self.presentViewController(objAlert, animated: true, completion: nil)
    
        UIApplication.shared().keyWindow?.rootViewController?.present(objAlert, animated: true, completion: nil)
    
    

    现在在任何视图控制器中创建一个按钮,并在 IBAction 中使用以下代码:

    let content = UNMutableNotificationContent()
    content.title = NSString.localizedUserNotificationString(forKey: "Hello!", arguments: nil)
    content.body = NSString.localizedUserNotificationString(forKey: "Hello_message_body", arguments: nil)
    content.sound = UNNotificationSound.default()
    content.categoryIdentifier = "notify-test"
    
    let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 5, repeats: false)
    let request = UNNotificationRequest.init(identifier: "notify-test", content: content, trigger: trigger)
    
    let center = UNUserNotificationCenter.current()
    center.add(request)
    

【讨论】:

我是否需要在按下按钮时运行 funcButtonIsPressed?如果我希望应用程序默认每周发出通知,我应该将其添加到初始 VC 的 viewDidLoad 中吗? 另外,为什么你的 AppDelegate.swift 文件有两次 didFinishLaunchingWithOptions? "import UserNotifications" 在你的 ViewController 中导入这个 很好的例子。请注意,AppDelegate 没有必要遵守UNUserNotificationCenterDelegate,除非您希望它执行一些通知逻辑。此外,根据需要,可以在应用委托之外完成请求授权或发送本地通知。【参考方案2】:

在 appdelegate.m 文件中,在 applicationDidEnterBackground 中写入以下代码以获取本地通知

- (void)applicationDidEnterBackground:(UIApplication *)application

   UILocalNotification *notification = [[UILocalNotification alloc]init];
   notification.repeatInterval = NSDayCalendarUnit;
   [notification setAlertBody:@"Hello world"];
   [notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:1]];
   [notification setTimeZone:[NSTimeZone  defaultTimeZone]];
   [application setScheduledLocalNotifications:[NSArray arrayWithObject:notification]];

【讨论】:

当您使用 setScheduledLocalNotifications 只安排一个通知时:是不必要的。有一个带有一个参数的 scheduleLocalNotification 方法 - 要安排的通知。 developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/…:【参考方案3】:

创建本地通知非常简单。只需按照以下步骤操作。

    在 viewDidLoad() 函数中,请求用户允许您的应用显示通知。为此,我们可以使用以下代码。

    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge], completionHandler: didAllow, error in
    )
    

    然后你可以创建一个按钮,然后在action函数中你可以编写如下代码来显示一个通知。

    //creating the notification content
    let content = UNMutableNotificationContent()
    
    //adding title, subtitle, body and badge
    content.title = "Hey this is Simplified iOS"
    content.subtitle = "iOS Development is fun"
    content.body = "We are learning about iOS Local Notification"
    content.badge = 1
    
    //getting the notification trigger
    //it will be called after 5 seconds
    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
    
    //getting the notification request
    let request = UNNotificationRequest(identifier: "SimplifiedIOSNotification", content: content, trigger: trigger)
    
    //adding the notification to notification center
    UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
    

    会显示通知,点击通知按钮后点击主页按钮。当应用程序处于前台时,不会显示通知。但是,如果您使用的是 iPhone X。即使应用程序在前台,您也可以显示通知。为此,您只需添加一个名为 UNUserNotificationCenterDelegate

    的委托

有关更多详细信息,请访问此博客文章:iOS Local Notification Tutorial

【讨论】:

【参考方案4】:

使用 Swift 5 更新 通常我们使用三种类型的本地通知

    简单的本地通知 带有操作的本地通知 带有内容的本地通知

您可以在其中发送简单的文本通知或操作按钮和附件。

在您的应用中使用 UserNotifications 包,以下示例 请求通知权限,根据用户操作 AppDelegate 本身准备和发送通知,并使用视图控制器列出不同类型的本地通知测试。

AppDelegate

import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate 

    let notificationCenter = UNUserNotificationCenter.current()
    var window: UIWindow?


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

        //Confirm Delegete and request for permission
        notificationCenter.delegate = self
        let options: UNAuthorizationOptions = [.alert, .sound, .badge]
        notificationCenter.requestAuthorization(options: options) 
            (didAllow, error) in
            if !didAllow 
                print("User has declined notifications")
            
        

        return true
    

    func applicationWillResignActive(_ application: UIApplication) 
    
    func applicationDidEnterBackground(_ application: UIApplication) 
    
    func applicationWillEnterForeground(_ application: UIApplication) 
    
    func applicationWillTerminate(_ application: UIApplication) 
    
    func applicationDidBecomeActive(_ application: UIApplication) 
        UIApplication.shared.applicationIconBadgeNumber = 0
    


    //MARK: Local Notification Methods Starts here

    //Prepare New Notificaion with deatils and trigger
    func scheduleNotification(notificationType: String) 

        //Compose New Notificaion
        let content = UNMutableNotificationContent()
        let categoryIdentifire = "Delete Notification Type"
        content.sound = UNNotificationSound.default
        content.body = "This is example how to send " + notificationType
        content.badge = 1
        content.categoryIdentifier = categoryIdentifire

        //Add attachment for Notification with more content
        if (notificationType == "Local Notification with Content")
        
            let imageName = "Apple"
            guard let imageURL = Bundle.main.url(forResource: imageName, withExtension: "png") else  return 
            let attachment = try! UNNotificationAttachment(identifier: imageName, url: imageURL, options: .none)
            content.attachments = [attachment]
        

        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
        let identifier = "Local Notification"
        let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)

        notificationCenter.add(request)  (error) in
            if let error = error 
                print("Error \(error.localizedDescription)")
            
        

        //Add Action button the Notification
        if (notificationType == "Local Notification with Action")
        
            let snoozeAction = UNNotificationAction(identifier: "Snooze", title: "Snooze", options: [])
            let deleteAction = UNNotificationAction(identifier: "DeleteAction", title: "Delete", options: [.destructive])
            let category = UNNotificationCategory(identifier: categoryIdentifire,
                                                  actions: [snoozeAction, deleteAction],
                                                  intentIdentifiers: [],
                                                  options: [])
            notificationCenter.setNotificationCategories([category])
        
    

    //Handle Notification Center Delegate methods
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) 
        completionHandler([.alert, .sound])
    

    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) 
        if response.notification.request.identifier == "Local Notification" 
            print("Handling notifications with the Local Notification Identifier")
        
        completionHandler()
    

ViewController

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource 

    var appDelegate = UIApplication.shared.delegate as? AppDelegate
    let notifications = ["Simple Local Notification",
                         "Local Notification with Action",
                         "Local Notification with Content",]

    override func viewDidLoad() 
        super.viewDidLoad()
    

    // MARK: - Table view data source

     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return notifications.count
    

     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = notifications[indexPath.row]
        return cell
    

     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        let notificationType = notifications[indexPath.row]
        let alert = UIAlertController(title: "",
                                      message: "After 5 seconds " + notificationType + " will appear",
                                      preferredStyle: .alert)
        let okAction = UIAlertAction(title: "Okay, I will wait", style: .default)  (action) in
            self.appDelegate?.scheduleNotification(notificationType: notificationType)
        
        alert.addAction(okAction)
        present(alert, animated: true, completion: nil)
    

【讨论】:

令人印象深刻!好教程【参考方案5】:
- (void)applicationDidEnterBackground:(UIApplication *)application

   UILocalNotification *notification = [[UILocalNotification alloc]init];
   notification.repeatInterval = NSDayCalendarUnit;
   [notification setAlertBody:@"Hello world"];
   [notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:1]];
   [notification setTimeZone:[NSTimeZone  defaultTimeZone]];
   [application setScheduledLocalNotifications:[NSArray arrayWithObject:notification]];

这是可行的,但在 iOS 8.0 及更高版本中,您的应用程序必须使用 -[UIApplication registerUserNotificationSettings:] 注册用户通知,然后才能安排和呈现 UILocalNotifications,不要忘记这一点。

【讨论】:

-[UIApplication registerUserNotificationSettings:] 将覆盖推送通知设置。所以如果使用推送可操作通知请小心。【参考方案6】:

iOS 8 及以上用户,请在 App delegate 中包含此功能以使其正常工作。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

    if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)])
    
        [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
    

    return YES;

然后添加这行代码会有所帮助,

- (void)applicationDidEnterBackground:(UIApplication *)application

    UILocalNotification *notification = [[UILocalNotification alloc]init];
    notification.repeatInterval = NSDayCalendarUnit;
    [notification setAlertBody:@"Hello world"];
    [notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:1]];
    [notification setTimeZone:[NSTimeZone  defaultTimeZone]];
    [application setScheduledLocalNotifications:[NSArray arrayWithObject:notification]];


【讨论】:

【参考方案7】:
-(void)kundanselect

    NSMutableArray *allControllers = [[NSMutableArray alloc] initWithArray:self.navigationController.viewControllers];
    NSArray *allControllersCopy = [allControllers copy];
    if ([[allControllersCopy lastObject] isKindOfClass: [kundanViewController class]]) 
    
        [[NSNotificationCenter defaultCenter]postNotificationName:@"kundanViewControllerHide"object:nil userInfo:nil];
    
    else
    
        [[NSUserDefaults standardUserDefaults] setInteger:4 forKey:@"selected"];
        [self performSegueWithIdentifier:@"kundansegue" sender:self];
    

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(ApparelsViewControllerHide) name:@"ApparelsViewControllerHide" object:nil];

【讨论】:

【参考方案8】:

我假设您已请求授权并注册您的应用以获取通知。

这是创建本地通知的代码

@available(iOS 10.0, *)
    func send_Noti()
    
        //Create content for your notification 
        let content = UNMutableNotificationContent()
        content.title = "Test"
        content.body = "This is to test triggering of notification"

        //Use it to define trigger condition
        var date = DateComponents()
        date.calendar = Calendar.current
        date.weekday = 5 //5 means Friday
        date.hour = 14 //Hour of the day
        date.minute = 10 //Minute at which it should be sent


        let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
        let uuid = UUID().uuidString
        let req = UNNotificationRequest(identifier: uuid, content: content, trigger: trigger)

        let notificationCenter = UNUserNotificationCenter.current()
        notificationCenter.add(req)  (error) in
            print(error)
        
    

【讨论】:

以上是关于如何创建本地通知?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用后台模式从本地 Web 服务器创建本地通知

接收到本地通知数据后如何创建使用目标 c 传递给主视图控制器?

如何在swift 3中每天在特定时间触发本地通知

Swift:在每天设定的时间之间创建重复的本地通知

iOS 10:如何在特定日期触发后重复本地通知?

iOS创建本地通知和删除对应的通知,工作日通知