Jak tworzyć lokalne powiadomienia?

114

Jak mogę skonfigurować powiadomienia lokalne, aby o określonej godzinie moja aplikacja generowała powiadomienie / alert z dostosowaną wiadomością?

learner2010
źródło

Odpowiedzi:

98

Oto przykładowy kod dla LocalNotification, który działał dla mojego projektu.

Cel C:

Ten blok kodu w AppDelegatepliku:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        [launchOptions valueForKey:UIApplicationLaunchOptionsLocalNotificationKey];
        // Override point for customization after application launch.
        return YES;
    }

    // This code block is invoked when application is in foreground (active-mode) 
 -(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {

        UIAlertView *notificationAlert = [[UIAlertView alloc] initWithTitle:@"Notification"    message:@"This local notification" 
        delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];

        [notificationAlert show];
       // NSLog(@"didReceiveLocalNotification");
    }

Ten blok kodu w pliku .m dowolnego ViewController:

-(IBAction)startLocalNotification {  // Bind this method to UIButton action
    NSLog(@"startLocalNotification");

    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:7];
    notification.alertBody = @"This is local notification!";
    notification.timeZone = [NSTimeZone defaultTimeZone];
    notification.soundName = UILocalNotificationDefaultSoundName;
    notification.applicationIconBadgeNumber = 10;

    [[UIApplication sharedApplication] scheduleLocalNotification:notification];    
}

Powyższy kod wyświetla AlertView po interwale 7 sekund po naciśnięciu przycisku, który wiąże startLocalNotificationJeśli aplikacja jest w tle, to wyświetlaBadgeNumber jako 10 i z domyślnym dźwiękiem powiadomienia.

Ten kod działa dobrze na iOS 7.xi niższych, ale na iOS 8 wyświetli następujący błąd na konsoli:

Podjęto próbę zaplanowania lokalnego powiadomienia z alertem, ale nie otrzymałem pozwolenia od użytkownika na wyświetlanie alertów

Oznacza to, że musisz zarejestrować się w celu uzyskania lokalnego powiadomienia. Można to osiągnąć za pomocą:

if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]){

    [application registerUserNotificationSettings [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}

Możesz również polecić bloga do lokalnego powiadomienia.

Szybki:

Twój AppDelegate.swiftplik powinien wyglądać następująco:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {    
    // Override point for customization after application launch.
    application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: UIUserNotificationType.Sound | UIUserNotificationType.Badge | UIUserNotificationType.Alert, categories: nil))

    return true
}

Swift plik (powiedzmy ViewController.swift), w którym chcesz utworzyć lokalne powiadomienie, powinien zawierać poniższy kod:

//MARK: - Button functions
func buttonIsPressed(sender: UIButton) {
    println("buttonIsPressed function called \(UIButton.description())")

    var localNotification = UILocalNotification()
    localNotification.fireDate = NSDate(timeIntervalSinceNow: 3)
    localNotification.alertBody = "This is local notification from Swift 2.0"
    localNotification.timeZone = NSTimeZone.localTimeZone()
    localNotification.repeatInterval = NSCalendarUnit.CalendarUnitMinute
    localNotification.userInfo = ["Important":"Data"];
    localNotification.soundName = UILocalNotificationDefaultSoundName
    localNotification.applicationIconBadgeNumber = 5
    localNotification.category = "Message"

    UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}


//MARK: - viewDidLoad

class ViewController: UIViewController {

    var objButton : UIButton!
    . . .

    override func viewDidLoad() {
        super.viewDidLoad()

        . . .

        objButton = UIButton.buttonWithType(.Custom) as? UIButton
        objButton.frame = CGRectMake(30, 100, 150, 40)
        objButton.setTitle("Click Me", forState: .Normal)
        objButton.setTitle("Button pressed", forState: .Highlighted)

        objButton.addTarget(self, action: "buttonIsPressed:", forControlEvents: .TouchDown)

        . . .
    }

    . . .
}

Sposób, w jaki pracujesz z Powiadomieniem lokalnym w iOS 9 i starszych, jest zupełnie inny w iOS 10.

Przedstawia to poniższy zrzut ekranu z informacji o wydaniu Apple.

Zrzut ekranu

Możesz skierować dokument referencyjny Apple do UserNotification.

Poniżej znajduje się kod powiadomienia lokalnego:

