Background Fetch, UILocalNotification and Apple Watch - ios

I write an iPhone app with Apple Watch. My app should implement the background fetch mode and if there is new data, I send a UILocalNotification and I want my Apple Watch be able to display this notification.
The background fetch part and also the notification works both very well, but the notification is never display in my Apple Watch, even if my iPhone is in sleep mode.
But if I try the same thing but without background fetch, just scheduling a UILocalNotification each minute, all is ok and I can see my notification in my Apple Watch.
So I suppose there is an issue when the notification is sent from the "performFetchWithCompletionHandler" method, however I don't understand why and what I can do to correct this behaviour.
This is my code in my app delegate:
import UIKit
import Alamofire
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let settings = UIUserNotificationSettings.init(forTypes: UIUserNotificationType.Alert, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
return true
}
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
print("App is registered to receive local notifications")
}
func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
print("########### Received Background Fetch ###########");
if isConnectedToNetwork() {
// Download the Content
let urlString = NSUserDefaults.standardUserDefaults().stringForKey(kServerUrl)
Alamofire.request(.GET, urlString!, parameters: nil)
.responseJSON() { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
self.sendLocalNotification(JSON as! [String : String])
completionHandler(.NewData);
} else {
completionHandler(.NoData)
}
}
} else {
print("No Internet connection: unable to fetch data.")
completionHandler(.NoData)
}
}
private func sendLocalNotification(dictionary: [String: String]) {
let seatInfo = dictionary["seat"]
let seat = "Seat: \(seatInfo)"
let amountInfo = dictionary["amount"]
let amount = "Amount: \(amountInfo)"
let localNotification = UILocalNotification()
localNotification.fireDate = NSDate(timeIntervalSinceNow: 0)
localNotification.alertTitle = "New order"
localNotification.alertBody = seat + "\n" + amount
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
}
And here in my NotificationController.swift:
import WatchKit
import Foundation
class NotificationController: WKUserNotificationInterfaceController {
#IBOutlet var alertLabel : WKInterfaceLabel!
#IBOutlet var bodyLabel : WKInterfaceLabel!
override init() {
// Initialize variables here.
super.init()
// Configure interface objects here.
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
super.didDeactivate()
}
override func didReceiveLocalNotification(localNotification: UILocalNotification, withCompletion completionHandler: ((WKUserNotificationInterfaceType) -> Void)) {
self.alertLabel.setText(localNotification.alertTitle)
self.bodyLabel.setText(localNotification.alertBody)
completionHandler(.Custom)
}
}

Related

I'd like to count badges from ios. You can't try everything about how to do it

