Minta Izin Pengguna untuk Menerima UILocalNotifications di iOS 8

115

Saya telah menyiapkan pemberitahuan lokal di Delegasi Aplikasi Menggunakan ini:

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

Ketika saya menjalankan aplikasi dan kemudian keluar, saya menerima pesan kesalahan yang mengatakan:

2014-06-07 11: 14: 16.663 CCA-TV [735: 149070] Mencoba menjadwalkan notifikasi lokal {fire date = Sabtu, 7 Juni 2014 pukul 11:14:21 Waktu Musim Panas Pasifik, zona waktu = Amerika / Los_Angeles (PDT) offset -25200 (Daylight), interval pengulangan = 0, pengulangan count = UILocalNotificationInfiniteRepeatCount, tanggal kebakaran berikutnya = Sabtu, 7 Juni 2014 pukul 11:14:21 Waktu Musim Panas Pasifik, info pengguna = (null)} dengan peringatan tetapi belum mendapat izin dari pengguna untuk menampilkan peringatan

Bagaimana saya bisa mendapatkan izin yang diperlukan untuk menampilkan peringatan?

dannysandler
sumber
1
Saya pikir aplikasi telah menolak izin sekali, Anda dapat mencoba mengaktifkan dari Pengaturan. Tapi ngomong-ngomong, UILocalNotification tidak memerlukan izin pengguna ..
iphonic
Coba registerUserNotificationSettings. Seandainya iOS 8, utas ini akan menjawab pertanyaan Anda. Tapi, lihat dulu - stackoverflow.com/questions/24006998/…
raurora

Jawaban:

237

Sejak iOS 8 Anda perlu meminta izin pengguna untuk menampilkan pemberitahuan dari aplikasi Anda, ini berlaku untuk pemberitahuan jarak jauh / push dan lokal. Di Swift Anda dapat melakukannya seperti ini,

Pembaruan untuk 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.0

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.
    }

Sintaks Objective C juga sangat mirip.

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

Untuk memeriksa jenis notifikasi yang saat ini terdaftar Anda dapat menggunakan metode kelas UIApplication,

- (UIUserNotificationSettings *)currentUserNotificationSettings

Jadi, jika pengguna mengatakan tidak pada aplikasi Anda, maka fungsi ini harus mengembalikan pengaturan tanpa tipe apa pun di dalamnya.

Saya telah menulis tutorial tentang ini, Anda bisa melihatnya di sini .

Satheeshwaran
sumber
1
Jika pengguna menolak izin, bagaimana Anda menentukannya nanti secara terprogram?
jjxtra
@satheeshwaran Ketika saya menggunakan kode ini, itu bekerja dengan baik dengan simulator dengan iOS8. Saya ingin target penerapan aplikasi saya mulai dari iOS7. Jadi, ketika saya menjalankan kode ini pada perangkat iOS7, saya mendapatkan error ini: dyld: Symbol not found: _OBJC_CLASS_$_UIUserNotificationSettings. Apakah ada cara lain di Swift untuk meminta izin pengguna agar bisa berfungsi di iOS7? tolong bantu.
Raghavendra
@Raghav UIUserNotificationSettings hanya tersedia dari iOS 8 dan yang Anda hadapi adalah perilaku yang benar. Anda tidak boleh menggunakan ini di iOS 7.
Satheeshwaran
1
-1 untuk memeriksa perangkat UID versi iOS. stackoverflow.com/a/25735175/1226304 jawaban memiliki pendekatan yang lebih baik untuk melakukan ini.
derpoliuk
3
@derpoliuk Diperbarui sebagai jawaban untuk kepentingan semua orang, oke ??
Satheeshwaran
38

Letakkan kode ini di pengontrol tampilan tempat Anda akan memprogram notifikasi terlebih dahulu (jika Anda memprogramnya saat peluncuran, maka itu akan terjadi application:didFinishLaunchingWithOptions:):

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

Di Swift:

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

Solusi yang menguji nomor versi sistem kurang optimal dan rawan kesalahan.

KPM
sumber
Saya akan menggunakan application.respondsToSelector(Selector("registerUserNotificationSettings"))danif ([application respondsToSelector:@selector(registerUserNotificationSettings:)])
derpoliuk
7
Itu hanya karena Anda menggunakannya di dalam application:didFinishLaunchingWithOptions:yang menyediakan applicationobjek yang berguna :)
KPM
18

Coba ini untuk 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];
  }
}

Untuk 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
}
Nagarjun
sumber
5

Saya baru saja menghadapi masalah yang sama. Sepertinya di iOS 8 kita perlu melakukan langkah tambahan, biasanya dilakukan di dalam:

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

Anda dapat menggunakan kode ini jika Anda ingin membuatnya tetap kompatibel:

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

Sistem akan mengingat keputusan tersebut, dan hanya akan menanyakan satu kali.

ppalancica.dll
sumber
Lebih baik memeriksa versi iOS dengan kode ini jika ([[UIDevice currentDevice] .systemVersion floatValue] <10)
Mehul Chuahan
1

** Pemberitahuan Lokal dengan aksi tiga tombol untuk iOS8 +

// Tombol: SAYA MENGAMBIL, INGAT NANTI, LEWATI **

        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()

        }

    }
PSS
sumber