Cel C:

  1. W App-delegate.hużyciu pliku@import UserNotifications;

  2. Delegat aplikacji powinien być zgodny z UNUserNotificationCenterDelegateprotokołem

  3. W didFinishLaunchingOptionsużyciu poniższy kod:

    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert)
           completionHandler:^(BOOL granted, NSError * _Nullable error) {
                  if (!error) {
                      NSLog(@"request authorization succeeded!");
                      [self showAlert];
                  }
    }];
    
    -(void)showAlert {
        UIAlertController *objAlertController = [UIAlertController alertControllerWithTitle:@"Alert" message:@"show an alert!" preferredStyle:UIAlertControllerStyleAlert];
    
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"OK"
          style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
            NSLog(@"Ok clicked!");
        }];
    
        [objAlertController addAction:cancelAction];
    
    
        [[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController] presentViewController:objAlertController animated:YES completion:^{            
        }];
    
    }
  4. Teraz utwórz przycisk w dowolnym kontrolerze widoku, a w IBAction użyj poniższego kodu:

    UNMutableNotificationContent *objNotificationContent = [[UNMutableNotificationContent alloc] init];
    
    objNotificationContent.title = [NSString localizedUserNotificationStringForKey:@“Notification!” arguments:nil];
    
    objNotificationContent.body = [NSString localizedUserNotificationStringForKey:@“This is local notification message!“arguments:nil];
    
    objNotificationContent.sound = [UNNotificationSound defaultSound];
    
    // 4. update application icon badge number
    objNotificationContent.badge = @([[UIApplication sharedApplication] applicationIconBadgeNumber] + 1);
    
    // Deliver the notification in five seconds.
    UNTimeIntervalNotificationTrigger *trigger =  [UNTimeIntervalNotificationTrigger                                             triggerWithTimeInterval:10.f repeats:NO];       
    
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@“ten                                                                            content:objNotificationContent trigger:trigger];
    
    // 3. schedule localNotification
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    
    [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        if (!error) {
            NSLog(@“Local Notification succeeded“);
        } else {
            NSLog(@“Local Notification failed“);
        }
    }];

Swift 3:

  1. W AppDelegate.swiftużyciu plikuimport UserNotifications
  2. Appdelegate powinien być zgodny z UNUserNotificationCenterDelegateprotokołem
  3. W didFinishLaunchingWithOptionsużyciu poniższy kod

    // Override point for customization after application launch.
    let center = UNUserNotificationCenter.current()
    center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
        // Enable or disable features based on authorization.
        if error != nil {
            print("Request authorization failed!")
        } else {
            print("Request authorization succeeded!")
            self.showAlert()
        }
    }
    
    
    func showAlert() {
        let objAlert = UIAlertController(title: "Alert", message: "Request authorization succeeded", preferredStyle: UIAlertControllerStyle.alert)
    
        objAlert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
        //self.presentViewController(objAlert, animated: true, completion: nil)
    
        UIApplication.shared().keyWindow?.rootViewController?.present(objAlert, animated: true, completion: nil)
    }
  4. Teraz utwórz przycisk w dowolnym kontrolerze widoku, a w IBAction użyj poniższego kodu:

    let content = UNMutableNotificationContent()
    content.title = NSString.localizedUserNotificationString(forKey: "Hello!", arguments: nil)
    content.body = NSString.localizedUserNotificationString(forKey: "Hello_message_body", arguments: nil)
    content.sound = UNNotificationSound.default()
    content.categoryIdentifier = "notify-test"
    
    let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 5, repeats: false)
    let request = UNNotificationRequest.init(identifier: "notify-test", content: content, trigger: trigger)
    
    let center = UNUserNotificationCenter.current()
    center.add(request)
Jayprakash Dubey
źródło
1
Czy muszę koniecznie uruchamiać funkcję funcButtonIsPressed po naciśnięciu przycisku? Co jeśli chcę, aby aplikacja domyślnie wysyłała to powiadomienie co tydzień, czy powinienem po prostu dodać je do początkowego viewDidLoad VC?
Dave G
1
Ponadto, dlaczego plik AppDelegate.swift dwukrotnie didFinishLaunchingWithOptions?
Dave G
„import UserNotifications” zaimportuj to do swojego ViewController
iOS
52

W pliku appdelegate.m napisz następujący kod w applicationDidEnterBackground, aby uzyskać lokalne powiadomienie

- (void)applicationDidEnterBackground:(UIApplication *)application
{
   UILocalNotification *notification = [[UILocalNotification alloc]init];
   notification.repeatInterval = NSDayCalendarUnit;
   [notification setAlertBody:@"Hello world"];
   [notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:1]];
   [notification setTimeZone:[NSTimeZone  defaultTimeZone]];
   [application setScheduledLocalNotifications:[NSArray arrayWithObject:notification]];
}
Madhu
źródło
11
Kiedy zaplanujesz tylko JEDNE powiadomienie za pomocą setScheduledLocalNotifications: jest niepotrzebne. Istnieje metoda scheduleLocalNotification, która przyjmuje jeden argument - powiadomienie do zaplanowania. developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/… :
Paul Brewczynski
16

