I'm developing a chat app. I'm using apple push notification service to notify user when he receives new messages. There are two scenarios.
The first when user is chatting and receiving a message, the user shouldn't be notified (meaning that notification shouldn't be shown) and when the app is in background i want to alert user for the messages. Everything is ok except that when app is on background the notification shows the whole JSON object the client is receiving.
The idea is ignore visually notification and if its on background show a local Notification.
This is how i have implemented the notification settings
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
let types: UIUserNotificationType = [UIUserNotificationType.None]
let settings: UIUserNotificationSettings = UIUserNotificationSettings(forTypes: types, categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
return true
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject])
{
//App handle notifications in background state
if application.applicationState == UIApplicationState.Background {
var login_user = LoginUser();
login_user.loadData();
var username:String!;
var message:String!;
if let msg = userInfo["aps"]as? Dictionary<String,AnyObject>
{
if let alert = msg["alert"] as? String{
if let data = alert.dataUsingEncoding(NSUTF8StringEncoding)
{
do
{
let jsonObject = try NSJSONSerialization.JSONObjectWithData(data,options: [])
username = jsonObject["senderUserName"] as! String;
message = jsonObject["content"] as! String!;
DatabaseOperations().insert(DatabaseOperations().STRING_VALUE_CHATING_USERNAME, value: username);
NSNotificationCenter.defaultCenter().postNotificationName("push_notification", object: self)
}
catch
{
}
}
}
}
let localNotification: UILocalNotification = UILocalNotification()
switch(login_user.privacyLevelId)
{
case 1:
localNotification.alertBody = username + ":" + message;
break;
case 2:
localNotification.alertBody = username;
break;
case 3:
localNotification.alertBody = "New Message";
break;
default:
localNotification.alertBody = "New Message";
break;
}
localNotification.alertAction = "Message"
localNotification.fireDate = NSDate(timeIntervalSinceNow: 5)
localNotification.soundName = UILocalNotificationDefaultSoundName
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
//App is shown and active
else
{
if let msg = userInfo["aps"]as? Dictionary<String,AnyObject>
{
if let alert = msg["alert"] as? String
{
if let data = alert.dataUsingEncoding(NSUTF8StringEncoding)
{
do
{
let jsonObject = try NSJSONSerialization.JSONObjectWithData(data,options: [])
let sender:String = jsonObject["senderUserName"] as! String;
DatabaseOperations().insert(DatabaseOperations().STRING_VALUE_CHATING_USERNAME, value: sender);
NSNotificationCenter.defaultCenter().postNotificationName("push_notification", object: self)
}
catch
{
}
}
}
}
}
}
I set UIUserNotificationType to NONE. Shouldn't by default the notification shows nothing?
I also have read some other posts, but i couldn't find anything to solve the problem.
Why does UIUserNotificationType.None return true in the current settings when user permission is given?
Hide, do not display remote notification from code (swift)
Any help would be appreciated.
application didReceiveRemoteNotification won't be called if the app is closed or in the background state, so you won't be able to create a local notification. So you need to pass the text you want to display in the aps dictionnary, associated with the alert key.
If you want to pass more information for the active state case, you should add them with a custom key to the push dictionnary.
For example :
{"aps": {
"badge": 1,
"alert": "Hello World!",
"sound": "sound.caf"},
"task_id": 1}
Related
I have implemented PushKit. I've followed these steps:
1.) https://stackoverflow.com/a/38184769/4970453
2.) https://stackoverflow.com/a/28562124
I am able to get didUpdatePushCredentials device token.
working in --> iPhone 5s , iPhone6 Plus
didUpdatePushCredentials Not working in --> iPhone6 and iPhone7
I am using same cerificates and Build for all devices. Don't know the exact issue.
If anyone have faced this kind of problem, please share work-arounds.
My code and Certificate Link
code -> https://www.dropbox.com/sh/x2615t7xn8mavs3/AADbX5nBuF5_08YNPX8wI59ga?dl=0
cer -> https://www.dropbox.com/sh/70l4htj1c46emog/AABxBalaoN1JP22dQp8-mNXGa?dl=0
Solution -----> I have changed Bundle identifier And create New certificate with New BundleId.
Make sure that in the certificates page you have the push notifications enabled in the App ID.
Also try using a 3G/4G connection. Network configuration may be not letting the device to obtain the token.
It should work in all devices when integrated properly. there is nothing changed for any device specific.
You can cross verify your steps.
Swift
import UIKit
import PushKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate,PKPushRegistryDelegate {
var window: UIWindow?
var isUserHasLoggedInWithApp: Bool = true
var checkForIncomingCall: Bool = true
var userIsHolding: Bool = true
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if #available(iOS 8.0, *){
let viewAccept = UIMutableUserNotificationAction()
viewAccept.identifier = "VIEW_ACCEPT"
viewAccept.title = "Accept"
viewAccept.activationMode = .Foreground
viewAccept.destructive = false
viewAccept.authenticationRequired = false
let viewDecline = UIMutableUserNotificationAction()
viewDecline.identifier = "VIEW_DECLINE"
viewDecline.title = "Decline"
viewDecline.activationMode = .Background
viewDecline.destructive = true
viewDecline.authenticationRequired = false
let INCOMINGCALL_CATEGORY = UIMutableUserNotificationCategory()
INCOMINGCALL_CATEGORY.identifier = "INCOMINGCALL_CATEGORY"
INCOMINGCALL_CATEGORY.setActions([viewAccept,viewDecline], forContext: .Default)
if application.respondsToSelector("isRegisteredForRemoteNotifications")
{
let categories = NSSet(array: [INCOMINGCALL_CATEGORY])
let types:UIUserNotificationType = ([.Alert, .Sound, .Badge])
let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: types, categories: categories as? Set<UIUserNotificationCategory>)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
}
}
else{
let types: UIRemoteNotificationType = [.Alert, .Badge, .Sound]
application.registerForRemoteNotificationTypes(types)
}
self.PushKitRegistration()
return true
}
//MARK: - PushKitRegistration
func PushKitRegistration()
{
let mainQueue = dispatch_get_main_queue()
// Create a push registry object
if #available(iOS 8.0, *) {
let voipRegistry: PKPushRegistry = PKPushRegistry(queue: mainQueue)
// Set the registry's delegate to self
voipRegistry.delegate = self
// Set the push type to VoIP
voipRegistry.desiredPushTypes = [PKPushTypeVoIP]
} else {
// Fallback on earlier versions
}
}
#available(iOS 8.0, *)
func pushRegistry(registry: PKPushRegistry!, didUpdatePushCredentials credentials: PKPushCredentials!, forType type: String!) {
// Register VoIP push token (a property of PKPushCredentials) with server
let hexString : String = UnsafeBufferPointer<UInt8>(start: UnsafePointer(credentials.token.bytes),
count: credentials.token.length).map { String(format: "%02x", $0) }.joinWithSeparator("")
print(hexString)
}
#available(iOS 8.0, *)
func pushRegistry(registry: PKPushRegistry!, didReceiveIncomingPushWithPayload payload: PKPushPayload!, forType type: String!) {
// Process the received push
// Below process is specific to schedule local notification once pushkit payload received
var arrTemp = [NSObject : AnyObject]()
arrTemp = payload.dictionaryPayload
let dict : Dictionary <String, AnyObject> = arrTemp["aps"] as! Dictionary<String, AnyObject>
if isUserHasLoggedInWithApp // Check this flag then only proceed
{
if UIApplication.sharedApplication().applicationState == UIApplicationState.Background || UIApplication.sharedApplication().applicationState == UIApplicationState.Inactive
{
if checkForIncomingCall // Check this flag to know incoming call or something else
{
var strTitle : String = dict["alertTitle"] as? String ?? ""
let strBody : String = dict["alertBody"] as? String ?? ""
strTitle = strTitle + "\n" + strBody
let notificationIncomingCall = UILocalNotification()
notificationIncomingCall.fireDate = NSDate(timeIntervalSinceNow: 1)
notificationIncomingCall.alertBody = strTitle
notificationIncomingCall.alertAction = "Open"
notificationIncomingCall.soundName = "SoundFile.mp3"
notificationIncomingCall.category = dict["category"] as? String ?? ""
//"As per payload you receive"
notificationIncomingCall.userInfo = ["key1": "Value1" ,"key2": "Value2" ]
UIApplication.sharedApplication().scheduleLocalNotification(notificationIncomingCall)
}
else
{
// something else
}
}
}
}
//MARK: - Local Notification Methods
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification){
// Your interactive local notification events will be called at this place
}
}
Objective C
#import <UIKit/UIKit.h>
#import <PushKit/PushKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate,PKPushRegistryDelegate>
{
PKPushRegistry *pushRegistry;
}
#property (strong, nonatomic) UIWindow *window;
#end
#import "AppDelegate.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
return YES;
}
#define PushKit Delegate Methods
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type{
if([credentials.token length] == 0) {
NSLog(#"voip token NULL");
return;
}
NSLog(#"PushCredentials: %#", credentials.token);
}
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
{
NSLog(#"didReceiveIncomingPushWithPayload");
}
https://github.com/hasyapanchasara/PushKit_SilentPushNotification
Updated answer
https://drive.google.com/file/d/0B7ooURy3zGWKYW5PZE1aN2pObW8/view?usp=sharing
Updated answer
Below are some trouble shooting option.
(1) Change com identifier and try again
(2) Keep puhkit code in app delegeate
I guess, you can change your bundle identifier and try again, it has to be work with all devices.
For PushKit to work properly, here are steps we need to follow:
Enable Push Notifications in project Capabilities
Enable Remote Notifications in Background Modes
Connect device to internet
Allow app to receive push notifications
Please refer to this step-by-step tutorial.
As it is happening for some devices only, may 3rd and 4th steps are responsible.
In my case I wasn't receiving the VoIP token in some of my devices. A HARD RESET of those devices fixed my issue.
I am making a "texting app" you can call it and it uses cloudkit and I have been looking everywhere to add notifications that work with cloudkit... Would someone be able to tell me the code to add push notifications for cloudkit in detail because I am very lost... Also I wan't the notifications to go to different "texting rooms" (in cloudkit it would be record types...) For instance I have one record type called "text" and another one called "text 2" I don't want notifications from "text" to get to people who use "text2" and vise versa.
Using Swift 2.0 with El Captain & Xcode 7.2.1
Elia, You need to add this to your app delegate. Which will arrive in a userInfo packet of data, which you can then parse to see which database/app sent it.
UIApplicationDelegate to the class
application.registerForRemoteNotifications() to the
func application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Than this method
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
let notification = CKQueryNotification(fromRemoteNotificationDictionary: userInfo as! [String : NSObject])
let container = CKContainer(identifier: "iCloud.com")
let publicDB = container.publicCloudDatabase
if notification.notificationType == .Query {
let queryNotification = notification as! CKQueryNotification
if queryNotification.queryNotificationReason == .RecordUpdated {
print("queryNotification.recordID \(queryNotification.recordID)")
// Your notification
}
}
print("userInfo \(userInfo["ck"])")
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: self, userInfo:dataDict)
}
}
}
}
}
That'll get you started.
You can use this method to check your subscriptions programmatically, of course while your developing you can use the dashboard.
func fetchSubsInPlace() {
let container = CKContainer(identifier: "iCloud.com")
let publicDB = container.publicCloudDatabase
publicDB.fetchAllSubscriptionsWithCompletionHandler({subscriptions, error in
for subscriptionObject in subscriptions! {
let subscription: CKSubscription = subscriptionObject as CKSubscription
print("subscription \(subscription)")
}
})
}
And finally when you got it; you can this routine to ensure you capture any subscriptions you missed while your app was sleeping and make sure that subscriptions don't go to all your devices, once you treated them too.
func fetchNotificationChanges() {
let operation = CKFetchNotificationChangesOperation(previousServerChangeToken: nil)
var notificationIDsToMarkRead = [CKNotificationID]()
operation.notificationChangedBlock = { (notification: CKNotification) -> Void in
// Process each notification received
if notification.notificationType == .Query {
let queryNotification = notification as! CKQueryNotification
let reason = queryNotification.queryNotificationReason
let recordID = queryNotification.recordID
print("reason \(reason)")
print("recordID \(recordID)")
// Do your process here depending on the reason of the change
// Add the notification id to the array of processed notifications to mark them as read
notificationIDsToMarkRead.append(queryNotification.notificationID!)
}
}
operation.fetchNotificationChangesCompletionBlock = { (serverChangeToken: CKServerChangeToken?, operationError: NSError?) -> Void in
guard operationError == nil else {
// Handle the error here
return
}
// Mark the notifications as read to avoid processing them again
let markOperation = CKMarkNotificationsReadOperation(notificationIDsToMarkRead: notificationIDsToMarkRead)
markOperation.markNotificationsReadCompletionBlock = { (notificationIDsMarkedRead: [CKNotificationID]?, operationError: NSError?) -> Void in
guard operationError == nil else {
// Handle the error here
return
}
}
let operationQueue = NSOperationQueue()
operationQueue.addOperation(markOperation)
}
let operationQueue = NSOperationQueue()
operationQueue.addOperation(operation)
}
}
I have an iOS app with a (daily) repeating local notification that when some conditions are meet fires a new local notification. A local notification that must be shown within the app (with a banner) and within the notifications view. I have implemented it roughly within the AppDelegate as a proof of concept and that works(tm).
From a block in the banner I remove the onetime local notification from the notifications view with cancelLocalNotification. But surprisingly the repeating localnotification is re-triggered when firing UIApplication.sharedApplication().cancelLocalNotification(<the one time notification>) - why ? And how do I prevent this ?
...
import JCNotificationBannerPresenter
...
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Setup local notifications support
let notificationType: UIUserNotificationType
= [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound]
let settings = UIUserNotificationSettings(forTypes: notificationType,
categories: nil)
application.registerUserNotificationSettings(settings)
// Clean up and reset
application.applicationIconBadgeNumber = 0
application.cancelAllLocalNotifications()
NSLog("Setup one repeating notification")
let n = UILocalNotification()
n.fireDate = NSDate(timeIntervalSinceNow: 15)
n.soundName = UILocalNotificationDefaultSoundName
n.timeZone = NSTimeZone.defaultTimeZone()
n.applicationIconBadgeNumber = 0
n.userInfo = ["id": "dailyreminder"]
n.repeatInterval = NSCalendarUnit.Day
UIApplication.sharedApplication().scheduleLocalNotification(n)
return true
}
...
func application(application: UIApplication,
didReceiveLocalNotification notification: UILocalNotification) {
NSLog("application(... didReceiveLocalNotification/////////////////////////")
NSLog(notification.description)
let state = application.applicationState
if let userInfo = notification.userInfo,
let id = userInfo["id"] as? String
where id != "dailyreminder" {
switch state {
case UIApplicationState.Active:
NSLog(String(format: "%# > UIApplicationState.Active", id))
JCNotificationCenter.enqueueNotificationWithTitle(
notification.alertTitle,
message: notification.alertBody,
tapHandler: { () -> Void in
NSLog("Banner click ///////////////////////////////////////////////")
// 1. Go to somewhere in the app
// 2. Cancel the notification from the `notifications view`
UIApplication.sharedApplication().cancelLocalNotification(notification)
// `cancel` results in an additional call up of the "dailyreminder" ~ why?
})
case UIApplicationState.Inactive:
NSLog(String(format: "%# > UIApplicationState.Inactive", id))
// This is called up when user selects the notification within the `notifications view`
// and canceled by user touch.
default:
let desc = state.rawValue.description
NSLog(String(format: "%# > Unexpected app state: %#", id, desc))
}
}
if let userInfo = notification.userInfo,
let id = userInfo["id"] as? String
where id == "dailyreminder" {
NSLog("Repeating daily reminder was called ~ lets fire a noti to show the user")
// Some condition checks that need to be true before firing the local notification
if true {
let n = UILocalNotification()
n.fireDate = nil
n.timeZone = NSTimeZone.defaultTimeZone()
n.applicationIconBadgeNumber = ++UIApplication.sharedApplication().applicationIconBadgeNumber
n.userInfo = [
"id": "onetimenotification"
]
n.alertTitle = "One time notification title"
n.alertBody = "One time notification body"
UIApplication.sharedApplication().scheduleLocalNotification(n)
}
}
}
...
Update 1
I have put up the full example on github.
Update 2
Ok I gave it another shoot. Having the cancel notification outside a block works (but don't fit the scenario):
case UIApplicationState.Active:
NSLog(String(format: "%# > UIApplicationState.Active", id))
UIApplication.sharedApplication().cancelLocalNotification(notification)
I also like to eliminate that the JCNotificationBannerPresenter was causing the odd behavior so I tried with the new ios altertController:
case UIApplicationState.Active:
NSLog(String(format: "%# > UIApplicationState.Active", id))
let alertController = UIAlertController(
title: "Daily reminder title",
message: "Daily reminder description.",
preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { _ in
NSLog("Do nothing ////////////////////// ")
}
alertController.addAction(cancelAction)
let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
NSLog("OK was pressed ////////////// ")
UIApplication.sharedApplication().cancelLocalNotification(notification)
}
alertController.addAction(OKAction)
self.window!.makeKeyAndVisible()
let v = self.window!.rootViewController!
v.presentViewController(alertController,
animated: true,
completion: {})
This did unfortunately reproduce the odd behavior so it tastes like its something with the combination of block and UIApplication.sharedApplication().cancelLocalNotification(notification)...
You have not cancel the repeating notification i.e. your daily reminder notification in your didReceiveLocalNotification method. You have cancel the notification where id != "dailyreminder" whereas you repeating notification have id == "dailyreminder". Check your conditions in didReceiveLocalNotification
I have a local notification scheduled in my app, and right now I get a generic cancel (cross) button as I swipe the alert to the left.
I'm curious if I can add custom buttons/actions to it like on the image below?
I prepared for you some snipped code which shows notification with one button 10 second after ViewDidLoad method did shown.
import UIKit
class TestViewController: UIViewController {
let category = UIMutableUserNotificationCategory()
override func viewDidLoad() {
super.viewDidLoad()
let restartAction = UIMutableUserNotificationAction()
restartAction.identifier = "xx"
restartAction.destructive = false
restartAction.title = "Restart"
restartAction.activationMode = .Background
restartAction.authenticationRequired = false
let categoryIdentifier = "category.identifier"
category.identifier = categoryIdentifier
category.setActions([restartAction], forContext: .Minimal)
category.setActions([restartAction], forContext: .Default)
let categories = Set(arrayLiteral: category)
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Sound], categories: categories)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
let localNotif = UILocalNotification()
localNotif.alertBody = "testBody"
localNotif.category = categoryIdentifier
// Notification will be shown after 10 second (IMPORTANT: if you want to see notification you have to close or put app into background)
localNotif.fireDate = NSDate().dateByAddingTimeInterval(10)
UIApplication.sharedApplication().scheduleLocalNotification(localNotif)
}
}
Note: you have to handle action in AppDelegate method:
func application(application: UIApplication, handleActionWithIdentifier identifier: String?,
forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) {
completionHandler()
}
Of course my code is not as clean as it should be, but you have to know that I wrote it only for presentation purposes.
This code is written in Swift but convertion to Objective C should be very simple.
Im making a remind app and the so far the user is apple to successfully submit and store data from a form which is then stored in an array, this array writes to a file when the app is closed and then the data is loaded from the file when the app is reopened.
I am having an issue because I'm wanting to set the notifications to remind the user to complete the task at a certain time and I am not able to recall the NSDate that is stored in my array. Also I want to make the app work so that the notification is repeated everyday.
Here is my TableViewController:
class MedicineTableViewController: UITableViewController {
//MARK Properties
var medicines = [Medicine]()
override func viewDidLoad() {
super.viewDidLoad()
//Notifications Setup
let reminderActionOkay = UIMutableUserNotificationAction()
reminderActionOkay.identifier = "Okay"
reminderActionOkay.title = "Okay"
reminderActionOkay.activationMode = UIUserNotificationActivationMode.Background
reminderActionOkay.destructive = true
reminderActionOkay.authenticationRequired = false
let reminderActionOpen = UIMutableUserNotificationAction()
reminderActionOpen.identifier = "Open App"
reminderActionOpen.title = "Open App"
reminderActionOpen.activationMode = UIUserNotificationActivationMode.Background
reminderActionOpen.destructive = false
reminderActionOpen.authenticationRequired = true
//Put the different types of notifications into a category
let ReminderCategory = UIMutableUserNotificationCategory()
ReminderCategory.identifier = "reminderCategory"
ReminderCategory.setActions([reminderActionOpen, reminderActionOkay], forContext: UIUserNotificationActionContext.Default)
ReminderCategory.setActions([reminderActionOpen, reminderActionOkay], forContext: UIUserNotificationActionContext.Minimal)
//MARK: Notification Schedule
func scheduleLocalNotification() {
let localNotificationtime1 = UILocalNotification()
localNotificationtime1.alertTitle = "Take", medicines.name
localNotificationtime1.alertBody = "It is time to take", medicines.name
localNotificationtime1.alertAction = "Show Details"
localNotificationtime1.fireDate = medicine.time1 // 1 Day repeating
localNotificationtime1.timeZone = NSTimeZone.defaultTimeZone()
localNotificationtime1.soundName = UILocalNotificationDefaultSoundName
localNotificationtime1.applicationIconBadgeNumber = 1
localNotificationtime1.category = "reminderCategory"
UIApplication.sharedApplication().scheduleLocalNotification(localNotificationtime1)
let localNotificationtime2 = UILocalNotification()
localNotificationtime2.alertTitle = "Take", medicines.name
localNotificationtime2.alertBody = "It is time to take", medicines.name
localNotificationtime2.alertAction = "Show Details"
localNotificationtime2.fireDate = medicines.time2
localNotificationtime2.timeZone = NSTimeZone.defaultTimeZone()
localNotificationtime2.soundName = UILocalNotificationDefaultSoundName
localNotificationtime2.applicationIconBadgeNumber = 1
localNotificationtime2.category = "reminderCategory"
UIApplication.sharedApplication().scheduleLocalNotification(localNotificationtime2)
let localNotificationtime3 = UILocalNotification()
localNotificationtime3.alertTitle = "Take", medicines.name
localNotificationtime3.alertBody = "It is time to take", medicines.name
localNotificationtime3.alertAction = "Show Details"
localNotificationtime3.fireDate = medicines.time3
localNotificationtime3.timeZone = NSTimeZone.defaultTimeZone()
localNotificationtime3.soundName = UILocalNotificationDefaultSoundName
localNotificationtime3.applicationIconBadgeNumber = 1
localNotificationtime3.category = "reminderCategory"
UIApplication.sharedApplication().scheduleLocalNotification(localNotificationtime3)
let localNotificationtime4 = UILocalNotification()
localNotificationtime4.alertTitle = "Take", medicines.name
localNotificationtime4.alertBody = "It is time to take", medicines.name
localNotificationtime4.alertAction = "Show Details"
localNotificationtime4.fireDate = medicines.time4
localNotificationtime4.timeZone = NSTimeZone.defaultTimeZone()
localNotificationtime4.soundName = UILocalNotificationDefaultSoundName
localNotificationtime4.applicationIconBadgeNumber = 1
localNotificationtime4.category = "reminderCategory"
UIApplication.sharedApplication().scheduleLocalNotification(localNotificationtime4)
let localNotificationtime5 = UILocalNotification()
localNotificationtime5.alertTitle = "Take", medicines.name
localNotificationtime5.alertBody = "It is time to take", medicines.name
localNotificationtime5.alertAction = "Show Details"
localNotificationtime5.fireDate = medicines.time5
localNotificationtime5.timeZone = NSTimeZone.defaultTimeZone()
localNotificationtime5.soundName = UILocalNotificationDefaultSoundName
localNotificationtime5.applicationIconBadgeNumber = 1
localNotificationtime5.category = "reminderCategory"
UIApplication.sharedApplication().scheduleLocalNotification(localNotificationtime5)
}
}
Here is my AppDelegate:
import UIKit
import CoreData
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
// Override point for customization after application launch.
return true
}
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
// Point for handling the local notification when the app is open.
// Showing reminder details in an alertview
UIAlertView(title: notification.alertTitle, message: notification.alertBody, delegate: nil, cancelButtonTitle: "OK").show()
}
func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) {
// Point for handling the local notification Action. Provided alongside creating the notification.
if identifier == "ShowDetails" {
// Showing reminder details in an alertview
UIAlertView(title: notification.alertTitle, message: notification.alertBody, delegate: nil, cancelButtonTitle: "OK").show()
} else if identifier == "Okay" {
} else if identifier == "Open App" {
//Launches app when open app button pressed
UIApplicationState.Active
}
completionHandler()
}
Here is my data model:
import UIKit
class Medicine : NSObject, NSCoding {
var name: String
var time1: NSDate
var time2: NSDate
var time3: NSDate
var time4: NSDate
var time5: NSDate
init?(name: String, time1: NSDate, time2: NSDate, time3: NSDate, time4: NSDate, time5: NSDate) {
self.name = name
self.time1 = time1
self.time2 = time2
self.time3 = time3
self.time4 = time4
self.time5 = time5
super.init()
if name.isEmpty {
return nil
}
}
I am also getting an error for the alert body and title since I don't know how I chain together the string followed by the stored information in the array.
Btw this is my first swift project since learning the language from scratch so go easy on me if I'm being an idiot. :(
Change these lines
localNotificationtime1.alertTitle = "Take", medicines.name
localNotificationtime1.alertBody = "It is time to take", medicines.name
to these
localNotificationtime1.alertTitle = "Take \(medicines.name)"
localNotificationtime1.alertBody = "It is time to take \(medicines.name)"
To add the time, add this code
localNotificationtime1.fireDate = NSDate(time1)