From 21ac3bcddcb1e2eea4c1fe6ec630113a4617b915 Mon Sep 17 00:00:00 2001 From: Sudheendra K Kaanugovi Date: Wed, 24 Feb 2016 19:01:01 -0500 Subject: [PATCH 1/2] Updated to Swift2 Syntax and work with Xcode 7.2 --- .../project.pbxproj | 9 +- .../UserInterfaceState.xcuserstate | Bin 0 -> 14036 bytes .../LocalNotificationsTutorial.xcscheme | 101 ++++++++++++++++++ .../xcschemes/xcschememanagement.plist | 27 +++++ LocalNotificationsTutorial/AppDelegate.swift | 10 +- LocalNotificationsTutorial/Info.plist | 2 +- LocalNotificationsTutorial/TodoList.swift | 28 +++-- .../TodoSchedulingViewController.swift | 13 +-- .../TodoTableViewController.swift | 4 +- LocalNotificationsTutorialTests/Info.plist | 2 +- 10 files changed, 169 insertions(+), 27 deletions(-) create mode 100644 LocalNotificationsTutorial.xcodeproj/project.xcworkspace/xcuserdata/chinnu.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 LocalNotificationsTutorial.xcodeproj/xcuserdata/chinnu.xcuserdatad/xcschemes/LocalNotificationsTutorial.xcscheme create mode 100644 LocalNotificationsTutorial.xcodeproj/xcuserdata/chinnu.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/LocalNotificationsTutorial.xcodeproj/project.pbxproj b/LocalNotificationsTutorial.xcodeproj/project.pbxproj index c2c71f7..11355ff 100644 --- a/LocalNotificationsTutorial.xcodeproj/project.pbxproj +++ b/LocalNotificationsTutorial.xcodeproj/project.pbxproj @@ -165,7 +165,9 @@ 7469E4231A7C8E8200C68120 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0620; + LastSwiftMigration = 0720; + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0720; TargetAttributes = { 7469E42A1A7C8E8200C68120 = { CreatedOnToolsVersion = 6.2; @@ -286,6 +288,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -351,6 +354,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = LocalNotificationsTutorial/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.lumarow.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -361,6 +365,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = LocalNotificationsTutorial/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.lumarow.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -379,6 +384,7 @@ ); INFOPLIST_FILE = LocalNotificationsTutorialTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.lumarow.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LocalNotificationsTutorial.app/LocalNotificationsTutorial"; }; @@ -394,6 +400,7 @@ ); INFOPLIST_FILE = LocalNotificationsTutorialTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.lumarow.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LocalNotificationsTutorial.app/LocalNotificationsTutorial"; }; diff --git a/LocalNotificationsTutorial.xcodeproj/project.xcworkspace/xcuserdata/chinnu.xcuserdatad/UserInterfaceState.xcuserstate b/LocalNotificationsTutorial.xcodeproj/project.xcworkspace/xcuserdata/chinnu.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..27c31bb99c551cb347ac10813342480865bef5e7 GIT binary patch literal 14036 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 S1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LocalNotificationsTutorial.xcodeproj/xcuserdata/chinnu.xcuserdatad/xcschemes/xcschememanagement.plist b/LocalNotificationsTutorial.xcodeproj/xcuserdata/chinnu.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..6ea026f --- /dev/null +++ b/LocalNotificationsTutorial.xcodeproj/xcuserdata/chinnu.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,27 @@ + + + + + SchemeUserState + + LocalNotificationsTutorial.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + 7469E42A1A7C8E8200C68120 + + primary + + + 7469E43F1A7C8E8200C68120 + + primary + + + + + diff --git a/LocalNotificationsTutorial/AppDelegate.swift b/LocalNotificationsTutorial/AppDelegate.swift index 7d8b7bc..5629c79 100644 --- a/LocalNotificationsTutorial/AppDelegate.swift +++ b/LocalNotificationsTutorial/AppDelegate.swift @@ -31,19 +31,19 @@ class AppDelegate: UIResponder, UIApplicationDelegate { todoCategory.setActions([remindAction, completeAction], forContext: .Default) // UIUserNotificationActionContext.Default (4 actions max) todoCategory.setActions([completeAction, remindAction], forContext: .Minimal) // UIUserNotificationActionContext.Minimal - for when space is limited (2 actions max) - application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: .Alert | .Badge | .Sound, categories: NSSet(array: [todoCategory]))) // we're now providing a set containing our category as an argument + application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: Set([todoCategory]))) // we're now providing a set containing our category as an argument return true } func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) { - var item = TodoItem(deadline: notification.fireDate!, title: notification.userInfo!["title"] as String, UUID: notification.userInfo!["UUID"] as String!) + let item = TodoItem(deadline: notification.fireDate!, title: notification.userInfo!["title"] as! String, UUID: notification.userInfo!["UUID"] as! String!) switch (identifier!) { case "COMPLETE_TODO": TodoList().removeItem(item) case "REMIND": TodoList().scheduleReminderforItem(item) default: // switch statements must be exhaustive - this condition should never be met - println("Error: unexpected notification action identifier!") + print("Error: unexpected notification action identifier!") } completionHandler() // per developer documentation, app will terminate if we fail to call this } @@ -57,8 +57,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } func applicationWillResignActive(application: UIApplication) { // fired when user quits the application - var todoItems: [TodoItem] = TodoList().allItems() // retrieve list of all to-do items - var overdueItems = todoItems.filter({ (todoItem) -> Bool in + let todoItems: [TodoItem] = TodoList().allItems() // retrieve list of all to-do items + let overdueItems = todoItems.filter({ (todoItem) -> Bool in return todoItem.deadline.compare(NSDate()) != .OrderedDescending }) UIApplication.sharedApplication().applicationIconBadgeNumber = overdueItems.count // set our badge number to number of overdue items diff --git a/LocalNotificationsTutorial/Info.plist b/LocalNotificationsTutorial/Info.plist index c112b87..40c6215 100644 --- a/LocalNotificationsTutorial/Info.plist +++ b/LocalNotificationsTutorial/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.lumarow.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/LocalNotificationsTutorial/TodoList.swift b/LocalNotificationsTutorial/TodoList.swift index 5181ab8..1627bbd 100644 --- a/LocalNotificationsTutorial/TodoList.swift +++ b/LocalNotificationsTutorial/TodoList.swift @@ -13,8 +13,8 @@ class TodoList { private let savePath = (NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString).stringByAppendingPathComponent("todo.plist") // ~/todo.plist func allItems() -> [TodoItem] { - var items: [AnyObject] = self.rawItems() - return items.map({TodoItem(deadline: $0["deadline"] as NSDate, title: $0["title"] as String, UUID: $0["UUID"] as String!)}).sorted({ + let items: [AnyObject] = self.rawItems() + return items.map({TodoItem(deadline: $0["deadline"] as! NSDate, title: $0["title"] as! String, UUID: $0["UUID"] as! String!)}).sort({ return ($0.deadline.compare($1.deadline) == .OrderedAscending) }) } @@ -22,17 +22,20 @@ class TodoList { private func rawItems() -> [AnyObject] { var items: Array = [] // default to an empty array... if (NSArray(contentsOfFile: self.savePath) != nil) { // ...because init?(contentsOfFile:) will return nil if file doesn't exist yet - items = NSArray(contentsOfFile: self.savePath)! // load stored items, if available + items = NSArray(contentsOfFile: self.savePath)! as Array // load stored items, if available } return items } func setBadgeNumbers() { - var notifications = UIApplication.sharedApplication().scheduledLocalNotifications as [UILocalNotification] // all scheduled notifications - var todoItems: [TodoItem] = self.allItems() + guard let notifications = UIApplication.sharedApplication().scheduledLocalNotifications else { + return + } + + let todoItems: [TodoItem] = self.allItems() for notification in notifications { - var overdueItems = todoItems.filter({ (todoItem) -> Bool in // array of to-do items... + let _ = todoItems.filter({ (todoItem) -> Bool in // array of to-do items... return (todoItem.deadline.compare(notification.fireDate!) != .OrderedDescending) // ...where item deadline is before or on notification fire date }) UIApplication.sharedApplication().cancelLocalNotification(notification) // cancel old notification @@ -48,7 +51,7 @@ class TodoList { (items as NSArray).writeToFile(self.savePath, atomically: true) // items casted as NSArray because writeToFile:atomically: is not available on Swift arrays // create a corresponding local notification - var notification = UILocalNotification() + let notification = UILocalNotification() notification.alertBody = "Todo Item \"\(item.title)\" Is Overdue" // text that will be displayed in the notification notification.alertAction = "open" // text that is displayed after "slide to..." on the lock screen - defaults to "slide to view" notification.fireDate = item.deadline // todo item due date (when notification will be fired) @@ -62,7 +65,7 @@ class TodoList { } func scheduleReminderforItem(item: TodoItem) { - var notification = UILocalNotification() // create a new reminder notification + let notification = UILocalNotification() // create a new reminder notification notification.alertBody = "Reminder: Todo Item \"\(item.title)\" Is Overdue" // text that will be displayed in the notification notification.alertAction = "open" // text that is displayed after "slide to..." on the lock screen - defaults to "slide to view" notification.fireDate = NSDate().dateByAddingTimeInterval(30 * 60) // 30 minutes from current time @@ -74,15 +77,18 @@ class TodoList { } func removeItem(item: TodoItem) { - for notification in UIApplication.sharedApplication().scheduledLocalNotifications as [UILocalNotification] { // loop through notifications... - if (notification.userInfo!["UUID"] as String == item.UUID) { // ...and cancel the notification that corresponds to this TodoItem instance (matched by UUID) + guard let notifications = UIApplication.sharedApplication().scheduledLocalNotifications else { + return + } + for notification in notifications { // loop through notifications... + if (notification.userInfo!["UUID"] as! String == item.UUID) { // ...and cancel the notification that corresponds to this TodoItem instance (matched by UUID) UIApplication.sharedApplication().cancelLocalNotification(notification) // there should be a maximum of one match on UUID break } } var items: [AnyObject] = self.rawItems() - items = items.filter {($0["UUID"] as String? != item.UUID)} // remove item that matches UUID + items = items.filter {($0["UUID"] as! String? != item.UUID)} // remove item that matches UUID (items as NSArray).writeToFile(self.savePath, atomically: true) // overwrite todo.plist with new array self.setBadgeNumbers() diff --git a/LocalNotificationsTutorial/TodoSchedulingViewController.swift b/LocalNotificationsTutorial/TodoSchedulingViewController.swift index bd4bede..f37e440 100644 --- a/LocalNotificationsTutorial/TodoSchedulingViewController.swift +++ b/LocalNotificationsTutorial/TodoSchedulingViewController.swift @@ -13,14 +13,15 @@ class TodoSchedulingViewController: UIViewController { @IBOutlet weak var deadlinePicker: UIDatePicker! @IBAction func savePressed(sender: UIButton) { - if (countElements(titleField.text.stringByTrimmingCharactersInSet(.whitespaceCharacterSet())) > 0) { // only save if titlefield text contains non-whitespace characters - let todoItem = TodoItem(deadline: deadlinePicker.date, title: titleField.text, UUID: NSUUID().UUIDString) - TodoList().addItem(todoItem) // schedule a local notification to persist this item - self.navigationController?.popToRootViewControllerAnimated(true) // return to list view where the newly created item will be displayed - } else { // text field was blank or contained only whitespace - var alertController = UIAlertController(title: "Error", message: "You must give this todo item a title", preferredStyle: .Alert) + guard let text = titleField.text where text.stringByTrimmingCharactersInSet(.whitespaceCharacterSet()).characters.count > 0 else { + // text field was blank or contained only whitespace + let alertController = UIAlertController(title: "Error", message: "You must give this todo item a title", preferredStyle: .Alert) alertController.addAction(UIAlertAction(title: "Ok", style: .Cancel, handler: nil)) self.presentViewController(alertController, animated: true, completion: nil) + return } + let todoItem = TodoItem(deadline: deadlinePicker.date, title: text, UUID: NSUUID().UUIDString) + TodoList().addItem(todoItem) // schedule a local notification to persist this item + self.navigationController?.popToRootViewControllerAnimated(true) // return to list view where the newly created item will be displayed } } \ No newline at end of file diff --git a/LocalNotificationsTutorial/TodoTableViewController.swift b/LocalNotificationsTutorial/TodoTableViewController.swift index 448750a..74a50bc 100644 --- a/LocalNotificationsTutorial/TodoTableViewController.swift +++ b/LocalNotificationsTutorial/TodoTableViewController.swift @@ -59,14 +59,14 @@ class TodoTableViewController: UITableViewController { return true // all cells are editable } - override func tableView(tableView: UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath indexPath: NSIndexPath) -> String! { + override func tableView(tableView: UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath indexPath: NSIndexPath) -> String? { return "Complete" // alternate text for delete button } override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { if editingStyle == .Delete { // the only editing style we'll support // Delete the row from the data source - var item = todoItems.removeAtIndex(indexPath.row) // remove TodoItem from notifications array, assign removed item to 'item' + let item = todoItems.removeAtIndex(indexPath.row) // remove TodoItem from notifications array, assign removed item to 'item' tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) TodoList().removeItem(item) // delete backing property list entry and unschedule local notification (if it still exists) self.navigationItem.rightBarButtonItem!.enabled = true // we definitely have under 64 notifications scheduled now, make sure 'add' button is enabled diff --git a/LocalNotificationsTutorialTests/Info.plist b/LocalNotificationsTutorialTests/Info.plist index 749b5c4..ba72822 100644 --- a/LocalNotificationsTutorialTests/Info.plist +++ b/LocalNotificationsTutorialTests/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.lumarow.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName From bdc5265e9fed9da25a089007622efe5f5841a3a0 Mon Sep 17 00:00:00 2001 From: Sudheendra K Kaanugovi Date: Wed, 24 Feb 2016 21:06:52 -0500 Subject: [PATCH 2/2] Fixed indentation and newline. --- .../TodoSchedulingViewController.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/LocalNotificationsTutorial/TodoSchedulingViewController.swift b/LocalNotificationsTutorial/TodoSchedulingViewController.swift index f37e440..9e362eb 100644 --- a/LocalNotificationsTutorial/TodoSchedulingViewController.swift +++ b/LocalNotificationsTutorial/TodoSchedulingViewController.swift @@ -20,8 +20,8 @@ class TodoSchedulingViewController: UIViewController { self.presentViewController(alertController, animated: true, completion: nil) return } - let todoItem = TodoItem(deadline: deadlinePicker.date, title: text, UUID: NSUUID().UUIDString) - TodoList().addItem(todoItem) // schedule a local notification to persist this item - self.navigationController?.popToRootViewControllerAnimated(true) // return to list view where the newly created item will be displayed + let todoItem = TodoItem(deadline: deadlinePicker.date, title: text, UUID: NSUUID().UUIDString) + TodoList().addItem(todoItem) // schedule a local notification to persist this item + self.navigationController?.popToRootViewControllerAnimated(true) // return to list view where the newly created item will be displayed } -} \ No newline at end of file +}