How to detect estimote beacon when app is killed in ios? - ios

i am new in estimote beacon programming .i want to detect the estimote beacon when app is closed. And when beacon is detected then fire the particular notification. how i can done it?
give me suggestions please. i had done the following code. but i can not getting any notification
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
beaconManager.delegate = self
beaconManager.startMonitoring(for: region)
beaconManager.startRangingBeacons(in: region)
}
func beaconManager(_ manager: Any, didEnter region: CLBeaconRegion) {
NSLog("beaconManager : didEnter Called")
let content = UNMutableNotificationContent()
content.title = "Beacon Detected"
content.body = "Enter region"
content.sound = UNNotificationSound.default()
let trigger = UNLocationNotificationTrigger(region:region, repeats:false)
let request = UNNotificationRequest(identifier: "Enter region", content: content, trigger: trigger)
center.add(request) { (error) in
if let error = error {
print(error.localizedDescription)
}
}
}
func beaconManager(_ manager: Any, didExitRegion region: CLBeaconRegion) {
NSLog("beaconManager : didExitRegion Called")
let content = UNMutableNotificationContent()
content.title = "Beacon Detected"
content.body = "Exit region"
content.sound = UNNotificationSound.default()
let trigger = UNLocationNotificationTrigger(region:region, repeats:false)
let request = UNNotificationRequest(identifier: "Enter region", content: content, trigger: trigger)
center.add(request) { (error) in
if let error = error {
print(error.localizedDescription)
}
}
}

In app delegate write the desired code under estimate delegate methods. Sample code as follows,
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
if launchOptions["UIApplicationLaunchOptionsLocationKey"] != nil {
beaconManager = ESTBeaconManager()
beaconManager.delegate = self
// don't forget the NSLocationAlwaysUsageDescription in your Info.plist
beaconManager.requestAlwaysAuthorization()
beaconManager.startMonitoring(for: ESTBeaconRegion(proximityUUID: ESTIMOTE_PROXIMITY_UUID, identifier: "AppRegion"))
}
return true
}
func beaconManager(_ manager: ESTBeaconManager, didEnter region: ESTBeaconRegion) {
let notification = UILocalNotification()
notification.alertBody = "Enter region"
notification.soundName = UILocalNotificationDefaultSoundName as? String
UIApplication.shared.presentLocalNotificationNow(notification)
}
func beaconManager(_ manager: ESTBeaconManager, didExitRegion region: ESTBeaconRegion) {
let notification = UILocalNotification()
notification.alertBody = "Exit region"
notification.soundName = UILocalNotificationDefaultSoundName as? String
UIApplication.shared.presentLocalNotificationNow(notification)
}
This is old code, may have few changes. Follow estimate community's thread for more information. You can find your problem on this thread https://community.estimote.com/hc/en-us/articles/203253193-Pushing-notifications-from-iBeacon-when-the-app-is-in-the-background-or-killed

Related

How to create reminders that don't have to be shown in the Apple's Reminders app

With the following code I can successfully create a reminder event and add an alarm to it that triggers 10 seconds after the event has been created. What I don't like about the way the reminder is created is that it shows in the Apple's Reminders app and when you get the notification message in your device, it shows the Reminders' app icon.
Is it possible to make the reminder private so it doesn't show in Apple's Reminders app? If not, what are my options to achieve such of task?
Note: I don't mind storing the reminders in the standard reminders local database as long as they don't show in the default Reminders app.
import EventKit
class ViewController: UIViewController{
var eventStore = EKEventStore()
override func viewDidLoad(){
super.viewDidLoad()
// get user permission
eventStore.requestAccess(to: EKEntityType.reminder, completion: {(granted, error) in
if !granted{
print("Access denied!")
}
})
}
#IBAction func createReminder(_ sender: Any) {
let reminder = EKReminder(eventStore: self.eventStore)
reminder.title = "Get Milk from the Store"
reminder.calendar = eventStore.defaultCalendarForNewReminders()
let date = Date()
let alarm = AKAlarm (absoluteDate: date.addingTimeInterval(10) as Date)
reminder.addAlarm(alarm)
do {
try eventStore.save(reminder, commit: true)
} catch let error {
print("Error: \(error.localizedDescription)")
}
}
}
FYI - To make the above code work you would need to add the NSRemindersUsageDescription key in the info.plist file.
Just for the record, what I was looking for was User Notifications.
Here is a complete example.
User Notifications
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
if granted{
print("User gave permissions for local notifications")
}else{
print("User did NOT give permissions for local notifications")
}
}
return true
}
override func viewDidLoad() {
super.viewDidLoad()
setReminderAtTime()
}
func setReminderAtTime(){
let reminderTime:TimeInterval = 60
let center = UNUserNotificationCenter.current()
center.removeAllPendingNotificationRequests()
let content = UNMutableNotificationContent()
content.title = "Title"
content.body = "Notification Message!."
content.sound = .default
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: reminderTime, repeats: false)
let request = UNNotificationRequest(identifier: "reminderName", content: content, trigger: trigger)
center.add(request) { (error) in
if error != nil{
print("Error = \(error?.localizedDescription ?? "error local notification")")
}
}
}

