Swift UserDefaults.standard.register in AppDelegate didFinishLaunchingWithOptions is not working - swift

I am attempting to register a Standard UserDefault value in AppDelegate but getting nil when I try to get the value out in a ViewController. I did this all of time in Obj C. What am I missing with the Swift code here? Thanks
AppDelegate
private func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
// Override point for customization after application launch.
setupAppearance()
// register default values for userDefaults
UserDefaults.standard.register(defaults: [
"selectedUUID": "0"
])
UserDefaults.standard.synchronize(). // is this still needed?
return true
}
ViewController
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Get the uuid that was registered in AppDelegate
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var defaults: UserDefaults = UserDefaults.standard
var selectedUUID = defaults.string(forKey: "selectedUUID")
print(selectedUUID!) // selectedUUID is nil, why? }

You can use UserDefaults.standard.set to set the User Default value.
There is no need to call synchronize, according to Apple here:
Waits for any pending asynchronous updates to the defaults database
and returns; this method is unnecessary and shouldn't be used.
This was deprecated in iOS 12 (release notes).
Try placing the following code in your didFinishLaunchingWithOptions to see this work:
let testDefaults = UserDefaults.standard.object(forKey: "selectedUUID") as? String
if testDefaults != nil {
print("Found UUID")
} else {
print("Did Not Find UUID")
UserDefaults.standard.set(UUID().uuidString, forKey: "selectedUUID")
}

Related

How to share properties between AppDelegate and ViewController, and save before App is terminated

I have a class with properties updated in viewController. I wanted to save the properties when the app goes into background or quit using AppDelegate. I used the following codes but it appears that the properties were not passed to the AppDelegate. Furthermore the applicationWillTerminate codes did not seem to get executed.
// testClass is defined and the properties are updated in viewController, e.g
testClass.status = true // default is false
// I want to save testClass.status when the app goes into background or being terminated using the following:
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var vc = ViewController()
func applicationDidEnterBackground(_ application: UIApplication) {
print(vc.testClass.status) // prints false
//codes to save
}
// save before App is terminated
func applicationWillTerminate(_ application: UIApplication) {
print(vc.testClass.status) // this code did not get executed?
//codes to save
}
}
applicationWillTerminate is called only when a user terminates the app without switching it to background mode.
When the app is active, double press on Home button and terminate the app.
But if you switch the app to the background, and then try to terminate the app, applicationWillTerminate will not be called.
And you are creating an instance of ViewController in AppDelegate
var vc = ViewController()
If you change the testClass property in another ViewController class instance, you won't get that value here. So create a singleton class like this
class TestClass: NSObject {
static let shared = TestClass()
private override init() {
super.init()
}
var status = false
}
Now update the value in any view controller from the singleton class
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
TestClass.shared.status = true
}
}
In AppDelegate save and retrieve the value from UserDefaults
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
TestClass.shared.status = UserDefaults.standard.bool(forKey: "Status")
return true
}
func applicationDidEnterBackground(_ application: UIApplication) {
UserDefaults.standard.set(TestClass.shared.status, forKey: "Status")
}
func applicationWillTerminate(_ application: UIApplication) {
UserDefaults.standard.set(TestClass.shared.status, forKey: "Status")
}
}
Or create a computed property to save the value in UserDefaults whenever it is changed.
class TestClass: NSObject {
static let shared = TestClass()
private override init() {
super.init()
}
var status: Bool {
get {
return UserDefaults.standard.bool(forKey: "Status")
}
set {
UserDefaults.standard.set(newValue, forKey: "Status")
}
}
}
As already mentioned by others you can ignore applicationWillTerminate.
To get notified when the app goes into the background just add an observer in the view controller.
However rather than didEnterBackground I'd recommend to observe willResignActive.
Add the observer in viewDidLoad once
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(forName: UIApplication.willResignActiveNotification, object: nil, queue: nil) { notification in
// save the properties
}
}
Or if you are using multiple view controllers you can add the observer in viewWillAppear and remove it in viewDidDisappear
Side note:
Never create a view controller with the default initializer ViewController() if you are using storyboard. You'll get a brand new instance which is not the storyboard instance.

Performing Long-Term Actions in the Background Swift 3

