Yêu cầu sự cho phép của người dùng để nhận UILocalNotutions trong iOS 8


115

Tôi đã thiết lập thông báo cục bộ trong Đại biểu ứng dụng bằng cách sử dụng:

- (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]];
}

Khi tôi chạy ứng dụng và sau đó thoát nó, tôi nhận được thông báo lỗi:

2014-06-07 11: 14: 16,663 CCA-TV [735: 149070] Cố gắng lên lịch thông báo địa phương {ngày cháy = Thứ Bảy, ngày 7 tháng 6 năm 2014 lúc 11:14:21 Giờ ban ngày Thái Bình Dương, múi giờ = America / Los_Angele (PDT) offset -25200 (Ánh sáng ban ngày), khoảng thời gian lặp lại = 0, số lần lặp lại = UILocalNotificationInfiniteRepeatCount, ngày cháy tiếp theo = Thứ Bảy, ngày 7 tháng 6 năm 2014 lúc 11:14:21 Giờ ban ngày Thái Bình Dương, thông tin người dùng = (null)} với cảnh báo nhưng chưa nhận được sự cho phép của người dùng để hiển thị cảnh báo

Làm thế nào tôi có thể có được sự cho phép cần thiết để hiển thị các cảnh báo?


1
Tôi nghĩ rằng ứng dụng đã từ chối quyền một lần, bạn có thể thử bật từ Cài đặt. Nhưng bằng cách này, UILocalNotification không cần sự cho phép của người dùng ..
iphonic

Hãy thử registerUserNotificationSettings. Nếu là iOS 8, chủ đề này sẽ trả lời câu hỏi của bạn. Nhưng, g phía trước có một cái nhìn - stackoverflow.com/questions/24006998/
raurora

Câu trả lời:


237

Vì iOS 8, bạn cần phải xin phép người dùng để hiển thị thông báo từ ứng dụng của mình, điều này áp dụng cho cả thông báo từ xa / đẩy và cục bộ. Trong Swift bạn có thể làm như thế này,

Cập nhật cho 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.
    }

Cú pháp khách quan C cũng rất giống nhau.

- (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;
}

Để kiểm tra các loại thông báo hiện đã đăng ký, bạn có thể sử dụng phương thức của lớp UIApplication,

- (UIUserNotificationSettings *)currentUserNotificationSettings

Vì vậy, nếu người dùng đã nói không với ứng dụng của bạn thì chức năng này sẽ trả về một cài đặt mà không có bất kỳ loại nào trong đó.

Tôi đã viết một hướng dẫn về điều này, bạn có thể thấy nó ở đây .


1
Nếu người dùng từ chối cấp phép, làm thế nào để bạn xác định điều này sau đó theo chương trình?
jjxtra

@sediteshwaran Khi tôi sử dụng mã này, Nó hoạt động tốt với trình giả lập với iOS8. Tôi muốn mục tiêu triển khai ứng dụng của tôi bắt đầu từ iOS7. Vì vậy, khi tôi chạy mã này trên thiết bị iOS7, tôi gặp lỗi này : dyld: Symbol not found: _OBJC_CLASS_$_UIUserNotificationSettings. Có cách nào khác trong Swift để yêu cầu người dùng cấp phép để hoạt động trong iOS7 không? xin vui lòng giúp đỡ.
Raghavendra

@Raghav UIUserNotificationS Settings chỉ khả dụng từ iOS 8 và những gì bạn đang đối mặt là hành vi đúng. Bạn không nên sử dụng tính năng này trong iOS 7.
Sediteshwaran

1
-1 để kiểm tra UIDevice phiên bản iOS. stackoverflow.com/a/25735175/1226304 câu trả lời có cách tiếp cận tốt hơn để làm điều này.
derpoliuk

3
@derpoliuk Cập nhật như trong câu trả lời vì lợi ích của mọi người, ok ??
Sediteshwaran

38

Đặt mã này trong trình điều khiển xem nơi đầu tiên bạn sẽ lập trình các thông báo (nếu bạn lập trình chúng khi khởi chạy, thì nó sẽ như vậy application:didFinishLaunchingWithOptions:):

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

Trong Swift:

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

Các giải pháp kiểm tra số phiên bản hệ thống là tối ưu phụ và dễ bị lỗi.


Tôi sẽ sử dụng application.respondsToSelector(Selector("registerUserNotificationSettings"))if ([application respondsToSelector:@selector(registerUserNotificationSettings:)])
derpoliuk

7
Vâng, đó chỉ là vì bạn đang sử dụng nó bên trong application:didFinishLaunchingWithOptions:cung cấp một applicationđối tượng tiện dụng :)
KPM

18

Hãy thử điều này cho 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];
  }
}

Dành cho 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

Tôi chỉ phải đối mặt với cùng một vấn đề. Có vẻ như trong iOS 8 chúng ta cần thực hiện một bước bổ sung, thường được thực hiện bên trong:

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

Bạn có thể sử dụng mã này nếu bạn muốn giữ cho nó tương thích ngược:

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

Hệ thống sẽ ghi nhớ quyết định, và sẽ chỉ hỏi một lần.


Tốt hơn để kiểm tra phiên bản iOS với mã này nếu ([[UIDevice currentDevice] .systemVersion floatValue] <10)
Mehul Chuahan

1

** Thông báo cục bộ với ba hành động nút cho iOS8 +

// Nút: TÔI NHÌN NÓ, NHỚ 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()

        }

    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.