Badge is not displaying OSX cocoa swift - swift

I am trying to display badge count in MacOS Ventura for my application, Here is my code
NSApplication.shared.dockTile.showsApplicationBadge = true
NSApplication.shared.dockTile.badgeLabel = "2"
NSApplication.shared.dockTile.display()
I also requested for notification allow
//create the notificationCenter
let center = UNUserNotificationCenter.current()
center.delegate = self
// set the type as sound or badge
center.requestAuthorization(options: [.sound,.alert,.badge]) { (granted, error) in
if granted {
print("Notification Enable Successfully")
}else{
print(error.debugDescription) // prints "Notifications are not allowed for this application"
}
}
but it is always going into error part, I don't know what's issue there.
I also checked in Notification settings in System preference, It's showing only alert there. There is no badge setting there.
How to add badge setting in notification setting? Here is the screenshot
Any help would be appreciated.

Related

Is it possible to set default alert style for macOS UNNotification?

My application posts local macOS notifications. It's important that these are not banner style but alert style instead.
So far I have achieved that by setting NSUserNotificationAlertStyle=alert in the Info.plist.
When a first NSUserNotification is sent to the user, he is asked to approve the app's alerts.
Once approved, the App gets Alert style set to Alerts in the macOS Preferences.
However, the NSUserNotification API s deprecated since macOS 11.
In the code below I've tried to use the newer UNNotification API, the Alert style is always set to banner
no matter the NSUserNotificationAlertStyle property value.
Is there any way to work around that? Since users can change the alert style anyway,
I am not sure why the apps cannot decide on the default style themselves.
import UserNotifications
import SwiftUI
#main
struct UNNotificationIssuesApp: App {
init() {
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
if granted {
notificationCenter.getNotificationSettings { settings in
print("Granted app notification permissions: \(settings)")
}
} else {
print("All the app's notification permissions were revoked")
}
if let err = error {
print("An error occurred while granting app notification permissions:", err.localizedDescription)
}
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}

Open Health Kit Permission Settings for the app that uses Health Kit

I am using Health Kit to display steps information for the user.
let healthKitTypes: Set = [ HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!]
self.healthStore.requestAuthorization(toShare: healthKitTypes, read: healthKitTypes) { (bool, error) in
if (bool) {
// Auth granted
} else {
// Navigate user to HealthKit app permissions
}
}
This code shows a popup to the user with the asked permissions. What I want to do in the // Navigate user to HealthKit app permissions is to open the Health Kit app permission settings directly for my app if the user did not approve the permissions on the popup.
I know that settings of the app can be opened by using something like this:
let settingsAction = UIAlertAction(title: "Settings", style: .default) { (_) -> Void in
guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
return
}
if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
print("Settings opened: \(success)") // Prints true
})
}
}
... I want to do similar, just in this case open the Health Kit Setting permission screen so that users can enable the requested permissions directly in settings - if they decline them in the app popup.
Thanks

swift notification not triggering

I'm new to notifications in swift and have setup the following in my AppDelegate.swift file. It runs and I get print output that the notifications are setup and do not error. I also get the permission ask for notifications, which I click yes to. I believe the interval notification I have should trigger in 20 seconds after launch. It does not trigger, this doesn't change if I'm in the app or have minimized the app. Note I am running in Simulator mode from XCODE. Why is my notification not triggering?
func setupNotifications(){
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
if granted {
print("Yay!")
} else {
print("D'oh")
}
}
notificationCenter.removeAllPendingNotificationRequests()
print("setting up notifications")
let content = UNMutableNotificationContent()
content.title = "Answer your daily questions"
content.body = "Answer your daily questions please"
content.categoryIdentifier = "alarm"
content.userInfo = ["customData": "fizzbuzz"]
content.sound = UNNotificationSound.default
//let trigger = UNTimeIntervalNotificationTrigger(timeInterval: (1*60), repeats: true)
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 20, repeats: false)
// Create the request
let request = UNNotificationRequest(identifier: "daily-notifier",
content: content, trigger: trigger)
// Schedule the request with the system.
notificationCenter.add(request) { (error) in
if error != nil {
print("there were errors to address")
// Handle any errors.
}
}
print("done setting up notifications")
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let path = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true)
print("\(path)")
// Override point for customization after application launch.
setupNotifications()
return true
}
First note that you should probably wait to receive permission before adding a request for a local notification as per Apple's documentation of the requestAuthorization(options:completionHandler:)
Note: Always call this method before scheduling any local notifications and before registering with the Apple Push Notification service.
Also make sure that you've added Push Notifications as a capability for your app as this will be needed should you submit it.
After I ran the above code I did not receive a notification while the app was still active but I did receive one while the app was in the background. I believe that if a user receives a notification for an app that is in the active state it is given silently; i.e., without the banner and sound (at least this is what I have experienced with my notifications, although there may be more to it).

