swift get to the server in the background - swift

after minimizing/closing(if possible) the application, it is necessary to contact the server every n minutes and, if necessary, display push notifications. With push notifications, the code turned out to be the following
func sendNotification(inSeconds seconds: TimeInterval, completion: (Bool) -> ()){
removeNotification(withIdentifiers: ["inurewd"])
let date = Date(timeIntervalSinceNow: seconds)
let content = UNMutableNotificationContent()
content.title = "title"
content.body = "body"
content.sound = UNNotificationSound.default
let calendar = Calendar(identifier: .gregorian)
let components = calendar.dateComponents([.month, .day, .hour, .minute, .second], from : date)
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: false)
let request = UNNotificationRequest(identifier: "inurewd", content: content, trigger: trigger)
let center = UNUserNotificationCenter.current()
center.add(request, withCompletionHandler: nil)
}
func removeNotification(withIdentifiers identifiers: [String]){
let center = UNUserNotificationCenter.current()
center.removePendingNotificationRequests(withIdentifiers: identifiers)
but I can not understand the work of the application in the background. Can u help me, what method will suit me and how to implement it ?

Related

Scheduling local notifications to repeat daily from tomorrow

I'm trying to schedule a local notification to fire every day, at a specific time, but from tomorrow.
e.g. "Trigger a notification every day at 2 pm, from tomorrow"
This is how I set up my schedule function.
func scheduleNotifications(date: Date, identfier: String, after: Bool) {
let content = UNMutableNotificationContent()
content.title = "App"
content.body = "Test."
content.sound = .default
content.userInfo = ["Hour": Int(hourFormatter.string(from: date)) ?? 0]
let afterDay = Calendar.current.date(byAdding: .day, value: after ? 1 : 0, to: Date())
var components = Calendar.current.dateComponents([.hour, .minute], from: afterDay!)
components.hour = Int(hourFormatter.string(from: date)) ?? 0
components.minute = Int(minuteFormatter.string(from: date)) ?? 0
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
let request = UNNotificationRequest(identifier: identfier, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request)
}
This code is for daily notification just call it in tomorrow schedule time
func setupNotificationSettings() {
DispatchQueue.main.async {
let content: UNMutableNotificationContent = UNMutableNotificationContent()
content.title = AppName
content.body = "APP_Body"
content.sound = UNNotificationSound.default
let trigger: UNTimeIntervalNotificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 86400, repeats: true)
let request: UNNotificationRequest = UNNotificationRequest(identifier: "\(AppName)_Local", content: content, trigger: trigger)
let center: UNUserNotificationCenter = UNUserNotificationCenter.current()
center.removeDeliveredNotifications(withIdentifiers: ["\(AppName)"])
center.removeDeliveredNotifications(withIdentifiers: ["\(AppName)"])
center.add(request) { (error) in
}
}
}

Is it possible to have two DateCompontents for one Local Notification?

I am trying to set two different times for Local Notifications - the default one being 10 am every day (if the user does not touch the date picker to pick their own notification time AKA it is nil), and one based on the user's input. The user input one does work and sends notifications every day, but if no time is chosen the default time does not work.
This is my code, can someone tell me what I am doing wrong? I basically want to check that if the user input is NIL it should revert to the default time set.
In settings:
IBOutlet var userDatePicker: UIDatePicker!
IBAction func pickerValueChanged(_ sender: UIDatePicker) {
var selectedTime = Date()
selectedTime = sender.date
// convert to data type DateComponents
let convertedSelectedTime = calendar.dateComponents([.hour, .minute,], from: selectedTime)
let delegate = UIApplication.shared.delegate as? AppDelegate
delegate?.sendNotification(with: convertedSelectedTime)
UserDefaults.standard.set(selectedTime, forKey: "SavedTime")
}
In AppDelegate:
func sendNotification(with userSelectedTime: DateComponents?) {
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Testing"
content.body = "testing"
var defaultTime = DateComponents()
defaultTime.hour = 10
defaultTime.minute = 00`// trying to set default time to 10 am if user never picks a time`
let components = userSelectedTime ?? defaultTime//option between the two
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
center.add(request)
}
Try this. All of its fields are optional. So you can use those you need.
DateComponents(calendar:timeZone:era:year:month:day:hour:minute:second:nanosecond:weekday:weekdayOrdinal:quarter:weekOfMonth:weekOfYear:yearForWeekOfYear:)
let triggerDaily = DateComponents(calendar: Calendar.current,
timeZone: Calendar.current.timeZone,
hour: 10, // Use 22 if PM
minute: 00,
second: 00,
nanosecond: 00)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: false)
More info
DateComponents - Apple
Update
In pickerValueChanged, you are schedulling notification every time DatePicker value is changed. That is bad. There you should only store date.
func pickerValueChanged(_ sender: UIDatePicker) {
UserDefaults.standard.set(sender.date, forKey: "SavedTime")
}
sendNotification should only send notification.
func sendNotification(with dateComponents: DateComponents) {
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Testing"
content.body = "testing"
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
center.add(request)
}
UIApplication has alife method that is called when an App goes to background. You can schedule notifications there.
func applicationDidEnterBackground(_ application: UIApplication) {
let date = UserDefaults.standard.value(forKey: "SavedTime") as? Date
if let date = date {
let convertedSelectedTime = Calendar.current.dateComponents([.hour, .minute,], from: date)
sendNotification(with: convertedSelectedTime)
} else {
let dateComponent = DateComponents(calendar: Calendar.current,
timeZone: Calendar.current.timeZone,
hour: 10, // Use 22 if PM
minute: 00,
second: 00,
nanosecond: 00)
sendNotification(with: dateComponent)
}
}
Use SavedTime if it exists in UserDefaaults. Else use 10:00.
If you use SceneDelegate, use sceneDidEnterBackground instead of applicationDidEnterBackground
func sceneDidEnterBackground(_ scene: UIScene) {
}
They both are life-cycle methods.
More info.
Managing Your App's Life Cycle
UIApplication

