IOS 10.2简单警报和徽章上的UserNotifications问题 [英] IOS 10.2 UserNotifications problems on simple Alert and Badge

查看:212
本文介绍了IOS 10.2简单警报和徽章上的UserNotifications问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在撰写这篇文章之前,我对UserNotification Framework进行了大量研究,取代了IOS 10中的UILocalNotification。我也按照本教程学习了有关这一新功能的所有内容: http://useyourloaf.com/blog/local-notifications-with-ios-10/

Before writing this post I made a lot of researches on UserNotification Framework, that substituted UILocalNotification in IOS 10. I also followed this tutorial to learn everything about this new feature : http://useyourloaf.com/blog/local-notifications-with-ios-10/.

今天我遇到了很多麻烦来实现这些琐碎的通知,因为它是最近的新功能,我找不到任何解决方案(特别是在目标C中)!我目前有2个不同的通知,一个提醒,一个徽章更新

Today I'm encountering so much troubles to implement such trivial Notifications and since it's a recent new feature I couldn't find any solutions (especially in objective C)! I currently have 2 different notifications, one Alert and one Badge updtate.

在将手机从IOS 10.1升级到10.2之前,我在Appdelegate上发出警报,当用户手动关闭应用程序时立即触发:

Before Updating my Phone from IOS 10.1 to 10.2, I made an alert on the Appdelegate that is triggered immediatly whenever the user closes the app manually:

-(void)applicationWillTerminate:(UIApplication *)application {
        NSLog(@"applicationWillTerminate");

        // Notification terminate
        [self registerTerminateNotification];
}

// Notification Background terminate 
-(void) registerTerminateNotification {
    // the center
    UNUserNotificationCenter * notifCenter = [UNUserNotificationCenter currentNotificationCenter];

    // Content
    UNMutableNotificationContent *content = [UNMutableNotificationContent new];
    content.title = @"Stop";
    content.body = @"Application closed";
    content.sound = [UNNotificationSound defaultSound];
    // Trigger 
    UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO];
    // Identifier
    NSString *identifier = @"LocalNotificationTerminate";
    // création de la requête
    UNNotificationRequest *terminateRequest = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
    // Ajout de la requête au center
    [notifCenter addNotificationRequest:terminateRequest withCompletionHandler:^(NSError * _Nullable error) {
        if (error != nil) {
            NSLog(@"Error %@: %@",identifier,error);
        }
    }];
}

在IOS 10.2之前它工作正常,当我手动关闭应用程序时,警报出现了。但是自从我更新到IOS 10.2后,没有任何理由显示任何内容,我没有改变任何东西,我看不出有什么遗漏..

Before IOS 10.2 it worked just fine, when I closed the app manually, an alert showed up. But since I updated to IOS 10.2, nothing shows up without any reason, I havent change anything, and I can't see what's missing..

我也试过(这次仅在IOS 10.2中)在我的应用程序图标上实现徽章,该图标工作正常,直到我尝试删除它。以下是执行此操作的函数:

I also tried (only in IOS 10.2 this time) to implement badging on my app icon which worked just fine, until I tried to remove it. Here is the function that does it :

+(void) incrementBadgeIcon {
    // only increment if application is in background 
    if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground){

        NSLog(@"increment badge");

        // notif center 
        UNUserNotificationCenter *notifCenter = [UNUserNotificationCenter currentNotificationCenter];

        // Content
        UNMutableNotificationContent *content = [UNMutableNotificationContent new];
        content.badge = [NSNumber numberWithInt:1];
        // Trigger 
        UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO];
        // Identifier
        NSString *identifier = @"LocalNotificationIncrementBadge";
        // request
        UNNotificationRequest *incrementBadgeRequest = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
        // Ajout de la requête au center
        [notifCenter addNotificationRequest:incrementBadgeRequest withCompletionHandler:^(NSError * _Nullable error) {
            if (error != nil) {
                NSLog(@"Error %@: %@",identifier,error);
            }
        }];
    }
}