I have an app that uses Corebluetooth and uses its Background services. I need also long-term CoreBluetooth action so I need to implement State preservation and restoration. I followed Apple document the link at the below https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html also watched WWDC 2013 presentation video link below,
https://developer.apple.com/videos/play/wwdc2013/703/
First of all, the sources are in Objective C and I am not familiar with that, I tried to convert them in swift3.
Then, I defined CBCentralManager with restoration identifier shown below,
self.myCentralManager = CBCentralManager(delegate: self, queue: nil, options: [CBCentralManagerOptionRestoreIdentifierKey: "myCentralManager"])
Then, added delegate method something in the below,
func centralManager( willRestoreState dict: [String : AnyObject]) {
let peripherals: [CBPeripheral] = dict[CBCentralManagerRestoredStatePeripheralsKey] as! [CBPeripheral]
for peripheral in peripherals {
self.peripherals.append(peripheral)
peripheral.delegate = self
}
}
Finally did didFinishLaunchingWithOptions method in AppDelegate,
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
if let peripheralManagerIdentifiers: [String] = launchOptions?[UIApplicationLaunchOptionsKey.bluetoothCentrals] as? [String]{
for identifier in peripheralManagerIdentifiers{
if (identifier == "myCentralManager"){
}
}
}
return true
}
When I debug, didFinishLaunchingWithOptions method called, the parameter launchOptions?[UIApplicationLaunchOptionsKey.bluetoothCentrals] is nil I think because of first time I created the app, then got error when defining CBCentralManager with restoration identifier the error is "reason: ' has provided a restore identifier but the delegate doesn't implement the centralManager:willRestoreState: method'"
I'm totally confused, thank you for any help,
Best regards,

Download in background in Swift

I'm trying to make my app download images in background. But when I press [Home] button, the app stop download. Is there any way to make it continue download even when I use another app? I have seen some apps can do like that but I don't know how.
This is what I've tried so far.
//
// AppDelegate.swift
// Swift-TableView-Example
//
// Created by Bilal ARSLAN on 11/10/14.
// Copyright (c) 2014 Bilal ARSLAN. All rights reserved.
//
import UIKit
import WebKit
protocol DownloadInBackgroundDelegate {
func downloadInBackgroundDidFinish(chapterid:Int, chaptername:String, storyid:Int, progressPercent:Float)
}
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var shareCache = NSURLCache()
var downloadDelegate:DownloadInBackgroundDelegate? = nil
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
var navigationBarAppearace = UINavigationBar.appearance()
application.setStatusBarOrientation(UIInterfaceOrientation.PortraitUpsideDown, animated: false)
self.startDownload()
return true
}
func application(application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
}
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
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.
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
FBAppEvents.activateApp()
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
}
func applicationDidReceiveMemoryWarning(application: UIApplication) {
NSURLCache.sharedURLCache().removeAllCachedResponses()
}
func application(application: UIApplication, willChangeStatusBarOrientation newStatusBarOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
application.windows
}
func startDownload(){
var filesPath = [String]()
filesPath.append("https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/iphoneappprogrammingguide.pdf")
filesPath.append("https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/MobileHIG.pdf")
filesPath.append("https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/NetworkingOverview.pdf")
filesPath.append("https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/AVFoundationPG/AVFoundationPG.pdf")
filesPath.append("http://manuals.info.apple.com/MANUALS/1000/MA1565/en_US/iphone_user_guide.pdf")
downloadFiles(0, filesPath: filesPath)
}
func downloadFiles(index: Int, filesPath: [String]) -> Void {
var imgURL: NSURL = NSURL(string: filesPath[index].stringByTrimmingCharactersInSet(.whitespaceAndNewlineCharacterSet()).stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!)!
let request: NSURLRequest = NSURLRequest(URL: imgURL)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {(response: NSURLResponse!,data: NSData!,error: NSError!) -> Void in
var fileCacheName = String(format: "%04d", index)
dispatch_async(dispatch_get_main_queue(), {
var fileExt = (data != nil && error == nil) ? Utility.checkImageType(data) : ""
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! String
let imagePath = paths.stringByAppendingPathComponent("\(fileCacheName).png")
if data.writeToFile(imagePath, atomically: false)
{
println("saved")
}
if index < filesPath.count - 1
{
var nextIndex:Int = index + 1
self.downloadFiles(nextIndex, filesPath: filesPath)
}
})
})
}
}
Answer
Based on the comment below, I found this thread : objective c - Proper use of beginBackgroundTaskWithExpirationHandler . I can solve my problem with it.
For downloading and storing of the images, instead of writing the logic yourself, I suggest you use some well known libraries, like:
https://github.com/Haneke/Haneke
https://github.com/rs/SDWebImage
Reason behind that is those libraries are well tested, quite robust and mainly very easy to use for basic tasks.
Now for the background download, there is beginBackgroundTaskWithExpirationHandler: that is specifically designed to do that. When you use it, you will get few more minutes to execute whatever you need (after that limit, your application will get terminated no matter what).
You can write following methods:
func beginBackgroundTask() -> UIBackgroundTaskIdentifier {
return UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({})
}
func endBackgroundTask(taskID: UIBackgroundTaskIdentifier) {
UIApplication.sharedApplication().endBackgroundTask(taskID)
}
When you want to use it, you just simple begin / end the task when starting / finishing the download call:
// Start task
let task = self.beginBackgroundTask()
// Do whatever you need
self.someBackgroundTask()
// End task
self.endBackgroundTask(task)
Hope it helps!
Use beginBackgroundTaskWithExpirationHandler: from the UIApplication to start a background task when the app enters the background
See Apple's document on multitasking background execution for details. See download in background in iphone its a similar question.