Tworzenie lokalnych powiadomień jest dość łatwe. Po prostu wykonaj następujące kroki.

  1. W funkcji viewDidLoad () zapytaj użytkownika o pozwolenie na wyświetlanie powiadomień przez aplikacje. W tym celu możemy użyć następującego kodu.

    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge], completionHandler: {didAllow, error in
    })
  2. Następnie możesz utworzyć przycisk, a następnie w funkcji akcji możesz napisać następujący kod, aby wyświetlić powiadomienie.

    //creating the notification content
    let content = UNMutableNotificationContent()
    
    //adding title, subtitle, body and badge
    content.title = "Hey this is Simplified iOS"
    content.subtitle = "iOS Development is fun"
    content.body = "We are learning about iOS Local Notification"
    content.badge = 1
    
    //getting the notification trigger
    //it will be called after 5 seconds
    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
    
    //getting the notification request
    let request = UNNotificationRequest(identifier: "SimplifiedIOSNotification", content: content, trigger: trigger)
    
    //adding the notification to notification center
    UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
  3. Powiadomienie zostanie wyświetlone, wystarczy kliknąć przycisk strony głównej po naciśnięciu przycisku powiadomienia. Gdy aplikacja jest na pierwszym planie, powiadomienie nie jest wyświetlane. Ale jeśli używasz iPhone'a X. Możesz wyświetlać powiadomienia, nawet gdy aplikacja jest na pierwszym planie. W tym celu wystarczy dodać delegata o nazwie UNUserNotificationCenterDelegate

Aby uzyskać więcej informacji, odwiedź ten wpis na blogu: Samouczek dotyczący lokalnych powiadomień systemu iOS

Kashfa Khan
źródło
Czy można powtarzać powiadomienie każdego dnia z czasem spokojnym i powtarzać aż do otwarcia aplikacji?
Mitul Marsoniya
@KashfaKCzy możesz mi powiedzieć, która metoda jest wykonywana, gdy aplikacja działa w tle, a aplikacja otrzymuje powiadomienie?
ArgaPK
10

Zaktualizowano za pomocą Swift 5 Generalnie używamy trzech typów powiadomień lokalnych

  1. Proste powiadomienie lokalne
  2. Powiadomienie lokalne z akcją
  3. Powiadomienie lokalne z zawartością

Gdzie możesz wysłać proste powiadomienie tekstowe lub z przyciskiem akcji i załącznikiem.

Korzystając z pakietu UserNotifications w aplikacji, poniższy przykład Żądanie uprawnienia do powiadamiania, przygotuj i wyślij powiadomienie zgodnie z działaniem użytkownika AppDelegate i użyj kontrolera widoku, który zawiera listę różnych typów testów powiadomień lokalnych.

AppDelegate

import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    let notificationCenter = UNUserNotificationCenter.current()
    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        //Confirm Delegete and request for permission
        notificationCenter.delegate = self
        let options: UNAuthorizationOptions = [.alert, .sound, .badge]
        notificationCenter.requestAuthorization(options: options) {
            (didAllow, error) in
            if !didAllow {
                print("User has declined notifications")
            }
        }

        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
    }
    func applicationDidEnterBackground(_ application: UIApplication) {
    }
    func applicationWillEnterForeground(_ application: UIApplication) {
    }
    func applicationWillTerminate(_ application: UIApplication) {
    }
    func applicationDidBecomeActive(_ application: UIApplication) {
        UIApplication.shared.applicationIconBadgeNumber = 0
    }


    //MARK: Local Notification Methods Starts here

    //Prepare New Notificaion with deatils and trigger
    func scheduleNotification(notificationType: String) {

        //Compose New Notificaion
        let content = UNMutableNotificationContent()
        let categoryIdentifire = "Delete Notification Type"
        content.sound = UNNotificationSound.default
        content.body = "This is example how to send " + notificationType
        content.badge = 1
        content.categoryIdentifier = categoryIdentifire

        //Add attachment for Notification with more content
        if (notificationType == "Local Notification with Content")
        {
            let imageName = "Apple"
            guard let imageURL = Bundle.main.url(forResource: imageName, withExtension: "png") else { return }
            let attachment = try! UNNotificationAttachment(identifier: imageName, url: imageURL, options: .none)
            content.attachments = [attachment]
        }

        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
        let identifier = "Local Notification"
        let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)

        notificationCenter.add(request) { (error) in
            if let error = error {
                print("Error \(error.localizedDescription)")
            }
        }

        //Add Action button the Notification
        if (notificationType == "Local Notification with Action")
        {
            let snoozeAction = UNNotificationAction(identifier: "Snooze", title: "Snooze", options: [])
            let deleteAction = UNNotificationAction(identifier: "DeleteAction", title: "Delete", options: [.destructive])
            let category = UNNotificationCategory(identifier: categoryIdentifire,
                                                  actions: [snoozeAction, deleteAction],
                                                  intentIdentifiers: [],
                                                  options: [])
            notificationCenter.setNotificationCategories([category])
        }
    }

    //Handle Notification Center Delegate methods
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert, .sound])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {
        if response.notification.request.identifier == "Local Notification" {
            print("Handling notifications with the Local Notification Identifier")
        }
        completionHandler()
    }
}