现在它不会增加徽章编号,因为它的名字应该建议,但它只是将徽章编号设置为1.文档说如果你将 content.badge 设置为0,它会将其删除,但这不起作用。我尝试使用其他数字,当我手动将其更改为2,3等时......它会发生变化,但如果我将其设置为0,则无效。

For now it does not increment the badge number, as it's name should suggest, but it just set the badge number to 1. Documentation says that if you set content.badge to 0, it removes it, but this does not work. I tried with other numbers, when I manually change it to '2', '3', etc... it changes, but if I set it to 0, it does not work.

此外,在我之前链接的教程中,它提到了几个函数: getPendingNotificationRequests:completionHandler: getDeliveredNotificationRequests:completionHandler:即可。我注意到,当我在调用 incrementBadgeIcon 之后立即调用这些函数时,如果content.badge设置为'1','2'等......它将出现在待处理通知列表中。但是,当我将其设置为0时,它不会出现在任何地方。我没有收到任何错误,Xcode中没有任何警告,我的应用程序徽章仍然存在。

Also, in the tutorial I linked earlier, it is mentionned several functions as getPendingNotificationRequests:completionHandler: and getDeliveredNotificationRequests:completionHandler:. I noticed that, when I call these functions right after calling incrementBadgeIcon, if the content.badge is set to '1', '2' etc... it appears in the pending notifications list. However, when I set it to 0, it does not appear anywhere. I get no error, no warning in Xcode, and my application badge still remain.

有谁知道如何修复这两个警报?

Does anyone know how I can fix these two Alerts?

提前感谢

PS:我还尝试使用 removeAllPendingNotificationRequests removeAllDeliveredNotifications 两者均未成功。

PS: I also tried to use removeAllPendingNotificationRequests and removeAllDeliveredNotifications for both without success.

推荐答案

关于提示:



您的应用可能是当您的本地通知触发时仍处于前台,因此您需要实现委托方法,以便通知执行任何操作。例如,在您的委托中定义此方法将允许通知显示警报,发出声音并更新徽章:

Regarding the alert:

It's possible that your app is still in the foreground when your local notification fires, so you'll need to implement a delegate method in order for the notification to do anything. For instance, defining this method in your delegate will allow the notification to display an alert, make a sound, and update the badge:

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



关于徽章:



我有观察到创建 UNMutableNotificationContent 对象并仅指定徽章值(作为NSNumber对象)适用于除0以外的所有徽章值(即,您无法以这种方式清除徽章) 。我没有找到任何关于为什么0的行为与任何其他值不同的文档,特别是因为.badge属性被定义为 NSNumber?,所以框架应该能够区分 nil (无变化)和 0 (清除徽章)。

Regarding the badge:

I have observed that creating a UNMutableNotificationContent object and specifying only the badge value (as an NSNumber object) works for all badge values except 0 (i.e., you cannot clear the badge in this way). I haven't found any documentation for why 0 would behave differently than any other value, especially since the .badge property is defined as an NSNumber?, so the framework should be able to differentiate between nil (no change) and 0 (clear the badge).

我已针对此提交了雷达

作为一种解决方法,我发现在 UNMutableNotificationContent title 属性>对象,徽章值为 NSNumber(值:0) 确实触发。如果缺少 title 属性,则不会触发。

As a work around, I've found that setting the title property on the UNMutableNotificationContent object, with a badge value of NSNumber(value: 0) does fire. If the title property is missing, it will not fire.

添加title属性仍然不会显示警报对于用户(更新:在iOS 11中不再是这种情况!),因此这是一种无需调用UIApplication对象即可将徽章值静默更新为0的方法(通过 UIApplication.shared.applicationIconBadgeNumber = 0 )。

Adding the title property still does not present an alert to the user (Update: this is no longer the case in iOS 11!), so this is a way to silently update the badge value to 0 without needing to invoke the UIApplication object (via UIApplication.shared.applicationIconBadgeNumber = 0).

这是我的示例项目中的全部代码; ViewController代码中有一个MARK,显示插入title属性的位置可以解决问题:

Here's the entirety of the code in my example project; there's a MARK in the ViewController code showing where inserting the title property resolves the problem:

//
//  AppDelegate.swift
//  userNotificationZeroBadgeTest
//
//  Created by Jeff Vautin on 1/3/17.
//  Copyright © 2017 Jeff Vautin. All rights reserved.
//

import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

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

        UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .sound]) { (success, error) -> Void in
            print("Badge auth: \(success)")
        }

        // For handling Foreground notifications, this needs to be assigned before finishing this method
        let vc = window?.rootViewController as! ViewController
        let center = UNUserNotificationCenter.current()
        center.delegate = vc

        return true
    }
}

//
//  ViewController.swift
//  userNotificationZeroBadgeTest
//
//  Created by Jeff Vautin on 1/3/17.
//  Copyright © 2017 Jeff Vautin. All rights reserved.
//

import UIKit
import UserNotifications

class ViewController: UIViewController, UNUserNotificationCenterDelegate {

    @IBAction func start(_ sender: Any) {
        // Reset badge directly (this always works)
        UIApplication.shared.applicationIconBadgeNumber = 0


        let center = UNUserNotificationCenter.current()

        // Schedule badge value of 1 in 5 seconds
        let notificationBadgeOneContent = UNMutableNotificationContent()
        notificationBadgeOneContent.badge = NSNumber(value: 1)
        let notificationBadgeOneTrigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 1*5, repeats: false)
        let notificationBadgeOneRequest = UNNotificationRequest.init(identifier: "1", content: notificationBadgeOneContent, trigger: notificationBadgeOneTrigger)
        center.add(notificationBadgeOneRequest)

        // Schedule badge value of 2 in 10 seconds
        let notificationBadgeTwoContent = UNMutableNotificationContent()
        notificationBadgeTwoContent.badge = NSNumber(value: 2)
        let notificationBadgeTwoTrigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 2*5, repeats: false)
        let notificationBadgeTwoRequest = UNNotificationRequest.init(identifier: "2", content: notificationBadgeTwoContent, trigger: notificationBadgeTwoTrigger)
        center.add(notificationBadgeTwoRequest)

        // Schedule badge value of 3 in 15 seconds
        let notificationBadgeThreeContent = UNMutableNotificationContent()
        notificationBadgeThreeContent.badge = NSNumber(value: 3)
        let notificationBadgeThreeTrigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 3*5, repeats: false)
        let notificationBadgeThreeRequest = UNNotificationRequest.init(identifier: "3", content: notificationBadgeThreeContent, trigger: notificationBadgeThreeTrigger)
        center.add(notificationBadgeThreeRequest)

        // Schedule badge value of 4 in 20 seconds
        let notificationBadgeFourContent = UNMutableNotificationContent()
        notificationBadgeFourContent.badge = NSNumber(value: 4)
        let notificationBadgeFourTrigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 4*5, repeats: false)
        let notificationBadgeFourRequest = UNNotificationRequest.init(identifier: "4", content: notificationBadgeFourContent, trigger: notificationBadgeFourTrigger)
        center.add(notificationBadgeFourRequest)

        // Schedule badge value of 0 in 25 seconds
        let notificationBadgeZeroContent = UNMutableNotificationContent()
        // MARK: Uncommenting this line setting title property will cause notification to fire properly.
        //notificationBadgeZeroContent.title = "Zero!"
        notificationBadgeZeroContent.badge = NSNumber(value: 0)
        let notificationBadgeZeroTrigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 5*5, repeats: false)
        let notificationBadgeZeroRequest = UNNotificationRequest.init(identifier: "0", content: notificationBadgeZeroContent, trigger: notificationBadgeZeroTrigger)
        center.add(notificationBadgeZeroRequest)
    }

    @IBAction func listNotifications(_ sender: Any) {
        let center = UNUserNotificationCenter.current()
        center.getDeliveredNotifications() { (notificationArray) -> Void in
            print("Delivered notifications: \(notificationArray)")
        }
        center.getPendingNotificationRequests() { (notificationArray) -> Void in
            print("Pending notifications: \(notificationArray)")
        }
    }

    // MARK: UNUserNotificationCenterDelegate

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

这篇关于IOS 10.2简单警报和徽章上的UserNotifications问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