Подтвердить что ты не робот

В отладочной записи упоминается, что я должен запросить разрешение на использование приложения

Я сделал очень простое приложение, которое может работать в фоновом режиме во время работы таймера. Если приложение все еще находится в фоновом режиме, и таймер заканчивается, он отправляет локальное уведомление и устанавливает значок приложения в 1. Когда я запускаю приложение, я всегда его очищаю. Я заметил, что после установки Xcode 6 я получал это сообщение каждый раз, когда запускал приложение:

"Попытка присвоить значку приложения, но не получила разрешения от пользователя на значок приложения

Ясно, что текст создается моим приложением, устанавливая значок на 0, чтобы очистить его. Где я могу установить эти разрешения или запросить их? Рассматривается ли это теперь как push-уведомление?


Проблема была исправлена, и ответ опубликован ниже. Суть в том, что вам нужно получить подтверждение от пользователя для любого уведомления, в то время как это было правдой только для push-уведомлений.

4b9b3361

Ответ 1

Я вообще не использовал значок приложения, и я отказался от исходного фрагмента кода, который я опубликовал здесь в среднем. Поскольку люди по-прежнему читают и комментируют этот вопрос, я также добавлю свое текущее текущее решение. Он содержит проверки для iOS7, но я не использую метод обратного вызова. Также эта версия не просто запрашивает разрешение на использование приложения.

Решение

UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];

Это то, что я использую сейчас

.h файл

#import <Foundation/Foundation.h>

@interface NotificationPermissionHandler : NSObject

+ (void)checkPermissions;
+ (bool)canSendNotifications;

@end

.m file:

#import "NotificationPermissionHandler.h"

@implementation NotificationPermissionHandler

static const UIUserNotificationType USER_NOTIFICATION_TYPES_REQUIRED = UIUserNotificationTypeAlert | UIUserNotificationTypeSound;
static const UIRemoteNotificationType REMOTE_NOTIFICATION_TYPES_REQUIRED = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;

+ (void)checkPermissions;
{
    bool isIOS8OrGreater = [[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)];
    if (!isIOS8OrGreater)
    {
        [NotificationPermissionHandler iOS7AndBelowPermissions];
        return;
    }

    [NotificationPermissionHandler iOS8AndAbovePermissions];
}

+ (void)iOS7AndBelowPermissions
{
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:REMOTE_NOTIFICATION_TYPES_REQUIRED];
}

+ (void)iOS8AndAbovePermissions;
{
    if ([NotificationPermissionHandler canSendNotifications])
    {
        return;
    }

    UIUserNotificationSettings* requestedSettings = [UIUserNotificationSettings settingsForTypes:USER_NOTIFICATION_TYPES_REQUIRED categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:requestedSettings];
}

+ (bool)canSendNotifications;
{
    UIApplication *application = [UIApplication sharedApplication];
    bool isIOS8OrGreater = [application respondsToSelector:@selector(currentUserNotificationSettings)];

    if (!isIOS8OrGreater)
    {
        // We actually just don't know if we can, no way to tell programmatically before iOS8
        return true;
    }

    UIUserNotificationSettings* notificationSettings = [application currentUserNotificationSettings];
    bool canSendNotifications = notificationSettings.types == USER_NOTIFICATION_TYPES_REQUIRED;

    return canSendNotifications;
}

@end

Это было мое первое решение

Я сохранил это как ссылку на начальную дискуссию. Этот код не поддерживается.

UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];

Вы также можете установить разрешения стека в один запрос, выполнив следующие действия:

UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];

Также, поскольку iOS 8 позволяет выяснить, какие предупреждения разрешены пользователем:

UIUserNotificationSettings* notificationSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
if (notificationSettings.types == UIUserNotificationTypeBadge)
{
     // change the badge
}

В итоге я использовал этот код:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if (![defaults objectForKey:@"first_run"])
    {
        [self setDefaults];
    }

    [self askAlertPermissions];

    if ([self canChangeBadge])
    {
         [self setBadge:0];
    }

    return YES;
}

- (void)setDefaults;
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    [defaults setObject:[NSNumber numberWithBool:NO] forKey:@"alerts_allowed"];
    [defaults setObject:[NSDate date] forKey:@"first_run"];
    // More defaults if needed

    [defaults synchronize];
}

- (void)askAlertPermissions;
{
    UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
}

// This will be called only after confirming your settings
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings;
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    // There is also a built in method to find out if the user has appropriate settings, you might want to use that instead if you just want to know what the setting is
    [defaults setObject:[NSNumber numberWithBool:YES] forKey:@"alerts_allowed"];
}

- (bool)canChangeBadge;
{
    UIUserNotificationSettings* notificationSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
    return notificationSettings.types == UIUserNotificationTypeBadge;
}

Подробнее читайте:

https://developer.apple.com/library/content/releasenotes/General/WhatsNewIniOS/Articles/iOS8.html

https://developer.apple.com/documentation/uikit/uiapplication