How do I make multiple local notifications on Swift?

The bottom line is that I made one local notification for a time interval of 10 seconds.
How do I add multiple notifications to this code with different time delays? That is, different notifications with different delays (several hours, days, and so on).
If this is possible, please use the example of my code.
I was told that I need to put a different identifier: "content" and different times. But I don't understand what parts of the code I need to duplicate.
import UIkit
import UserNotifications
class ViewController UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Hi"
content.body = "Bear"
content.sound = UNNotificationSound.default
content.threadIdentifier = "local-notifications"
let date = Date(timeIntervalSinceNow: 10)
let dateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
let request = UNNotificationRequest(identifier: "content", content: content, trigger: trigger)
center.add(request) {(error) in
if error != nil {
print (error)
}
}
}
```
You can create method scheduleNotification(identifier:content:date:) in UNUserNotificationCenter extension ,
extension UNUserNotificationCenter {
func scheduleNotification(identifier: String, content: UNMutableNotificationContent, date: Date) {
let dateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
self.add(request) {(error) in
if error != nil {
print (error)
}
}
}
}
Now, call this method for multiple notifications with the appropriate parameters that you want to use, i.e.
Example-1:
let content1 = UNMutableNotificationContent()
content1.title = "Hi"
UNUserNotificationCenter.current().scheduleNotification(identifier: "content1", content: content1, date: Date(timeIntervalSinceNow: 10))
Example-2:
let content2 = UNMutableNotificationContent()
content2.title = "Hello"
UNUserNotificationCenter.current().scheduleNotification(identifier: "content2", content: content2, date: Date(timeIntervalSinceNow: 20))

How do you send a notification at a certain time that the user has entered in a text box in xcode 10?

I am trying to get a user to enter the time to take medicine or when they have an appointment in a text field and then send an alarm or notification at that time. I am a newbie so I don't know how to send notifications and such. I would need to do multiple of these depending on how many the user wants.
let content = UNMutableNotificationContent()
content.title = "Title"
content.body = "Body"
content.sound = UNNotificationSound.default()
let gregorian = Calendar(identifier: .gregorian)
let now = Date()
var components = gregorian.dateComponents([.year, .month, .day, .hour, .minute, .second], from: now)
// Change the time to 7:00:00 in your locale
components.hour = 7
components.minute = 0
components.second = 0
let date = gregorian.date(from: components)!
let triggerDaily = Calendar.current.dateComponents([.hour,.minute,.second,], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: true)
let request = UNNotificationRequest(identifier: CommonViewController.Identifier, content: content, trigger: trigger)
print("INSIDE NOTIFICATION")
UNUserNotificationCenter.current().add(request, withCompletionHandler: {(error) in
if let error = error {
print("SOMETHING WENT WRONG")
}
})

iOS 10 UserNotification Framework. Calendar Trigger

I am on iOS 10.3.2 Beta 4 and xcode 8.3.2. I am attempting to fire a notification at the same time daily, however the notifications never seem to fire. If I do not use the calendar trigger and use the timeinterval trigger they work as expected.
Here is my code
let content = UNMutableNotificationContent()
content.title = "Daily Notification"
content.subtitle = ""
content.body = NSLocalizedString("Hello I am a notification", comment: "Comment")
content.badge = 1
content.sound = UNNotificationSound.default()
let calendar = Calendar.current
var dateComponents = calendar.dateComponents([.day, .month, .year, .hour], from: Date())
dateComponents.hour = 14
dateComponents.minute = 55
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
NSLog("Setting daily notification - \(dateComponents)")
let request = UNNotificationRequest(identifier: "dailyWarning", content: content, trigger: trigger)
center.add(request, withCompletionHandler: { error in
if error != nil {
NSLog("Error occurred")
} else {
NSLog("Request added successfully: %#", request)
}
})
Try creating your trigger like this:
var dateComponents = DateComponents()
dateComponents.hour = 14
dateComponents.minute = 55
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true) // Setting repeats to true will trigger the notification daily
For more information about why providing just the hour and minutes is sufficient see the explanation above Listing 1 in the documentation found here.