How do I send local notifications at a specific time in Swift?

I have been looking all over for an answer on how to send notifications at a specific time of day. I need it to display a local notification to the user's device every weekday at 8:00 A.M. I am aware that this question has been answered before. I found a Stack Overflow question: Local Notifications at a specific time
Unfortunately, it was pretty outdated as most of the code was removed from Swift since iOS 11 was released. I needed a more recent answer. I am kind of new to Swift programming. If someone could help me out and give me a more recent answer, that would be amazing!
This is an example of what I have used for scheduling local notifications using Notification Centre.
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "My title"
content.body = "Lots of text"
content.sound = UNNotificationSound.default()
content.categoryIdentifier = "yourIdentifier"
content.userInfo = ["example": "information"] // You can retrieve this when displaying notification
// Setup trigger time
var calendar = Calendar.current
calendar.timeZone = TimeZone.current
let testDate = Date() + 5 // Set this to whatever date you need
let trigger = UNCalendarNotificationTrigger(dateMatching: testDate, repeats: false)
// Create request
let uniqueID = UUID().uuidString // Keep a record of this if necessary
let request = UNNotificationRequest(identifier: uniqueID, content: content, trigger: trigger)
center.add(request) // Add the notification request
The Date object (represented by testDate above) can be whatever date you want. It is often convenient to create it from DateComponents.
You will need to ask permission for local notifications in the App Delegate at startup to allow this to work. Here is an example.
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Ask permission for notifications
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
if granted {
print("Permission granted")
} else {
print("Permission denied\n")
}
}
}
}
Swift 5
This is an example of what I have used for scheduling local notifications using Notification Center.
import UserNotifications
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//MARK: Authorization
let center = UNUserNotificationCenter.current()
//Delegate for UNUserNotificationCenterDelegate
center.delegate = self
//Permission for request alert, soud and badge
center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
// Enable or disable features based on authorization.
if(!granted){
print("not accept authorization")
}else{
print("accept authorization")
center.delegate = self
}
}
return true
}
}
send notification
let content = UNMutableNotificationContent()
content.title = NSString.localizedUserNotificationString(forKey: "We have a new message for you", arguments: nil)
content.body = NSString.localizedUserNotificationString(forKey: "Open the app for see", arguments: nil)
content.sound = UNNotificationSound.default
content.badge = 1
let identifier = id.uuidString
//Receive notification after 5 sec
//let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
//Receive with date
var dateInfo = DateComponents()
dateInfo.day = day //Put your day
dateInfo.month = month //Put your month
dateInfo.year = year // Put your year
dateInfo.hour = 8 //Put your hour
dateInfo.minute = 0 //Put your minutes
//specify if repeats or no
let trigger = UNCalendarNotificationTrigger(dateMatching: dateInfo, repeats: true)
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
let center = UNUserNotificationCenter.current()
print(identifier)
center.add(request) { (error) in
if let error = error {
print("Error \(error.localizedDescription)")
}else{
print("send!!")
}
}
remembering to read this in the documentation:
https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/index.html#//apple_ref/doc/uid/TP40008194-CH3-SW1

How to schedule Notifications in Swift

