Triggered only after notification (swift3)

My code uses datePicker , which, when the datePicker changes, matches the current date of the user device. It triggers a notification. However, AVSpeechUtterance I use fire as soon as the datePickers time does not change when a notification appears. I would like AVSpeechUtterance and the notice to be fired at the same time.

 import UIKit import AVFoundation import UserNotifications class ViewController: UIViewController { @IBOutlet var datePicker: UIDatePicker! @IBAction func datePicker(_ sender: Any) { let c = UNMutableNotificationContent() c.title = "Lets Roll" c.subtitle = "s" c.body = "d" let begin = AVSpeechUtterance(string: " Hello ") let synthesizer = AVSpeechSynthesizer() begin.voice = AVSpeechSynthesisVoice(language: "en-US") begin.rate = 0.08 synthesizer.speak(begin) let triggerDate = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: datePicker.date ) let t = UNCalendarNotificationTrigger(dateMatching: triggerDate, repeats: false) let r = UNNotificationRequest(identifier: "any", content: c, trigger: t) UNUserNotificationCenter.current().add(r, withCompletionHandler: nil) }} 

APP DELEAGATE

  import AVFoundation import UIKit import UserNotifications enum NotificationName: String { case mySpeechNotification } @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { if #available(iOS 10.0, *) { let center = UNUserNotificationCenter.current() center.delegate = self center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in if error != nil { print("Ops, error trying to get authorization") } else { if !granted { print("Dude, let me use notifications!") } } } } return true } func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { print("Oh, will present a notification, let see the identifier: \(notification.request.identifier)") if (notification.request.identifier == NotificationName.mySpeechNotification.rawValue) { print("Speaking...") } else { print("Nothing to say...") } completionHandler(.alert) let begin = AVSpeechUtterance(string: " Hello ") begin.voice = AVSpeechSynthesisVoice(language: "en-US") begin.rate = 0.08 let synthesizer = AVSpeechSynthesizer() synthesizer.speak(begin) } } 

error message

+5
source share
3 answers

You can complete your speech action after receiving a notification. To do this, you can:

If you are under iOS 10, you can use application:didReceiveLocalNotification: on UIAppplicatinoDelegate , and then start your speech.

The idea of ​​the implementation will be to check some value in the notification to make sure that it is the “voice notification” you called.

If you are using iOS 10+, you can use UNUserNotificationCenterDelegateExample here you can see an example implementation.

+1
source

Have you tried installing preUtteranceDelay for AVSpeechUtterance?

0
source
 import UIKit import UserNotifications import UserNotificationsUI //framework to customize the notification class TestViewController: UIViewController { @IBOutlet weak var datePicker: UIDatePicker! let appDelegate = UIApplication.shared.delegate as! AppDelegate override func viewDidLoad() { super.viewDidLoad() datePicker.addTarget(self, action: #selector(dateChanged(_:)), for: .valueChanged) } //MARK:- Date Picker Value Changed func dateChanged(_ sender: UIDatePicker) { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "MMM dd, yyyy" let selectedDate = dateFormatter.string(from: datePicker.date) let currentDate = dateFormatter.string(from: Date()) if selectedDate == currentDate{ self.triggerLocalNotification() } print(selectedDate) } //MARK:- Removed all pending notifications func removeLocalNotification() { print("Removed all pending notifications") let center = UNUserNotificationCenter.current() center.removePendingNotificationRequests(withIdentifiers: [appDelegate.requestIdentifier]) } //MARK:- Trigger Local Notification func triggerLocalNotification() { self.removeLocalNotification() let content = UNMutableNotificationContent() content.title = "Title" content.subtitle = "Subtitle" content.body = "Body" content.sound = UNNotificationSound.default() let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 5.0, repeats: false) let request = UNNotificationRequest(identifier: appDelegate.requestIdentifier, content: content, trigger: trigger) UNUserNotificationCenter.current().add(request){(error) in if (error != nil){ print(error?.localizedDescription) } } } } 

// ============= AppDelegate =========

 import UIKit import AVFoundation import UserNotifications let center = UNUserNotificationCenter.current() let requestIdentifier = "SampleRequest" //identifier is to cancel the notification request func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { //Requesting Authorization for User Interactions center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in // Enable or disable features based on authorization. } center.delegate = self return true } extension AppDelegate:UNUserNotificationCenterDelegate{ func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { print("Tapped in notification") } //This is key callback to present notification while the app is in foreground func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { print("Notification being triggered") let begin = AVSpeechUtterance(string: " Hello ") begin.voice = AVSpeechSynthesisVoice(language: "en-US") begin.rate = 0.08 let synthesizer = AVSpeechSynthesizer() synthesizer.speak(begin) //You can either present alert ,sound or increase badge while the app is in foreground too with ios 10 //to distinguish between notifications if notification.request.identifier == requestIdentifier{ completionHandler( [.alert,.sound,.badge]) } } } 

=============

0
source

Source: https://habr.com/ru/post/1269952/


All Articles