setObjectForKey method with custom objects doesn't work NSUserDefaults swift

I use the setObjectForKey method when I try to save a custom object, but when I try to retrieve it for the same key, it returns nil. I have been researching and I know that there is some issue with set custom objects to NSUserDefaults so I tried using NSKeyedArchiver class, but it still returns nil.
//
// VirtualRewardsClient.swift
// VirtualRewardsNew
//
// Created by Dhruv Mangtani on 3/14/15.
// Copyright (c) 2015 dhruv.mangtani. All rights reserved.
//
import UIKit
class VirtualRewardsClient{
class var sharedInstance: VirtualRewardsClient{
struct Static{
static var instance = VirtualRewardsClient()
}
return Static.instance
}
func getClass() -> Class{
var defaults = NSUserDefaults.standardUserDefaults()
println(defaults.objectForKey(classKey))
if let data = defaults.objectForKey(classKey) as? NSData{
//let unarc = NSKeyedUnarchiver(forReadingWithData: data)
//unarc.setClass(Class.self, forClassName: "Class")
let currentClass = NSKeyedUnarchiver.unarchiveObjectWithData(data) as Class
println("entering")
Class.sharedInstance.students = currentClass.students
Class.sharedInstance.teacher = currentClass.teacher
return currentClass
} else {
var newClass = Class()
newClass.students = [Student]()
var encodedObject: NSData = NSKeyedArchiver.archivedDataWithRootObject(newClass)
defaults.setObject(encodedObject, forKey: classKey)
defaults.synchronize()
return newClass
}
}
}
Class.swift
import Foundation
import UIKit
let classKey = "CLASS_KEY"
class Class: NSObject{
let defaults = NSUserDefaults.standardUserDefaults()
class var sharedInstance: Class{
struct Static{
static var instance: Class = VirtualRewardsClient.sharedInstance.getClass()
}
return Static.instance
}
var students:[Student] = [Student]()
var teacher = Teacher(currentClass: sharedInstance)
func addStudent(name: String, value: Int){
students.append(Student(name: name, startingPoints: value))
defaults.setObject(Class.sharedInstance, forKey: classKey)
VirtualRewardsClient.sharedInstance.getClass()
}
func addStudent(name: String){
students.append(Student(name: name))
defaults.setObject(Class.sharedInstance, forKey: classKey)
VirtualRewardsClient.sharedInstance.getClass()
}
func printClass(){
for i in students{
println("Student: \(i.name), Points: \(i.points)")
}
}
}
App Delegate:
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
/*var storyboard = UIStoryboard(name: "Main", bundle: nil)
var vc = storyboard.instantiateViewControllerWithIdentifier("StudentsNavigationController") as UIViewController
window?.rootViewController = vc
println("didFinishLaunchingWithOptions\(window?.rootViewController)")
*/
return true
}
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
println("applicationDidEnterBackground")
}
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
println("applicationWillEnterForeground")
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
println("applicationDidBecomeActive")
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
change Class to VirtualRewardsClient

Not able to set Interactive Push Notifications on iOS8

