iOS 8でUILocalNotificationsを受信するためのユーザー権限を要求する


115

これを使用して、App Delegateでローカル通知を設定しました。

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    UILocalNotification *notification = [[UILocalNotification alloc]init];
    [notification setAlertBody:@"Watch the Latest Episode of CCA-TV"];
    [notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:5]];
    [notification setTimeZone:[NSTimeZone defaultTimeZone]];
    [application setScheduledLocalNotifications:[NSArray arrayWithObject:notification]];
}

アプリを実行して終了すると、次のエラーメッセージが表示されます。

2014-06-07 11:14:16.663 CCA-TV [735:149070] ローカル通知をスケジュールしようとしています{発射日= 2014年6月7日土曜日11:14:21太平洋夏時間、タイムゾーン= America / Los_Angeles (PDT)オフセット-25200(夏時間)、繰り返し間隔= 0、繰り返しカウント= UILocalNotificationInfiniteRepeatCount、次の発射日= 2014年6月7日土曜日11:14:21太平洋夏時間、ユーザー情報=(null)} アラート付きユーザーからアラートを表示する許可を受け取っていません

アラートを表示するために必要な権限を取得するにはどうすればよいですか?


1
アプリが許可を一度拒否したと思います。設定から有効にしてみてください。しかし、道UILocalNotificationでユーザー権限..必要はありません
iphonic

お試しくださいregisterUserNotificationSettings。iOS 8だったら、このスレッドはあなたの質問に答えていただろう。-しかし、Gは先に見ていstackoverflow.com/questions/24006998/...
raurora

回答:


237

iOS 8ではアプリからの通知を表示する許可をユーザーに要求する必要があるため、これはリモート/プッシュ通知とローカル通知の両方に適用されます。Swiftでは、次のように実行できます。

Swift 2.0のアップデート

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
    // Override point for customization after application launch.
    if(UIApplication.instancesRespondToSelector(Selector("registerUserNotificationSettings:")))
    {
        let notificationCategory:UIMutableUserNotificationCategory = UIMutableUserNotificationCategory()
        notificationCategory.identifier = "INVITE_CATEGORY"
        notificationCategory.setActions([replyAction], forContext: UIUserNotificationActionContext.Default)

        //registerting for the notification.
        application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes:[.Sound, .Alert, .Badge], categories: nil))
    }
    else
    {
       //do iOS 7 stuff, which is pretty much nothing for local notifications.
    }
    return true
}

Swift 3.2

if(UIApplication.instancesRespond(to: #selector(UIApplication.registerUserNotificationSettings(_:)))){
     let notificationCategory:UIMutableUserNotificationCategory = UIMutableUserNotificationCategory()
     notificationCategory.identifier = "INVITE_CATEGORY"
     notificationCategory.setActions([replyAction], forContext: UIUserNotificationActionContext.Default)

     //registerting for the notification.
        application.registerUserNotificationSettings(UIUserNotificationSettings(types:[.sound, .alert, .badge], categories: nil))
}
else{
        //do iOS 7 stuff, which is pretty much nothing for local notifications.
    }

Objective Cの構文も非常に似ています。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]){
        [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
    }
    // Override point for customization after application launch.
    return YES;
}

現在登録されている通知タイプを確認するには、UIApplicationクラスのメソッドを使用できます。

- (UIUserNotificationSettings *)currentUserNotificationSettings

そのため、ユーザーがアプリにノーと言った場合、この関数はタイプのない設定を返す必要があります。

これについてのチュートリアルを書いたので、ここで確認できます


1
ユーザーが許可を拒否した場合、プログラムでこれを後でどのように決定しますか?
jjxtra 2014年

@satheeshwaranこのコードを使用すると、iOS8のシミュレータで問題なく動作します。iOS7からアプリの展開ターゲットが必要でした。そのため、iOS7デバイスでこのコードを実行すると、次のエラーが発生しますdyld: Symbol not found: _OBJC_CLASS_$_UIUserNotificationSettings。SwiftでiOS7で作業するためにユーザーに権限を要求する方法は他にありますか?助けてください。
Raghavendra 2014