On iOS 13 the biometric authentication alert does not show on older phones

On older iPhones such as the 6, 6s etc. The biometric authentication dialogue/alert is hidden. If you press the home button on the iPhone to authenticate via a fingerprint it still works, but the dialogue/alert is hidden, which is a source of confusion for users.
Various sources (1) (2) have reported this as an iOS 13 bug.
This worked correctly on iOS 12, the issue started on iOS 13.
My biometric auth code looks like this and is fired in a view controller's viewDidAppear method:
let localAuthContext = LAContext()
var error: NSError?
if localAuthContext.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error) {
localAuthContext.evaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, localizedReason: "SIGNIN.TITLE.Login".localized) { [weak self] (success, error) in
if success {
// success
} else {
// failure
}
}
} else {
// can't evaluate policy
}
So, do I need to change something in my code for iOS 13, or is this an Apple issue?
It seems to be issue in processing.
I've fixed this issue by showing it from main queue so it will surely show maybe after delay but it will not remain hidden.
DispatchQueue.main.async {
if localAuthContext.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error) {
localAuthContext.evaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, localizedReason: "SIGNIN.TITLE.Login".localized) { [weak self] (success, error) in
if success {
// success
} else {
// failure
}
}
} else {
// can't evaluate policy
}
}
It just happens from iOS 13 and above. The solution is trying to call evaluate function twice like this:
let systemVersion = UIDevice.current.systemVersion
// Trick here: Try to do an pre-evaluate
if systemVersion.compare("13.0", options: .numeric) != .orderedAscending {
context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "Authenticate to open the app", reply: { (_, _) in
//Ignore callback here
})
}
context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "Authenticate to open the app", reply: { (success, error) in
// Handle callback here
})
Tested and work well for all iOS 13.x.x versions so far.
This seems to be an Apple issue on older iOS 13 versions. I am unable to reproduce this issue from iOS 13.1.2 onwards.

NSAlert beginSheetModalForWindow Not Showing Alert

I have a settings view controller that is presented as a sheet. It has a button that saves the settings if they are valid. If the settings are valid the view controller is dismissed. If they are not valid the user gets an alert saying the settings are not valid. My code is as follows:
var settingsValidated = false
#IBAction func dismissSettings(sender: AnyObject) {
if settingsValidated == true {
dismissViewController(self)
} else {
let alert = NSAlert()
alert.messageText = "Warning"
alert.addButtonWithTitle("OK")
alert.informativeText = "Your settings did not validate!"
let window = NSApplication.sharedApplication().mainWindow
let res = alert.beginSheetModalForWindow(window!, completionHandler: nil)
}
}
If settingsValidated is set to true everything works as expected but when I set settingsValidated to false nothing happens. The alert never shows. What am I missing? I do not receive any errors in Xcode.
Please note this question is about OS X NOT iOS.
It's not showing up because you aren't doing anything with the res object! — so remove it:
alert.beginSheetModalForWindow(window!, completionHandler: nil)
↳ NSAlert Class Reference