OS X today widget not updating its snapshot - macos

I'm developing an OS X today widget similar to the builtin Weather widget. It runs fine in Xcode's widget simulator. However, after I export it as an Mac app, the today widget in notification center always show the last snapshot that was created while running in widget simulator previously. The correct behavior should be that, whenever the notification center slides out, the today widget fetches the user's current location and display the local time and weather.
Here is what I have in the widgetPerformUpdateWithCompletionHandler:
func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!) {
locationManager.startUpdatingLocation()
completionHandler(.NewData)
}

Related

How to get snapshot for app in Mac OS 11?

I need to get snapshot for the whole window my app in Mac OS 11, even if the APP is half-outside the screen. I do not know which API I can use. Use C++ or OC first.
CGDirectDisplayID displayID = CGMainDisplayID(); return CGDisplayCreateImage(displayID);
above code is get screen and can not get image outside the screen.
UIView is a new OS13 API.

SwiftUI: Calendar view instead of DatePicker on macOS

I'm wondering whether SwiftUI have calendar view for macOS.
DatePicker requires user to pick date instead of always display the whole calendar.
Some awesome libraries like FSCalendar and ElegantCalendar are for iOS and iPadOS.
I'm not planing to use Mac Catalyst since my application only target macOS.

WidgetKit on Mac with Intent doesn't work

I am trying to make a WidgetKit widget for macOS Big Sur. The widget itself works -- the same code on both the Mac and iOS. The issue is that on the Mac the intent (settings) does not work. When I click "Edit Widget" the options I defined do not appear. When I press "Done," it's replaced with a screen that says "Unable to load."
This seems to happen with a brand new target and just a simple new text parameter. These are the steps I took:
Create a new Mac project
Add a new Widget target
Change the generated Intent, adding a parameter. You also need to add a "Siri Dialog Prompt"
Click "Run"
Click "Info" in the Widget Simulator
Click "Configure Intent"
Am I missing something or is this a bug?
This has been an issue since at least Big Sur beta 5 and Xcode 12b6. I opened a ticket with Apple, but I'm also asking here as it seems that some people have it working and it's entirely possible that I'm missing something!
This seems to be a bug of the Widget Simulator. When I run the same Widget in the Widget panel of Big Sur, I see all configuration options.
The problem turned out to be an older copy of the app on my disk and macOS getting confused and looking in the wrong place.
I'm adding a Widget to an existing app that doesn't currently have one. I have the current, App Store version in /Applications. I've been running the updated version from Xcode or exporting it to my desktop and running it from there. The Widget itself -- as noted in the question -- runs just fine. But it seems that when looking for the Intent used for the configuration, it prefers to look in /Application rather than the Xcode version. As soon as I deleted the original app, the widget and its settings immediately started working.
Thanks to Ely for pointing me to this blog which didn't give the answer but pointing me in the right direction.

macOS Notification Service Extension not being used

I have a notification service extension for my macOS app.
Here is the code for that extension:
import UserNotifications
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: #escaping (UNNotificationContent) -> Void) {
print("Extension received notification!")
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
bestAttemptContent?.title = "Title modified!"
}
override func serviceExtensionTimeWillExpire() {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
}
My payload is also pretty simple:
{"aps": {
"alert":{"title":"Test1", "subtitle":"Test2", "body":"Test3"},
"sound":"default",
"mutable-content":1,
"category":"news"
}
}
However, upon receiving the notification, the title is not modified. I also tried the Attach to process by PID or name menu, I can not attach to this extension, which means it is not being ran.
Many other question were asking about iOS, I tried the solutions for those, but unfortunately they don't work.
Any ideas?
1- An other possibility to not have an app extension run (or seems like it was not run) is that some thing happened and the extension did fail/crash and the OS delivered the Push notification without changes. (try to debug your extension using Xcode.)
2- Try also clean your target and derived data in Xcode.
3- Ensure that your extensions' entitlement has all supported Mac (Mac Catalyst) and not only suported iOS keys (if using for Mac Catalyst).
4- (Mac Catalyst) Try to run the extension on iOS (if it did but not on the Mac it means that some configuration/code crash should not be in your Mac target) Again debugging should help
Check that you don't have multiple versions of the app installed.
After I deleted the release version of the app (same bundle ID), it all started to work.
pluginkit and this SO thread pushed me into the right direction.
I had the same issue with Mac Catalyst (the iOS Notification Services extension is working fine but Not for MAC OS). (Xcode 11.1)
For Mac OS X (Mac Catalyst) (if you already have the "App Sandbox" capability please skip to step 5)
Select your extension's target.
then on top select the tab "Signing and Capabilities"
than click on Capability +
Add the "App Sandbox" capability
Ensure that Incoming Connection (Server) is checked (enabled).
Please see attached image.
Xcode Notification Services Extension target setting

Location background service not working in Swift2

I have some odd behaviour in my app.
In my app delegate file I ask the user for permission to use their location while they use the app. This works fine and I can get their current location. After I get their initial location I stop updating location. Great. There is a button users can tap to start updating locations.
If the app is in the foreground I can see that locations are being added to my dictionary every second (I will change this to distanceFilter 10 later). If the user puts the app in to the background location services stop and I don't see the blue bar at the top of the screen.
I have:
Background modes for location updates enabled
NSLocationWhenInUseUsageDescription set (I am able to successfully ask the user for permission)
Started the location updates with startUpdatingLocation()
Tried setting the app to track location always (same result)
Deleted the app from my phone and reinstalled
In the previous version of my app (before Swift 2) this was working perfectly. I could see location being tracked even when the app was in the background.
I am testing on my iPhone not the simulator.
If anyone else has the same issue, I had updated my iPhone to iOS9 so it was required for me to add
locationManager.allowsBackgroundLocationUpdate = true
to my location manager.
The following worked for me, please note allowsBackgroundLocationUpdates is plural.
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.allowsBackgroundLocationUpdates = true

Resources