I am trying to schedule notifications in my project. I don't get any errors or runtime crashes, however for some reason I don't get any notifications on the simulator when scheduling. I am not sure where exactly I am going wrong, as I have been successful in doing so in a previous project.
Does anyone have any suggestions ?
import UserNotifications
func addNotification(title: String, category: String, UI: String, date: Date) {
// Remove Notification
removeNotifcation(UI: UI)
// Create Notification
// iOS 10 Notification
if #available(iOS 10.0, *) {
let notif = UNMutableNotificationContent()
notif.title = title
notif.subtitle = "Reminder for \(title)"
notif.body = "Your Reminder for \(title) set for \(date)"
notif.sound = UNNotificationSound.default()
notif.categoryIdentifier = UI
let today = Date()
let interval = date.timeIntervalSince(today as Date)
let notifTrigger = UNTimeIntervalNotificationTrigger(timeInterval: interval, repeats: false)
let request = UNNotificationRequest(identifier: title, content: notif, trigger: notifTrigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: { error in
if error != nil {
print(error as Any)
// completion(Success: false)
} else {
//completion(Sucess: true)
}
})
} else {
let newNotification:UILocalNotification = UILocalNotification()
newNotification.category = category
newNotification.userInfo = [ "UUID" : UI]
newNotification.alertBody = "Your reminder for \(title)"
newNotification.fireDate = date
//notification.repeatInterval = nil
newNotification.soundName = UILocalNotificationDefaultSoundName
UIApplication.shared.scheduleLocalNotification(newNotification)
}
}
func removeNotifcation(UI: String) {
//Remove Notif
//iOS 10 Notification
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [UI])
} else {
//Remove Notif
let app:UIApplication = UIApplication.shared
for oneEvent in app.scheduledLocalNotifications! {
let notification = oneEvent as UILocalNotification
let userInfoCurrent = notification.userInfo!
let uuid = userInfoCurrent["UUID"] as! String
if uuid == UI {
//Cancelling local notification
app.cancelLocalNotification(notification)
break;
}
}
}
}
This is how I am calling the methods
dataManager.addNotification(title: "String", category: "001", UI: uuid, date: datePicker.date)
Notifications don't appear when app is in foreground only if you implement willPresent delegate method and because of
let today = Date()
this date makes it triggers when you run it , so add a time interval and send app to background and you'll see it , plus make sure you request a permission for it in AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
print("granted: (\(granted)")
}
return true
}
Also you can have a look to this tutorial
//
Edit : to verify it triggers anyway implement this
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
print("handling notifications with the TestIdentifier Identifier")
completionHandler()
}
and set the delegate to the VC
UNUserNotificationCenter.current().delegate = self

UNUserNotification not visually showing notification on real device

My notification works fine on simulator but on my device (running iOS 10.3.3) the notification does not show at all (phone locked at time of trigger) but the phone does vibrate when triggered and the app does get updated to correct settings so I know that the notification is getting triggered - its just not visually showing on the device. Have I missed anything?
This is where I setup authorisation for notifications in AppDelegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
locationManager.delegate = self
// Setup notifications authorization request
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
// Check if granted, if not then notify user
if granted {
print("Notification access granted")
} else {
print(error?.localizedDescription ?? "General Error: notification access not granted")
self.window?.rootViewController?.showAlertApplicationSettings(forErorType: .turnOnNotifications)
}
}
Location trigger in AppDelegate:
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
if region is CLCircularRegion {
print("DidEnter: \(region.identifier)")
handleEvent(forRegion: region)
}
}
Handle event code that gets data from core data and then send to notifyUser method in AppDelegate:
func handleEvent(forRegion region: CLRegion) {
guard let reminder = getReminder(fromRegionIdentifier: region.identifier) else {
// There was a problem access the notification data, inform user
notifyUser(title: "Reminder notifiction error", subtitle: "One of your notifications has just been triggered but error restriving notification data", notes: nil)
return
}
notifyUser(title: reminder.titleString, subtitle: "Reminder has been triggered", notes: reminder.notesString)
updateRemindersState(reminder: reminder)
}
This is the actual notification trigger code in AppDelegate:
func notifyUser(title: String, subtitle: String, notes: String?) {
// show an alert if applocation is active
if UIApplication.shared.applicationState == .active {
window?.rootViewController?.showAlert(title: title, message: subtitle)
} else {
let notification = UNMutableNotificationContent()
notification.title = title
notification.subtitle = subtitle
if let notes = notes {
notification.body = notes
}
notification.sound = UNNotificationSound.default()
let request = UNNotificationRequest(identifier: "Notification", content: notification, trigger: nil)
UNUserNotificationCenter.current().add(request, withCompletionHandler: { (error) in
if let error = error {
print(error)
}
})
}
}
p.s. checked that on my device in settings its has Show in Notifications Centre, sounds, show on lock screen, banners all turned on.

iOS: Notifications and iBeacon

I have an app that needs to send notifications when user is out of range of iBeacon. The problem is that user becomes notifications randomly: sometimes it works, sometimes it doesn't work.
My code:
// this function I call in viewDidLoad for my UIViewController
func startMonitorig() {
let beaconRegion:CLBeaconRegion = {
let r = CLBeaconRegion(proximityUUID: UUID(uuidString: "XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")!, major: 1, minor: 6, identifier: "com.myapp.identifier")
return r
}()
locationManager.startMonitoring(for: beaconRegion)
locationManager.startRangingBeacons(in: beaconRegion)
}
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
startMonitorig()
}
AppDelegate:
let locationManager = CLLocationManager()
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Request permission to send notifications
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options:[.alert, .sound]) { (granted, error) in }
locationManager.delegate = self
return true
}
extension AppDelegate: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
guard region is CLBeaconRegion else { return }
let content = UNMutableNotificationContent()
content.title = "Forget Me Not"
content.body = "Are you forgetting something?"
content.sound = .default()
let request = UNNotificationRequest(identifier: "ForgetMeNot", content: content, trigger: nil)
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
}
I'm curious why it's like that and what I'm doing wrong? What can be the reason?

Resources