iOS 10中UI本地通知已经被弃用

48

也许这是提前的问题,但我想知道在iOS 10中可以用什么替代UILocalNotification。我正在开发一个目标系统为iOS 8的应用程序,那么使用UILocalNotification是否可以呢?

4个回答

107

是的,你可以使用 UILocalNotification,旧的API在iOS 10上也可以正常工作,但最好改用User Notifications框架中的API。此外,还有一些新功能,只能在iOS 10 User Notifications框架中使用。

远程通知也是如此,更多信息请参见:这里

新功能:

  • 现在你可以在应用程序前台显示警报、声音或增加徽章了。
  • 现在当用户点击(或滑动)操作按钮时,甚至当应用程序已经被杀死时,你可以在一个地方处理所有事件。
  • 支持3D Touch而不是滑动手势。
  • 现在你只需要一行代码就可以删除特定的本地通知了。
  • 支持具有自定义UI的富通知。

我们很容易将UILocalNotification API转换为iOS 10 User Notifications 框架的API,它们非常相似。

我在这里编写了一个演示,展示如何同时使用新旧API:iOS 10适配技巧

例如,

使用Swift实现:

  1. import UserNotifications

    ///    Notification become independent from UIKit
    import UserNotifications
    
  2. 请求本地通知的授权

  3.     let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
            // Enable or disable features based on authorization.
        }
    
  4. 安排本地通知

  5. 更新应用程序图标徽章数量

    @IBAction  func triggerNotification(){
        let content = UNMutableNotificationContent()
        content.title = NSString.localizedUserNotificationString(forKey: "Elon said:", arguments: nil)
        content.body = NSString.localizedUserNotificationString(forKey: "Hello Tom!Get up, let's play with Jerry!", arguments: nil)
        content.sound = UNNotificationSound.default()
        content.badge = UIApplication.shared().applicationIconBadgeNumber + 1;
        content.categoryIdentifier = "com.elonchan.localNotification"
        // Deliver the notification in 60 seconds.
        let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 60.0, repeats: true)
        let request = UNNotificationRequest.init(identifier: "FiveSecond", content: content, trigger: trigger)
    
        // Schedule the notification.
        let center = UNUserNotificationCenter.current()
        center.add(request)
    }
    
    @IBAction func stopNotification(_ sender: AnyObject) {
        let center = UNUserNotificationCenter.current()
        center.removeAllPendingNotificationRequests()
        // or you can remove specifical notification:
        // center.removePendingNotificationRequests(withIdentifiers: ["FiveSecond"])
    }
    

Objective-C实现:

  1. 导入UserNotifications

// Notifications are independent from UIKit
#import <UserNotifications/UserNotifications.h>
  • 请求本地通知的授权

  • UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert)
                          completionHandler:^(BOOL granted, NSError * _Nullable error) {
                              if (!error) {
                                  NSLog(@"request authorization succeeded!");
                                  [self showAlert];
                              }
                          }];
    
  • 安排本地通知

  • 更新应用程序图标徽章数字

    UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
    content.title = [NSString localizedUserNotificationStringForKey:@"Elon said:"
                                                        arguments:nil];
    content.body = [NSString localizedUserNotificationStringForKey:@"Hello Tom!Get up, let's play with Jerry!"
                                                       arguments:nil];
    content.sound = [UNNotificationSound defaultSound];
    
    // 4. update application icon badge number
    content.badge = [NSNumber numberWithInteger:([UIApplication sharedApplication].applicationIconBadgeNumber + 1)];
    // Deliver the notification in five seconds.
    UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger
                                                triggerWithTimeInterval:5.f
                                                repeats:NO];
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"FiveSecond"
                                                                        content:content
                                                                        trigger:trigger];
    /// 3. schedule localNotification
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        if (!error) {
            NSLog(@"add NotificationRequest succeeded!");
        }
    }];
    
  • 更新

    应用程序因未捕获的异常“NSInternalInconsistencyException”而终止,原因是“如果重复,则时间间隔必须至少为60”

    let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 60, repeats: true)
    

    在 "center.requestAuthorization([.alert, .sound])" 中,您缺少参数名称,应该是 "center.requestAuthorization(options: [.alert, .sound])"。 - MQoder
    我在我的应用程序中完全按照上面的方式设置了这个。通知只出现了一次。我再次运行它并使用不同的通知,现在我没有收到任何通知。有什么想法吗? - Nate4436271
    didReceiveLocalNotification在iOS 10.0和10.1 GA中已经停止工作。有没有人在不迁移到新的通知框架的情况下使其正常工作? - Billy
    谢谢,但是如果您也想支持iOS 9设备怎么办? - Zennichimaro
    2
    @Zennichimaro:你可以在你的代码中同时实现UILocalNotification(iOS 9)和UNNotificationRequest(iOS 10)。使用以下代码来测试当前运行的iOS版本:if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber10_0) { \\ 运行 iOS 10 代码 } else { // 运行 iOS 9 代码 } - koen
    有人尝试在MacOS应用程序中使通知工作吗? - Dominique

    9

    苹果又做到了,正确的实现方式是:AppDelegate.swift

    if #available(iOS 10.0, *) {
            let center = UNUserNotificationCenter.currentNotificationCenter()
            center.requestAuthorizationWithOptions([.Alert, .Sound]) { (granted, error) in
                // Enable or disable features based on authorization.
            }
        } else {
            // Fallback on earlier versions
        }
    

    不要忘记添加。
    import UserNotifications
    

    3

    swift 4

    if #available(iOS 10.0, *) {
            let center = UNUserNotificationCenter.current()
            center.requestAuthorization(options: [.alert, .badge, .sound])  { (granted, error) in
                // Enable or disable features based on authorization.
            }
        } else {
            // REGISTER FOR PUSH NOTIFICATIONS
            let notifTypes:UIUserNotificationType  = [.alert, .badge, .sound]
            let settings = UIUserNotificationSettings(types: notifTypes, categories: nil)
            application.registerUserNotificationSettings(settings)
            application.registerForRemoteNotifications()
            application.applicationIconBadgeNumber = 0
    
        }
    

    MARK: - 用于推送通知的代理

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let installation = PFInstallation.current()
        installation?.setDeviceTokenFrom(deviceToken)
        installation?.saveInBackground(block: { (succ, error) in
            if error == nil {
                print("DEVICE TOKEN REGISTERED!")
            } else {
                print("\(error!.localizedDescription)")
            }
        })
    }
    
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("application:didFailToRegisterForRemoteNotificationsWithError: %@", error)
    }
    
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
        print("\(userInfo)")
    
        // PFPush.handle(userInfo)
        if application.applicationState == .inactive {
            PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(inBackground: userInfo, block: nil)
        }
    }
    

    2

    Objective-C中的iOS 10本地通知。

    如果您已经编程一段时间,我相信您很熟悉UILocalNotification类,现在随着iOS 10的到来,您会发现UILocalNotification已被弃用。有关详细实现,请访问此博客文章


    我们能用 Swift 实现吗? - King

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接