I was already able to set Interactive LOCAL notifications, but the Remote notifications aren't working. I'm using Parse.com to send the JSON
My AppDelegate.Swift looks like this:
//
// AppDelegate.swift
// SwifferApp
//
// Created by Training on 29/06/14.
// Copyright (c) 2014 Training. All rights reserved.
//
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
UINavigationBar.appearance().barTintColor = UIColor.orangeColor()
UINavigationBar.appearance().tintColor = UIColor.whiteColor()
Parse.setApplicationId("eUEC7O4Jad0Kt3orqRouU0OJhkGuE20n4uSfrLYE", clientKey: "WypmaQ8XyqH26AeWIANttqwUjRJR4CIM55ioXvez")
let notificationTypes:UIUserNotificationType = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound
let notificationSettings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
return true
}
func application(application: UIApplication!, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings!) {
UIApplication.sharedApplication().registerForRemoteNotifications()
}
func application(application: UIApplication!, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData!) {
let currentInstallation:PFInstallation = PFInstallation.currentInstallation()
currentInstallation.setDeviceTokenFromData(deviceToken)
currentInstallation.saveInBackground()
}
func application(application: UIApplication!, didFailToRegisterForRemoteNotificationsWithError error: NSError!) {
println(error.localizedDescription)
}
func application(application: UIApplication!, didReceiveRemoteNotification userInfo:NSDictionary!) {
var notification:NSDictionary = userInfo.objectForKey("aps") as NSDictionary
if notification.objectForKey("content-available"){
if notification.objectForKey("content-available").isEqualToNumber(1){
NSNotificationCenter.defaultCenter().postNotificationName("reloadTimeline", object: nil)
}
}else{
PFPush.handlePush(userInfo)
}
}
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
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.
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
on Parse, I'm setting the Push payload like this:
{
"alert": "Tune in for the World Series, tonight at 8pm EDT",
"badge": "Increment",
"sound": "chime",
"category": "FIRST_CATEGORY"
}
and I receive the push, but not with the custom buttons I've set.
I'm not sure if my problem is the same to yours (Make sure your problem is not due to Parse). Just post my solution here in case anyone else would encounter the same issue.
My problem is in the notification category.
Make sure you have set the category when registering the notification settings (I'm using Objective-C, no much difference):
UIMutableUserNotificationCategory *notificationCategory = [[UIMutableUserNotificationCategory alloc] init];
notificationCategory.identifier = #"CallNotificationCategory";
[notificationCategory setActions:#[declineAction, answerAction] forContext:UIUserNotificationActionContextDefault];
NSSet *categories = [[NSSet alloc] initWithObjects:notificationCategory, nil];
And, when you send remote notification, make sure you have "category" in the payload and the value is the same as you defined in the client. In my case it's something like:
{
"alert": "Tune in for the World Series, tonight at 8pm EDT",
"badge": "Increment",
"sound": "chime",
"category": "CallNotificationCategory"
}
This is in case if anyone comes across this problem while using Firebase Remote Notifications.
Just ask the backend developer to send:
"notification" : {
"title" : YOUR_TITLE,
"body" : YOUR_BODY,
"click_action" : YOUR_CATEGORY_NAME
}
You need to pass categories while registering for APNS.
Look at my sample :
var replyAction : UIMutableUserNotificationAction = UIMutableUserNotificationAction()
replyAction.identifier = "REPLY_ACTION"
replyAction.title = "Yes, I need!"
replyAction.activationMode = UIUserNotificationActivationMode.Background
replyAction.authenticationRequired = false
var replyCategory : UIMutableUserNotificationCategory = UIMutableUserNotificationCategory()
replyCategory.identifier = "REPLY_CATEGORY"
let replyActions:NSArray = [replyAction]
replyCategory.setActions(replyActions, forContext: UIUserNotificationActionContext.Default)
replyCategory.setActions(replyActions, forContext: UIUserNotificationActionContext.Minimal)
let categories = NSSet(object: replyCategory)
let settings : UIUserNotificationType = UIUserNotificationType.Sound | UIUserNotificationType.Alert | UIUserNotificationType.Badge
UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotificationSettings(forTypes: settings, categories: categories))
UIApplication.sharedApplication().registerForRemoteNotifications()
This worked for me to get interactive push notifications displaying and working in Swift with Parse. Note that you need to create a UIMutableNotificationAction for each interactive button you want to create. Source below goes into much more detail of configuring options for buttons.
In your app delegate file:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let notificationTypes:UIUserNotificationType = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound
var notificationActionAccept :UIMutableUserNotificationAction = UIMutableUserNotificationAction()
notificationActionAccept.identifier = "ACCEPT_IDENTIFIER"
notificationActionAccept.title = "Accept"
notificationActionAccept.destructive = true
notificationActionAccept.authenticationRequired = false
notificationActionAccept.activationMode = UIUserNotificationActivationMode.Background
var notificationCategory:UIMutableUserNotificationCategory = UIMutableUserNotificationCategory()
notificationCategory.identifier = "CallNotificationCategory"
notificationCategory .setActions([notificationActionAccept], forContext: UIUserNotificationActionContext.Default)
let notificationSettings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: NSSet(array:[notificationCategory]))
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
return true
}
And in Parse Cloud when you send the push, you would match the category to the UIMutableUserNotificationCategory like #Xialin mentioned above.
Looks like you weren't setting categories or at least not setting them until after you had registered the UINotificationSettings - you need to set them before or it won't work.
I got most of this info at the link below. It goes into more detail if needed. Hope this helps:
http://thecodeninja.tumblr.com/post/90742435155/notifications-in-ios-8-part-2-using-swift-what-is