iOS 8에서 UILocalNotification을 수신하기위한 사용자 권한 요청


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
}

스위프트 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

@satheeshwaran이 코드를 사용하면 iOS8의 시뮬레이터에서 잘 작동합니다. iOS7부터 내 앱의 배포 대상을 원했습니다. 따라서 iOS7 장치에서이 코드를 실행하면이 오류가 발생 dyld: Symbol not found: _OBJC_CLASS_$_UIUserNotificationSettings합니다.. iOS7에서 작업하기 위해 사용자에게 권한을 요청하는 다른 방법이 Swift에 있습니까? 도와주세요.
Raghavendra 2014-08-23

@Raghav UIUserNotificationSettings는 iOS 8에서만 사용할 수 있으며 직면 한 것은 올바른 동작입니다. iOS 7에서는 사용하지 마십시오.
Satheeshwaran 2014-08-23

1
-1은 iOS 버전 UIDevice를 확인합니다. stackoverflow.com/a/25735175/1226304 답변에는 더 나은 접근 방식이 있습니다.
derpoliuk 2014 년

3
@derpoliuk 모두의 이익에 대한 답변으로 업데이트되었습니다.
Satheeshwaran

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

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

시스템은 결정을 기억하고 한 번만 묻습니다.


개선이 코드 iOS 버전을 확인한다 ([UIDevice currentDevice] .systemVersion하는 FloatValue] <10)의 경우
Mehul Chuahan

1

** iOS8 +에 대한 세 개의 버튼 동작이있는 로컬 알림

// 버튼 : I TOOK IT, REMIND LATER, SKIP IT **

        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.