This is a list of methods I used.
Use firebase on Background Handler.
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(onBackgroundHandler);
}
Future onBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
FlutterAppBadger.updateBadgeCount(10);
return Future.value();
}
it`s not working
Code AppDelegate is coded directly.
#UIApplicationMain
#objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func applicationDidBecomeActive(_ application: UIApplication) {
UIApplication.shared.applicationIconBadgeNumber = 0
}
}
it`s not working
Coding directly to the code added to Notification Service Extension.
#available(iOSApplicationExtension, unavailable)
class NotificationViewController: UIViewController, UNNotificationContentExtension {
#IBOutlet var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
#available(iOSApplicationExtension 10.0, *)
func didReceive(_ notification: UNNotification) {
let content = notification.request.content
let count = UIApplication.shared.applicationIconBadgeNumber
UIApplication.shared.applicationIconBadgeNumber = count + 1
if let urlImageString = content.userInfo["urlImageString"] as? String {
if let url = URL(string: urlImageString) {
URLSession.downloadImage(atURL: url) { [weak self] (data, error) in
if let _ = error {
return
}
guard let data = data else {
return
}
DispatchQueue.main.async {
self?.imageView.image = UIImage(data: data)
}
}
}
}
}
}
it`s not working
Coding directly to the code added to Notification controller extension.
#available(iOSApplicationExtension, unavailable)
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: #escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
let count = UIApplication.shared.applicationIconBadgeNumber
UIApplication.shared.applicationIconBadgeNumber = count + 1
https://pushpsenairekar.medium.com/increment-ios-apps-badge-count-in-using-5-simple-steps-3d80e77d45c8 referred to the blog.
I don't want to count badges directly on fcm.
How can I increase the count of badges every time I get a notification?
I understand this might be frustrating. The issue is that you think you need to increase the badge number manually and programmatically and that's not the right way of doing that.
What you want is your notification payload to actually include an integer for its badge key stating to iOS as an operating system what badge integer to display for your application.
This documentation for Firebase notifications will clear things up for you. So instead of trying to do that manually, include the integer value of your badge for iOS inside the notification itself.

AppDelegate Never Gets Its didReceiveRemoteNotification Called For CKQuerySubscription

I'm trying to let the iOS app listen to CKQuerySubscription changes. Data is transmitted by a remote iOS app. I already have a macOS application, which does receive data sent by the remote iOS app. The iOS app I have trouble with already has a subscription. Yet, its AppDelegate never receives a call in the didReceiveRemoteNotification method.
import UIKit
import UserNotifications
import CloudKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
/* notifications */
let center = UNUserNotificationCenter.current()
center.delegate = self
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
switch settings.authorizationStatus {
case .authorized:
print("You already have permission")
DispatchQueue.main.async() {
application.registerForRemoteNotifications()
}
case .denied:
print("setting has been disabled")
case .notDetermined:
print("Let me ask")
UNUserNotificationCenter.current().requestAuthorization(options: []) { (granted, error) in
if error == nil {
if granted {
print("you are granted permission")
DispatchQueue.main.async() {
application.registerForRemoteNotifications()
}
}
}
}
}
}
return true
}
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Failed to register notifications_ error:", error)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
print("Receiving data...") // never called...
}
}
I have some capabilities on as shown below. I don't know if the app needs push notifications. For now, it's turned on.
So why doesn't my iOS app get the remote notification call? I'm using the app with an actual device, not a simulator. Thanks.
EDIT: Creating a subscription to a record change
class HomeViewController: UIViewController {
override func viewDidLoad() {
registerSubscription()
}
func registerSubscription() {
let cloudContainer = CKContainer(identifier: "iCloud.com.xxx.XXXXX")
let privateDB = cloudContainer.privateCloudDatabase
let predicate = NSPredicate(format: "TRUEPREDICATE")
let subscription = CKQuerySubscription(recordType: "PrivateRecords", predicate: predicate, options: .firesOnRecordCreation)
let notification = CKNotificationInfo()
subscription.notificationInfo = notification
privateDB.save(subscription, completionHandler: ({returnRecord, error in
if let err = error {
print("Subscription has failed: \(err.localizedDescription)")
} else {
print("Subscription set up successfully")
print("Subscription ID: \(subscription.subscriptionID)")
}
}))
}
}
There are a few more things you can check.
First, make sure you implement didReceiveRemoteNotification in your app delegate:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
let dict = userInfo as! [String: NSObject]
let notification = CKNotification(fromRemoteNotificationDictionary: dict)
if let sub = notification.subscriptionID{
print("iOS Notification Received: \(sub)")
}
}
There are also a few other things you can check:
Try deleting your CKQuerySubscription in the CloudKit dashboard, then run your iOS code again that registers it. Does the subscription show up in the dashboard?
Does the CloudKit log show that a notification was sent? It lists all notifications that were pushed to a device.
If you are using silent push notifications, try enabling Background fetch in the Background Modes capability (right above Remote notifications).
If you do all that and it still doesn't work, can you share your CKQuerySubscription code?
-- Update --
Try setting some additional attributes on your CKNotificationInfo object. There are some obscure bugs with notifications that can usually be circumvented by setting a couple properties like this:
notification.shouldSendContentAvailable = true
notification.alertBody = "" //(Yes, a blank value. It affects the priority of the notification delivery)
You can also try setting your predicate to: NSPredicate(value: true)
Also, what does your privateDB.save method return? Does it say it succeeds or fails?

SWIFT: I dont get notifications from my CloudKit app?

I asked this question and people have answered but nothing ever works. This is very important to me that I can get this to work. Here is some of my code:
#IBAction func sendSweet(sender: AnyObject) {
//delegate method
let newSweet = CKRecord(recordType: "Extra1")
newSweet["content"] = textField.text
let publicData = CKContainer.defaultContainer().publicCloudDatabase
publicData.saveRecord(newSweet, completionHandler: { (record:CKRecord?, error:NSError?) -> Void in
if error == nil {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.beginUpdates()
self.sweets.insert(newSweet, atIndex: 0)
let indexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Top)
self.tableView.endUpdates()
self.textField.text = ""
self.textField.resignFirstResponder()
})
}})
// Put the CloudKit private database in a constants
let privateDatabase = CKContainer.defaultContainer().publicCloudDatabase
// Create subscription and set three of its properties (an id, a predicate, and options)
let friendsSubscription = CKSubscription(recordType: "Extra1",
predicate: NSPredicate(format: "TRUEPREDICATE"),
subscriptionID: "Extra1",
options: .FiresOnRecordCreation)
// Create a notification and set two of its properties (alertBody and shouldBadge)
let notificationInfo = CKNotificationInfo()
notificationInfo.alertBody = "New message in Lms Chat"
notificationInfo.shouldBadge = false
// Attach the notification to the subscription
friendsSubscription.notificationInfo = notificationInfo
// Save the subscription in the private database
privateDatabase.saveSubscription(friendsSubscription) {recordReturned, error in
// On the main thread, display an error/success message in the textView
if error != nil {
NSOperationQueue.mainQueue().addOperationWithBlock {
self.textField.text = "Cloud error\n\(error!.localizedDescription)"
}
} else {
NSOperationQueue.mainQueue().addOperationWithBlock {
self.textField.text = ""
}
}
}
}
func textFieldShouldEndEditing(textField: UITextField!) -> Bool { //delegate method
return false
}
func textFieldShouldReturn(textField: UITextField!) -> Bool { //delegate method
textField.resignFirstResponder()
return true
}
It's a messaging app so people can message eachother but I also want them to recieve notifications. This is the code for notifications and I also have some code for notifications in App Delegate:
import UIKit
import CloudKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
UIApplication.sharedApplication().registerForRemoteNotifications()
return true
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
print(deviceToken) // This is the device token
var token: String = "\(deviceToken)" /// formatted token.
// Following lines will convert token from NSData to String.
let rawtoken = token.stringByReplacingOccurrencesOfString(">", withString: "")
let cleantoken = rawtoken.stringByReplacingOccurrencesOfString("<", withString: "")
var finaltoken = cleantoken.stringByReplacingOccurrencesOfString(" ", withString: "")
// Send device token to server
}
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print(error)
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
let cloudKitNotification = CKNotification(fromRemoteNotificationDictionary: userInfo as! [String:NSObject])
if cloudKitNotification.notificationType == CKNotificationType.Query {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
NSNotificationCenter.defaultCenter().postNotificationName("performReload", object: nil)
})
}
}
func resetBadge () {
let badgeReset = CKModifyBadgeOperation(badgeValue: 0)
badgeReset.modifyBadgeCompletionBlock = { (error) -> Void in
if error == nil {
UIApplication.sharedApplication().applicationIconBadgeNumber = 0
}
}
CKContainer.defaultContainer().addOperation(badgeReset)
}
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) {
resetBadge()
}
func applicationWillEnterForeground(application: UIApplication) {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
NSNotificationCenter.defaultCenter().postNotificationName("performReload", object: nil)
})
}
func applicationDidBecomeActive(application: UIApplication) {
resetBadge()
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
But notifications do not come in even though I have all of the code needed to make notifications every time someone sends a message. Am I missing something? Thanks!
Someone answered me before saying:
You are adding data to the public database but you are creating your subscription on the private database. One of those two needs to be changed to match the other.
So I changed the let privateDatabase = CKContainer.defaultContainer().privateCloudDatabase to let privateDatabase = CKContainer.defaultContainer().publicCloudDatabase
Someone also told me I was missing a function:
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
print(deviceToken) // This is the device token
var token: String = "\(deviceToken)" /// formatted token.
// Following lines will convert token from NSData to String.
let rawtoken = token.stringByReplacingOccurrencesOfString(">", withString: "")
let cleantoken = rawtoken.stringByReplacingOccurrencesOfString("<", withString: "")
var finaltoken = cleantoken.stringByReplacingOccurrencesOfString(" ", withString: "")
// Send device token to server
}
}
}
They said: "What I mean is that to send notification, you register user for push Notification. For the case If the register succeeds, you have to implement the method above. if the registeration fails, you have to implement this :"
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print(error)
}
I added this and it still doesn't work (Notifications still do not come up.) Any other solution? Thanks!

SWIFT: I don't get notifications from my CloudKit app?

Here is my code:
#IBAction func sendSweet(sender: AnyObject) {
//delegate method
let newSweet = CKRecord(recordType: "Extra1")
newSweet["content"] = textField.text
let publicData = CKContainer.defaultContainer().publicCloudDatabase
publicData.saveRecord(newSweet, completionHandler: { (record:CKRecord?, error:NSError?) -> Void in
if error == nil {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.beginUpdates()
self.sweets.insert(newSweet, atIndex: 0)
let indexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Top)
self.tableView.endUpdates()
self.textField.text = ""
self.textField.resignFirstResponder()
})
}})
// Put the CloudKit private database in a constants
let privateDatabase = CKContainer.defaultContainer().publicCloudDatabase
// Create subscription and set three of its properties (an id, a predicate, and options)
let friendsSubscription = CKSubscription(recordType: "Extra1",
predicate: NSPredicate(format: "TRUEPREDICATE"),
subscriptionID: "Extra1",
options: .FiresOnRecordCreation)
// Create a notification and set two of its properties (alertBody and shouldBadge)
let notificationInfo = CKNotificationInfo()
notificationInfo.alertBody = "New message in Lms Chat"
notificationInfo.shouldBadge = false
// Attach the notification to the subscription
friendsSubscription.notificationInfo = notificationInfo
// Save the subscription in the private database
privateDatabase.saveSubscription(friendsSubscription) {recordReturned, error in
// On the main thread, display an error/success message in the textView
if error != nil {
NSOperationQueue.mainQueue().addOperationWithBlock {
self.textField.text = "Cloud error\n\(error!.localizedDescription)"
}
} else {
NSOperationQueue.mainQueue().addOperationWithBlock {
self.textField.text = ""
}
}
}
}
func textFieldShouldEndEditing(textField: UITextField!) -> Bool { //delegate method
return false
}
func textFieldShouldReturn(textField: UITextField!) -> Bool { //delegate method
textField.resignFirstResponder()
return true
}
It's a messaging app so people can message eachother but I also want them to recieve notifications. This is the code for notifications and I also have some code for notifications in App Delegate:
import UIKit
import CloudKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
UIApplication.sharedApplication().registerForRemoteNotifications()
return true
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
let cloudKitNotification = CKNotification(fromRemoteNotificationDictionary: userInfo as! [String:NSObject])
if cloudKitNotification.notificationType == CKNotificationType.Query {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
NSNotificationCenter.defaultCenter().postNotificationName("performReload", object: nil)
})
}
}
func resetBadge () {
let badgeReset = CKModifyBadgeOperation(badgeValue: 0)
badgeReset.modifyBadgeCompletionBlock = { (error) -> Void in
if error == nil {
UIApplication.sharedApplication().applicationIconBadgeNumber = 0
}
}
CKContainer.defaultContainer().addOperation(badgeReset)
}
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) {
resetBadge()
}
func applicationWillEnterForeground(application: UIApplication) {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
NSNotificationCenter.defaultCenter().postNotificationName("performReload", object: nil)
})
}
func applicationDidBecomeActive(application: UIApplication) {
resetBadge()
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
But notifications do not come in even though I have all of the code needed to make notifications every time someone sends a message. Am I missing something? Thanks!
Someone answered me before saying:
You are adding data to the public database but you are creating your subscription on the private database. One of those two needs to be changed to match the other.
So I changed the let privateDatabase = CKContainer.defaultContainer().privateCloudDatabase to let privateDatabase = CKContainer.defaultContainer().publicCloudDatabase
In your app Delegate, you are missing this method :
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
print(deviceToken) // This is the device token
var token: String = "\(deviceToken)" /// formatted token.
let rawtoken = token.stringByReplacingOccurrencesOfString(">", withString: "")
let cleantoken = rawtoken.stringByReplacingOccurrencesOfString("<", withString: "")
var finaltoken = cleantoken.stringByReplacingOccurrencesOfString(" ", withString: "")
// Send device token to server
}
}
}
WHat I mean is that to send notification, you register user for push Notification. For the case If the register succeeds, you have to implement the method above.
if the registeration fails, you have to implement this :
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print(error)
}

SWIFT: Why do I not get notifications from my CloudKit app?

Here is my code:
#IBAction func sendSweet(sender: AnyObject) {
//delegate method
let newSweet = CKRecord(recordType: "Extra1")
newSweet["content"] = textField.text
let publicData = CKContainer.defaultContainer().publicCloudDatabase
publicData.saveRecord(newSweet, completionHandler: { (record:CKRecord?, error:NSError?) -> Void in
if error == nil {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.beginUpdates()
self.sweets.insert(newSweet, atIndex: 0)
let indexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Top)
self.tableView.endUpdates()
self.textField.text = ""
self.textField.resignFirstResponder()
})
}})
// Put the CloudKit private database in a constants
let privateDatabase = CKContainer.defaultContainer().privateCloudDatabase
// Create subscription and set three of its properties (an id, a predicate, and options)
let friendsSubscription = CKSubscription(recordType: "Extra1",
predicate: NSPredicate(format: "TRUEPREDICATE"),
subscriptionID: "Extra1",
options: .FiresOnRecordCreation)
// Create a notification and set two of its properties (alertBody and shouldBadge)
let notificationInfo = CKNotificationInfo()
notificationInfo.alertBody = "New message in Lms Chat"
notificationInfo.shouldBadge = false
// Attach the notification to the subscription
friendsSubscription.notificationInfo = notificationInfo
// Save the subscription in the private database
privateDatabase.saveSubscription(friendsSubscription) {recordReturned, error in
// On the main thread, display an error/success message in the textView
if error != nil {
NSOperationQueue.mainQueue().addOperationWithBlock {
self.textField.text = "Cloud error\n\(error!.localizedDescription)"
}
} else {
NSOperationQueue.mainQueue().addOperationWithBlock {
self.textField.text = ""
}
}
}
}
func textFieldShouldEndEditing(textField: UITextField!) -> Bool { //delegate method
return false
}
func textFieldShouldReturn(textField: UITextField!) -> Bool { //delegate method
textField.resignFirstResponder()
return true
}
It's a messaging app so people can message eachother but I also want them to recieve notifications. This is the code for notifications and I also have some code for notifications in App Delegate:
import UIKit
import CloudKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
UIApplication.sharedApplication().registerForRemoteNotifications()
return true
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
let cloudKitNotification = CKNotification(fromRemoteNotificationDictionary: userInfo as! [String:NSObject])
if cloudKitNotification.notificationType == CKNotificationType.Query {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
NSNotificationCenter.defaultCenter().postNotificationName("performReload", object: nil)
})
}
}
func resetBadge () {
let badgeReset = CKModifyBadgeOperation(badgeValue: 0)
badgeReset.modifyBadgeCompletionBlock = { (error) -> Void in
if error == nil {
UIApplication.sharedApplication().applicationIconBadgeNumber = 0
}
}
CKContainer.defaultContainer().addOperation(badgeReset)
}
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) {
resetBadge()
}
func applicationWillEnterForeground(application: UIApplication) {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
NSNotificationCenter.defaultCenter().postNotificationName("performReload", object: nil)
})
}
func applicationDidBecomeActive(application: UIApplication) {
resetBadge()
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
But notifications do not come in even though I have all of the code needed to make notifications every time someone sends a message. Am I missing something? Thanks!
You are adding data to the public database but you are creating your subscription on the private database. One of those two needs to be changed to match the other.

Resources