web-dev-qa-db-ja.com

デバッグ出力に、アプリケーションバッジの許可を求める必要があると記載されています

タイマーの実行中にバックグラウンドで実行できる非常にシンプルなアプリを作成しました。アプリがまだバックグラウンドにあり、タイマーが終了すると、ローカル通知が送信され、アプリケーションバッジが1に設定されます。アプリを起動すると、常にアプリがクリアされます。 Xcode 6をインストールした後、アプリを起動するたびに次のメッセージが表示されることに気付きました。

「アプリケーションアイコンにバッジを付けようとしていますが、アプリケーションにバッジを付ける許可をユーザーから受け取っていません」

明らかに、そのテキストは、バッジを0に設定してクリアするアプリによって生成されます。これらの権限をどこに設定または要求しますか?現在、プッシュ通知と見なされていますか?


問題は修正され、回答は以下に掲載されています。肝心なのは、あらゆる種類の通知についてユーザーから確認を得る必要があるということですが、これは以前はプッシュ通知にのみ当てはまりました。

18
Departamento B

結局、アプリケーションバッジをまったく使用しなくなり、その間にここに投稿した最初のコードスニペットを放棄しました。この質問を読んだりコメントしたりする人がまだいるので、現在の解決策もここに追加します。 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ファイル:

#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];

これを行うことで、権限を1つのリクエストにスタックすることもできます。

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

29
Departamento B