ขออนุญาตผู้ใช้เพื่อรับ UILocalNotifications ใน iOS 8


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] กำลังพยายามกำหนดเวลาการแจ้งเตือนในท้องถิ่น {วันที่เกิดเพลิงไหม้ = วันเสาร์ที่ 7 มิถุนายน 2014 เวลา 11:14:21 น. เวลาออมแสงแปซิฟิกเขตเวลา = อเมริกา / ลอส _ แอนเจลิส (PDT) ชดเชย -25200 (Daylight), ช่วงเวลาการทำซ้ำ = 0, การนับซ้ำ = UILocalNotificationInfiniteRepeatCount, วันที่ยิงครั้งต่อไป = วันเสาร์ที่ 7 มิถุนายน 2014 เวลา 11:14:21 เวลาออมแสงแปซิฟิกข้อมูลผู้ใช้ = (null)} พร้อมการแจ้งเตือน แต่ไม่ได้รับอนุญาตจากผู้ใช้ให้แสดงการแจ้งเตือน

ฉันจะขอสิทธิ์ที่จำเป็นเพื่อแสดงการแจ้งเตือนได้อย่างไร


1
ฉันคิดว่าแอปปฏิเสธสิทธิ์หนึ่งครั้งคุณสามารถลองเปิดใช้งานจากการตั้งค่า แต่โดยวิธีการที่ UILocalNotification ไม่จำเป็นต้องได้รับอนุญาตจากผู้ใช้ ..
iphonic

ลองregisterUserNotificationSettings. หากเคยเป็น iOS 8 เธรดนี้จะตอบคำถามของคุณได้ แต่ไปดูกัน - 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ฉันได้รับข้อผิดพลาดนี้: มีวิธีอื่นใน Swift ในการขอสิทธิ์จากผู้ใช้เพื่อทำงานใน iOS7 หรือไม่? กรุณาช่วย.
Raghavendra

@Raghav UIUserNotificationSettings พร้อมใช้งานจาก iOS 8 เท่านั้นและสิ่งที่คุณเผชิญคือพฤติกรรมที่ถูกต้อง คุณไม่ควรใช้สิ่งนี้ใน iOS 7
Satheeshwaran

1
-1 สำหรับการตรวจสอบ UIDevice เวอร์ชัน iOS stackoverflow.com/a/25735175/1226304คำตอบมีแนวทางที่ดีกว่าในการดำเนินการนี้
derpoliuk

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 +

// ปุ่ม: ฉันทำมันเตือนทีหลังข้ามไป **

        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.