i ViewController

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var appDelegate = UIApplication.shared.delegate as? AppDelegate
    let notifications = ["Simple Local Notification",
                         "Local Notification with Action",
                         "Local Notification with Content",]

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    // MARK: - Table view data source

     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return notifications.count
    }

     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = notifications[indexPath.row]
        return cell
    }

     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let notificationType = notifications[indexPath.row]
        let alert = UIAlertController(title: "",
                                      message: "After 5 seconds " + notificationType + " will appear",
                                      preferredStyle: .alert)
        let okAction = UIAlertAction(title: "Okay, I will wait", style: .default) { (action) in
            self.appDelegate?.scheduleNotification(notificationType: notificationType)
        }
        alert.addAction(okAction)
        present(alert, animated: true, completion: nil)
    }
}
swiftBoy
źródło
1
- (void)applicationDidEnterBackground:(UIApplication *)application
{
   UILocalNotification *notification = [[UILocalNotification alloc]init];
   notification.repeatInterval = NSDayCalendarUnit;
   [notification setAlertBody:@"Hello world"];
   [notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:1]];
   [notification setTimeZone:[NSTimeZone  defaultTimeZone]];
   [application setScheduledLocalNotifications:[NSArray arrayWithObject:notification]];
}

To działa, ale w systemie iOS 8.0 i nowszych aplikacja musi zarejestrować się w celu korzystania z powiadomień użytkowników, -[UIApplication registerUserNotificationSettings:]zanim będzie można zaplanować i przedstawić UILocalNotifications, nie zapomnij o tym.

cathy.s
źródło
- [UIApplication registerUserNotificationSettings:] nadpisuje ustawienie powiadomień push. Więc uważaj, jeśli używane powiadomienie o działaniu push.
Avijit Nagare,
0

Użytkownicy systemu iOS 8 i nowszych powinni uwzględnić to w pełnomocniku aplikacji, aby działało.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)])
    {
        [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
    }

    return YES;
}

Dodanie tych wierszy kodu pomogłoby,

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    UILocalNotification *notification = [[UILocalNotification alloc]init];
    notification.repeatInterval = NSDayCalendarUnit;
    [notification setAlertBody:@"Hello world"];
    [notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:1]];
    [notification setTimeZone:[NSTimeZone  defaultTimeZone]];
    [application setScheduledLocalNotifications:[NSArray arrayWithObject:notification]];

}
Manoj Kumar
źródło
0
-(void)kundanselect
{
    NSMutableArray *allControllers = [[NSMutableArray alloc] initWithArray:self.navigationController.viewControllers];
    NSArray *allControllersCopy = [allControllers copy];
    if ([[allControllersCopy lastObject] isKindOfClass: [kundanViewController class]]) 
    {
        [[NSNotificationCenter defaultCenter]postNotificationName:@"kundanViewControllerHide"object:nil userInfo:nil];
    }
    else
    {
        [[NSUserDefaults standardUserDefaults] setInteger:4 forKey:@"selected"];
        [self performSegueWithIdentifier:@"kundansegue" sender:self];
    }
}

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(ApparelsViewControllerHide) name:@"ApparelsViewControllerHide" object:nil];

shikha kochar
źródło
0

Zakładam, że poprosiłeś o autoryzację i zarejestrowałeś swoją aplikację do powiadamiania.

Oto kod do tworzenia lokalnych powiadomień

@available(iOS 10.0, *)
    func send_Noti()
    {
        //Create content for your notification 
        let content = UNMutableNotificationContent()
        content.title = "Test"
        content.body = "This is to test triggering of notification"

        //Use it to define trigger condition
        var date = DateComponents()
        date.calendar = Calendar.current
        date.weekday = 5 //5 means Friday
        date.hour = 14 //Hour of the day
        date.minute = 10 //Minute at which it should be sent


        let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
        let uuid = UUID().uuidString
        let req = UNNotificationRequest(identifier: uuid, content: content, trigger: trigger)

        let notificationCenter = UNUserNotificationCenter.current()
        notificationCenter.add(req) { (error) in
            print(error)
        }
    }
Ashutosh Shukla
źródło