diff --git a/LocalNotificationBase.xcodeproj/project.pbxproj b/LocalNotificationBase.xcodeproj/project.pbxproj index dd7afac..56f99b0 100644 --- a/LocalNotificationBase.xcodeproj/project.pbxproj +++ b/LocalNotificationBase.xcodeproj/project.pbxproj @@ -7,6 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + 869E664C22B2C8A4000E5866 /* EditViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 869E664B22B2C8A4000E5866 /* EditViewController.swift */; }; + 869E665022B2C958000E5866 /* sendNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 869E664F22B2C958000E5866 /* sendNotification.swift */; }; + 869E665222B2F071000E5866 /* logo.png in Resources */ = {isa = PBXBuildFile; fileRef = 869E665122B2F071000E5866 /* logo.png */; }; + 869E665422B2F70E000E5866 /* HaViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 869E665322B2F70E000E5866 /* HaViewController.swift */; }; AA6671C922B1292D00824252 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6671C822B1292D00824252 /* AppDelegate.swift */; }; AA6671CB22B1292D00824252 /* BaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6671CA22B1292D00824252 /* BaseViewController.swift */; }; AA6671CE22B1292D00824252 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA6671CC22B1292D00824252 /* Main.storyboard */; }; @@ -15,6 +19,10 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 869E664B22B2C8A4000E5866 /* EditViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditViewController.swift; sourceTree = ""; }; + 869E664F22B2C958000E5866 /* sendNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = sendNotification.swift; sourceTree = ""; }; + 869E665122B2F071000E5866 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = ""; }; + 869E665322B2F70E000E5866 /* HaViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HaViewController.swift; sourceTree = ""; }; AA6671C522B1292D00824252 /* LocalNotificationBase.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LocalNotificationBase.app; sourceTree = BUILT_PRODUCTS_DIR; }; AA6671C822B1292D00824252 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; AA6671CA22B1292D00824252 /* BaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseViewController.swift; sourceTree = ""; }; @@ -35,6 +43,26 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 869E664D22B2C8C3000E5866 /* View */ = { + isa = PBXGroup; + children = ( + AA6671D122B1293000824252 /* LaunchScreen.storyboard */, + AA6671CC22B1292D00824252 /* Main.storyboard */, + ); + path = View; + sourceTree = ""; + }; + 869E664E22B2C8CF000E5866 /* Controller */ = { + isa = PBXGroup; + children = ( + 869E664B22B2C8A4000E5866 /* EditViewController.swift */, + AA6671CA22B1292D00824252 /* BaseViewController.swift */, + 869E664F22B2C958000E5866 /* sendNotification.swift */, + 869E665322B2F70E000E5866 /* HaViewController.swift */, + ); + path = Controller; + sourceTree = ""; + }; AA6671BC22B1292D00824252 = { isa = PBXGroup; children = ( @@ -54,11 +82,11 @@ AA6671C722B1292D00824252 /* LocalNotificationBase */ = { isa = PBXGroup; children = ( + 869E664D22B2C8C3000E5866 /* View */, + 869E664E22B2C8CF000E5866 /* Controller */, AA6671C822B1292D00824252 /* AppDelegate.swift */, - AA6671CA22B1292D00824252 /* BaseViewController.swift */, - AA6671CC22B1292D00824252 /* Main.storyboard */, + 869E665122B2F071000E5866 /* logo.png */, AA6671CF22B1293000824252 /* Assets.xcassets */, - AA6671D122B1293000824252 /* LaunchScreen.storyboard */, AA6671D422B1293000824252 /* Info.plist */, ); path = LocalNotificationBase; @@ -122,6 +150,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 869E665222B2F071000E5866 /* logo.png in Resources */, AA6671D322B1293000824252 /* LaunchScreen.storyboard in Resources */, AA6671D022B1293000824252 /* Assets.xcassets in Resources */, AA6671CE22B1292D00824252 /* Main.storyboard in Resources */, @@ -135,7 +164,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 869E665422B2F70E000E5866 /* HaViewController.swift in Sources */, AA6671CB22B1292D00824252 /* BaseViewController.swift in Sources */, + 869E664C22B2C8A4000E5866 /* EditViewController.swift in Sources */, + 869E665022B2C958000E5866 /* sendNotification.swift in Sources */, AA6671C922B1292D00824252 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -283,7 +315,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = GT48V5L69E; + DEVELOPMENT_TEAM = CTAFH43K36; INFOPLIST_FILE = LocalNotificationBase/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -301,7 +333,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = GT48V5L69E; + DEVELOPMENT_TEAM = CTAFH43K36; INFOPLIST_FILE = LocalNotificationBase/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/LocalNotificationBase/AppDelegate.swift b/LocalNotificationBase/AppDelegate.swift index 07da379..3959af9 100644 --- a/LocalNotificationBase/AppDelegate.swift +++ b/LocalNotificationBase/AppDelegate.swift @@ -13,16 +13,18 @@ import UserNotifications class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - + let notificationCenter = UNUserNotificationCenter.current() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. - let options: UNAuthorizationOptions = [.alert,.sound,.badge] - let notificationCenter = UNUserNotificationCenter.current() + notificationCenter.delegate = self + + let options: UNAuthorizationOptions = [.alert, .sound, .badge] + notificationCenter.requestAuthorization(options: options) { (didAllow, error) in if !didAllow { - print("Notifications not allowed by user") + print("User has declined notifications") } } return true @@ -40,6 +42,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + application.applicationIconBadgeNumber = 0 } func applicationDidBecomeActive(_ application: UIApplication) { @@ -53,3 +56,90 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } +extension AppDelegate: UNUserNotificationCenterDelegate { + + + + 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) { + + //TAKE REPONSE OF THE ACTION + let identifier = response.actionIdentifier + + + //TAKE OPTION OF THE ACTION + if identifier == "repeat"{ + scheduleNotification("title", "String", "String", "identifier") + } + else if identifier == "open" { + + //Create a instance of the ViewController + let storyboard = UIStoryboard(name: "Main", bundle: nil); + let viewController: HaViewController = storyboard.instantiateViewController(withIdentifier: "HaViewController") as! HaViewController; + + // Then push that view controller onto the navigation stack + let rootViewController = self.window!.rootViewController as! UINavigationController; + rootViewController.pushViewController(viewController, animated: true); + + } + + completionHandler() + } + + + + func scheduleNotification(_ title:String, _ subtitle:String, _ body:String, _ identifier:String) { + + let content = UNMutableNotificationContent() + + //CREATE BODY OF THE NOTIFICATION + content.title = title + content.subtitle = subtitle + content.body = body + content.sound = UNNotificationSound.default + content.badge = 1 + content.categoryIdentifier = identifier + + + //SET IMAGE + let imageName = "logo" + 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] + + + + + //REQUEST NOTIFICATION + let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false) + let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger) + + notificationCenter.add(request) { (error) in + if let error = error { + print("Error \(error.localizedDescription)") + } + } + + + + //ACTIONS IN THE NOTIFICATION + let snoozeAction = UNNotificationAction(identifier: "repeat", title: "Repeat", options: []) + let deleteAction = UNNotificationAction(identifier: "open", title: "Open", options: [.foreground]) + let category = UNNotificationCategory(identifier: identifier, + actions: [snoozeAction, deleteAction], + intentIdentifiers: [], + options: []) + + notificationCenter.setNotificationCategories([category]) + } +} diff --git a/LocalNotificationBase/Base.lproj/Main.storyboard b/LocalNotificationBase/Base.lproj/Main.storyboard deleted file mode 100644 index 0d2afb5..0000000 --- a/LocalNotificationBase/Base.lproj/Main.storyboard +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/LocalNotificationBase/BaseViewController.swift b/LocalNotificationBase/BaseViewController.swift deleted file mode 100644 index b3615fb..0000000 --- a/LocalNotificationBase/BaseViewController.swift +++ /dev/null @@ -1,47 +0,0 @@ -// -// ViewController.swift -// LocalNotificationBase -// -// Created by Bruno Omella Mainieri on 12/06/19. -// Copyright © 2019 Bruno Omella Mainieri. All rights reserved. -// - -import UIKit -import UserNotifications - -class BaseViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - } - - @IBAction func remindButton(_ sender: Any) { - let notificationCenter = UNUserNotificationCenter.current() - notificationCenter.getNotificationSettings { (settings) in - if settings.authorizationStatus == .authorized { - - let content = UNMutableNotificationContent() - content.title = NSString.localizedUserNotificationString(forKey: "Lembre-se", arguments: nil) - content.body = NSString.localizedUserNotificationString(forKey: "Você se lembrou", arguments: nil) - content.sound = UNNotificationSound.default - - let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false) - - let request = UNNotificationRequest(identifier: "5seconds", content: content, trigger: trigger) - - let center = UNUserNotificationCenter.current() - center.add(request) { (error : Error?) in - if let error = error { - print(error.localizedDescription) - } - } - - } else { - print("Impossível mandar notificação - permissão negada") - } - } - } - -} - diff --git a/LocalNotificationBase/Controller/BaseViewController.swift b/LocalNotificationBase/Controller/BaseViewController.swift new file mode 100644 index 0000000..eb6da47 --- /dev/null +++ b/LocalNotificationBase/Controller/BaseViewController.swift @@ -0,0 +1,25 @@ +// +// ViewController.swift +// LocalNotificationBase +// +// Created by Bruno Omella Mainieri on 12/06/19. +// Copyright © 2019 Bruno Omella Mainieri. All rights reserved. +// + +import UIKit +import UserNotifications + +class BaseViewController: UIViewController { + var appDelegate = UIApplication.shared.delegate as? AppDelegate + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + } + + @IBAction func remindButton(_ sender: Any) { +// sendNotificationLocal("Lembre-se", "ocê se lembrou", "5", 5, true, 1) + self.appDelegate?.scheduleNotification("title", "subtitle", "body", "identifier") + } + +} + diff --git a/LocalNotificationBase/Controller/EditViewController.swift b/LocalNotificationBase/Controller/EditViewController.swift new file mode 100644 index 0000000..b151db9 --- /dev/null +++ b/LocalNotificationBase/Controller/EditViewController.swift @@ -0,0 +1,83 @@ +// +// editViewController.swift +// LocalNotificationBase +// +// Created by Matheus Gois on 13/06/19. +// Copyright © 2019 Bruno Omella Mainieri. All rights reserved. +// + +import UIKit + +class EditViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { + + + @IBOutlet weak var titleNotification: UITextField! + @IBOutlet weak var bodyNotification: UITextField! + + @IBOutlet weak var changeTimePickerNotification: UIPickerView! + @IBOutlet weak var enableSoundNotification: UISwitch! + @IBOutlet weak var enableBadgeNotification: UISwitch! + + var array = ["1","2","3","4","5","6","7","8","9","10"] + var timeSelected = "" + + @IBAction func sendNotification(_ sender: UIButton) { + let title = titleNotification.text as! String + let body = bodyNotification.text as! String + let stateBadge = self.enableBadgeNotification.isOn + let stateSound = self.enableSoundNotification.isOn + guard let time = TimeInterval(self.timeSelected) else { return } + + sendNotificationLocal(title, body, "1", time, stateSound, (stateBadge ? 1 : 0)) + + } + + override func viewDidLoad() { + super.viewDidLoad() + + timeSelected = array[0] + + // Do any additional setup after loading the view. + self.changeTimePickerNotification.delegate = self + self.changeTimePickerNotification.dataSource = self + } + + + + func numberOfComponents(in pickerView: UIPickerView) -> Int { + return 1 + } + + func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + return array.count + } + func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + return array[row] + } + + func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + timeSelected = array[row] + } + + + +} + + +//func stringFromTimeInterval (interval: String) -> TimeInterval { +// let endingDate = Date() +// if let timeInterval = TimeInterval(interval) { +// let startingDate = endingDate.addingTimeInterval(-timeInterval) +// let calendar = Calendar.current +// +// var componentsNow = calendar.dateComponents([.hour, .minute, .second], from: startingDate, to: endingDate) +// if let hour = componentsNow.hour, let minute = componentsNow.minute, let seconds = componentsNow.second { +// return "\(hour):\(minute):\(seconds)" +// } else { +// return "00:00:00" +// } +// +// } else { +// return "00:00:00" +// } +//} diff --git a/LocalNotificationBase/Controller/HaViewController.swift b/LocalNotificationBase/Controller/HaViewController.swift new file mode 100644 index 0000000..fbbbb8a --- /dev/null +++ b/LocalNotificationBase/Controller/HaViewController.swift @@ -0,0 +1,30 @@ +// +// HaViewController.swift +// LocalNotificationBase +// +// Created by Matheus Gois on 13/06/19. +// Copyright © 2019 Bruno Omella Mainieri. All rights reserved. +// + +import UIKit + +class HaViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/LocalNotificationBase/Controller/sendNotification.swift b/LocalNotificationBase/Controller/sendNotification.swift new file mode 100644 index 0000000..a69dfa1 --- /dev/null +++ b/LocalNotificationBase/Controller/sendNotification.swift @@ -0,0 +1,52 @@ +// +// sendNotification.swift +// LocalNotificationBase +// +// Created by Matheus Gois on 13/06/19. +// Copyright © 2019 Bruno Omella Mainieri. All rights reserved. +// + +import Foundation +import UserNotifications + +func sendNotificationLocal(_ title:String, _ body:String, _ identifier: String, _ timeInterval:TimeInterval, _ sound:Bool, _ badge:NSNumber) -> Void{ + let notificationCenter = UNUserNotificationCenter.current() + notificationCenter.getNotificationSettings { (settings) in + if settings.authorizationStatus == .authorized { + + let content = UNMutableNotificationContent() + content.title = NSString.localizedUserNotificationString(forKey: title, arguments: nil) + content.body = NSString.localizedUserNotificationString(forKey: body, arguments: nil) + + content.sound = sound ? UNNotificationSound.default : nil + content.badge = badge + + let trigger = UNTimeIntervalNotificationTrigger(timeInterval: timeInterval, repeats: false) + + let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger) + + let center = UNUserNotificationCenter.current() + center.add(request) { (error : Error?) in + if let error = error { + print(error.localizedDescription) + } + } + + + + //Actions + let snoozeAction = UNNotificationAction(identifier: "Snooze", title: "Snooze", options: []) + let deleteAction = UNNotificationAction(identifier: "DeleteAction", title: "Delete", options: [.destructive]) + let category = UNNotificationCategory(identifier: identifier, + actions: [snoozeAction, deleteAction], + intentIdentifiers: [], + options: []) + + center.setNotificationCategories([category]) + + + } else { + print("Impossível mandar notificação - permissão negada") + } + } +} diff --git a/LocalNotificationBase/Base.lproj/LaunchScreen.storyboard b/LocalNotificationBase/View/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from LocalNotificationBase/Base.lproj/LaunchScreen.storyboard rename to LocalNotificationBase/View/Base.lproj/LaunchScreen.storyboard diff --git a/LocalNotificationBase/View/Base.lproj/Main.storyboard b/LocalNotificationBase/View/Base.lproj/Main.storyboard new file mode 100644 index 0000000..8e4a25a --- /dev/null +++ b/LocalNotificationBase/View/Base.lproj/Main.storyboard @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LocalNotificationBase/logo.png b/LocalNotificationBase/logo.png new file mode 100644 index 0000000..87e9f4a Binary files /dev/null and b/LocalNotificationBase/logo.png differ