@Raghav UIUserNotificationSettingsはiOS 8からのみ使用可能であり、直面しているのは正しい動作です。あなたは、iOS 7でこれを使用しないでください
Satheeshwaran

1
iOSバージョンUIDeviceをチェックする場合は-1。 stackoverflow.com/a/25735175/1226304答えはこれを行うためのより良いアプローチを持っています。
derpoliuk 2014

3
@derpoliukみんなの利益のために答えのように更新されました、いいですか?
Satheeshwaran 2014

38

このコードを、最初に通知をプログラムするビューコントローラーに配置します(起動時にそれらをプログラムする場合は、次のようになりますapplication:didFinishLaunchingWithOptions:)。

if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
    [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeSound categories:nil]];
}

Swiftの場合:

if(UIApplication.instancesRespondToSelector(Selector("registerUserNotificationSettings:"))) {
    UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotificationSettings(forTypes: .Alert | .Sound, categories: nil))
}

システムバージョン番号に対してテストするソリューションは、最適ではなく、エラーが発生しやすくなります。


私は使用application.respondsToSelector(Selector("registerUserNotificationSettings"))しますif ([application respondsToSelector:@selector(registerUserNotificationSettings:)])
derpoliuk '19

7
まあそれはあなたがapplication:didFinishLaunchingWithOptions:便利なapplicationオブジェクトを提供する中でそれを使っているからだけです:)
KPM

18

Objective-Cでこれを試してください。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:    (NSDictionary *)launchOptions
{
// are you running on iOS8?
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) 
  {
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeAlert|UIUserNotificationTypeSound) categories:nil];
    [application registerUserNotificationSettings:settings];
  } 
else // iOS 7 or earlier
  {
    UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
    [application registerForRemoteNotificationTypes:myTypes];
  }
}

Swiftの場合:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
// Override point for customization after application launch.
 if(UIApplication.instancesRespondToSelector(Selector("registerUserNotificationSettings:")))
 {
    application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: UIUserNotificationType.Sound | UIUserNotificationType.Alert | UIUserNotificationType.Badge, categories: nil))
 }
 else
 {
    //
 }
return true
}

5

私は同じ問題に直面しました。iOS 8では、通常は内部で追加の手順を実行する必要があるようです。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { /*...*/ }

下位互換性を維持したい場合は、このコードを使用できます。

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
    if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)])
    {
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]];
    }
#endif

システムは決定を記憶し、一度だけ尋ねます。


([[UIDevice currentDevice] .systemVersion floatValue] <10)の場合、このコードでiOSバージョンをチェックする方が良い
Mehul Chuahan

1

** iOS8以降の3つのボタンアクションによるローカル通知

//ボタン:私はそれを取りました、後で注意してください、それをスキップしてください**

        let completeAction = UIMutableUserNotificationAction()
        completeAction.identifier = "COMPLETE_TODO"
        completeAction.title = "I TOOK IT"
        completeAction.activationMode = .Background
        completeAction.destructive = true
        completeAction.authenticationRequired = false

        let remindAction = UIMutableUserNotificationAction()
        remindAction.identifier = "REMIND_TODO"
        remindAction.title = "REMIND LATER"
        remindAction.activationMode = .Background
        remindAction.destructive = false
        //  remindAction.authenticationRequired = false

        let skipAction = UIMutableUserNotificationAction()
        skipAction.identifier = "SKIP_TODO"
        skipAction.title = "SKIP IT"
        skipAction.activationMode = .Background
        skipAction.destructive = false
        skipAction.authenticationRequired = false


        let todoCategory = UIMutableUserNotificationCategory()
        todoCategory.identifier = "TODO_CATEGORY"
        todoCategory.setActions([completeAction, remindAction, skipAction], forContext: .Default)
        todoCategory.setActions([completeAction,remindAction,skipAction], forContext: .Minimal)


        if application.respondsToSelector("isRegisteredForRemoteNotifications")
        {

            let categories = NSSet(array: [todoCategory,todoVideoCategory])
            let types:UIUserNotificationType = ([.Alert, .Sound, .Badge])

            let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: types, categories: categories as? Set<UIUserNotificationCategory>)

            application.registerUserNotificationSettings(settings)
            application.registerForRemoteNotifications()

        }

    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.