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
Related
I'm trying to add a notification service extension to my Xamarin iOS so that I can receive silent notifications. I'm using OneSignal and have followed their instructions and set up everything that I think is required:
App bundle id = com.abc.abcapp
Extension bundle ID = com.abc.abcapp.OneSignalNotificationServiceExtension
Added extension project reference to app
Enabled App Groups in app & extension and set to group.com.abc.abcapp.onesignal (also registered this in Apple developer portal)
Using Automatic Provisioning for both, which seems to have registered everything properly
It builds fine. I have Visual Studio 2022 deploy it to a physical iPhone plugged into my computer. It deploys fine. But notifications don't appear to go to the extension. They just go to the App, which limit the number of silent notifications I can send to a device to a few an hour.
Some possibly useful debugging?
Getting the phone's device log in Visual Studio is really hit or miss but at one point I did see this err:
Library Validation failed: Rejecting '/private/var/containers/Bundle/Application/11D98889-9C2C-4218-A2C8-227C93CBD579/Abc.app/PlugIns/OneSignalNotificationServiceExtension.appex/libOneSignalNotificationServiceExtension.dll.dylib' (Team ID: none, platform: no) for process 'OneSignalNotific(2868)' (Team ID: CJTV38PNRD, platform: no), reason: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.
When I try to build this in MS App Center, it doesn't recognize that I have an extension and doesn't let me associate a second profile or cert. (which I think it's supposed to do?)
According to documentation You can’t modify silent notifications or those that only play a sound or badge the app’s icon.
I have an iOS app that gives support to Mac Catalyst (and runs in Mac OS). In the app, I have a feature where users can send text messages (basically select phone number, enter message content) via MFMessageComposeViewController.
And the code for which is:
if MFMessageComposeViewController.canSendText() {
let composeVC = MFMessageComposeViewController()
composeVC.messageComposeDelegate = self
composeVC.recipients = recipients
composeVC.body = body
self.present(composeVC, animated: true, completion: nil)
}
This piece of code works fine in iOS as well as in Mac OS (till mac os bigSur i.e, 11.6, and I tested this by myself). But in the latest Mac OS i.e., Mac OS Monterey (12.0+) this is not working. Basically the method MFMessageComposeViewController.canSendText() always returns false.
And if I run the code without checking this condition (just for testing purposes) I get the below exception:
[MFMessageComposeViewController] Unable to initialize due to + [MFMessageComposeViewController canSendText] returns NO.
An uncaught exception was raised
Application tried to present a nil modal view controller on target <MyApp.ViewControllerName:0x7fe3d6e67120>
Has anyone faced this issue or does anyone know if this is an OS bug or something's updated in the code in the latest OS?
Thanks!
Having an issue running any app with Xcode 12 on a physical device (device running 14.0.1)
Starting with a new project, the simple Hello World app will not launch on my device while connected to Xcode.
The screen remains black with the white bottom home bar showing. Xcode shows app is running, no warnings, no errors.
struct ContentView: View {
var body: some View {
Text("Hello, world!").foregroundColor(.red)
.padding()
.onAppear {
print("Working....")
}
}
}
It works fine on the simulator, and thus prints out the debug text.
But, on my device, I do not get the debug text - so the launch process has failed.
However, if I stop the project on Xcode and then run the installed app on my device the app runs as expected!!
I changed the font color a couple of times, and it correctly installs the app to the device but fails to run when connected to Xcode, but works when running the app on the phone
I unpaired my device that didn't help.
No sure what to try next...
Thanks for any suggestions
I pass on this solution, which fixed this issue for me:
Go to Xcode -> Preferences -> Locations.
Tap the little arrow under the Derived Data section to open the Xcode directory in the Finder:
Quit Xcode.
In that folder, go to the folder "iOS DeviceSupport":
Delete all the folders within the "iOS DeviceSupport" folder.
Restart Xcode.
If you use wireless debugging you'll probably have to reconnect your device to your computer to re-establish the connection.
Build your project.
Of course, it probably helps to be on the latest Xcode (12.0.1 as of writing) for this.
I am developing a Safari Extension for my local Mac App, I want to use SafariExtension Companion to communicate between them.
However, in my Global.html of the extension, whenever I am trying to get safari.extension.companion, it is always null. Do I setup the extension wrong?
Besides, according to the guide, I can use safari.extension.addEventListener to listen the message from local app, however, when I debug the extension, it prompts me safari.extension.addEventListener is undefined, why is that?
Answer: safari.application.addEventListener is correct, Apple write a wrong document.
I do setup the exact Companion Bundle Identifier in Extension Builder as the identifier which I set in Xcode for the safari companion according to the guide. Is there anything else I miss? Please help!!!
A Safari extension companion is a type of a MacOS X app extension. Those are shipped as part of application bundles. When the app is installed (the bundle is copied to Applications), Safari picks up the extension.
First, you need an Xcode project with a target of type "Cocoa application" ("Command line tool" won't do). Then you need to create a target of type "Safari Extension Companion", and you have a chance to specify the primary app while creating it.
When you build and archive the app, and export the archive, you get an option to add the extension to the app bundle. Then install the app bundle.
Make sure the bundle ID of the extension matches the setting in the Safari Extension Builder. Also, make sure the app and the Safari extension are both signed, and the keys have matching developer IDs. For certificate type on MacOS X, choose "Developer ID" - first when requesting, then when exporting the bundle from the build archive.
EDIT: when the native companion crashes, Safari quietly disables it. If you remove and reinstall the app bundle, and also restart Safari, it loves the companion again.
I am trying to test In-App purchases for MacOS. After entering the test user credentials, the App Store complains: "Current receipt invalid or mismatched ds person id." and the purchase fails.
Some of the many things I tried to get around this problem.
Getting App Store Receipts
UPDATE: Here is Rainer Brockerhoff's comment from the bottom that article. Much more elegant solution.
I don't see the need for all those contortions...
To debug my receipt checking code, I just build, then show the product
app in the Finder. Double-click it once and it will exit(173), then
you'll get the receipt into the bundle.
Now go back to Xcode and debug the checker. The receipt will stay
there until you clean; you can do all that again, or copy the receipt
elsewhere and put it back after build - at one point I had the receipt
reinserted by a build script.
If you want to test out the archived app, show the product in the
Finder, then go up a few folder levels to the "Release" folder, and
there'll you see the app - you can double-click it from there.
The long procedure for getting a receipt:
Archive the app
Within Xcode organizer
Select Distribute...
Export as: Mac Installer Package
Finally install it from the commandline like this
sudo installer -store -pkg (path to package including filename) -target /
Now the app should contain a receipt at this path
/Applications/SampleApp.app/Contents/_MASReceipt/receipt
Verification Email
Apple sends an email when you create a Test User within iTunes Connect.
Email subject:
Please verify the contact email address for your Apple ID
My mail ended up in my spam folder, so I never saw it. Thus never got verified the Test User Account.
Check Status
Within iTunes Connect under Manage Your Apps > SampleApp > Manage In-App Purchases
Here the status should say: Ready to Submit
If it doesn't, then you may need to upload a screenshot.
I will answer my own question. I watched the video called "In-App Purchase for iOS and Mac OS X" on http://developer.apple.com/videos/wwdc/2011/.
The key part was regarding downloading the app receipt at launch. The code to include in the App Delegate was something like:
- (void) applicationWillFinishLaunching:(NSNotification *)notification
{
if(![[NSFileManager defaultManager] fileExistsAtPath:[[[NSBundle mainBundle] appStoreReceiptURL] path]]) {
NSLog(#"to get sandbox receipt, the app must be launched from outside xcode");
//exit(173);
}
}
i myself was very much in trouble in order to integrate In-App Purchase in Mac OS X.
I googled a lot but nothing came with the solution. Finally, apple developers came to rescue. the basically told the reason in wwdc 2012 that there was a bug in MAC OS X (version 10.7.2) due to which one was not able to receive the receipt.
This bug has been solved in the latest version ie MAC OS X (version 10.7.4)
i simply upgraded my OS and was able to get the receipt. So friends who so ever get the problem "Current receipt invalid or mismatched ds person id." simply upgrade the OS to 10.7.4 and the apso write down the following code in your app delegate "applicationDidFinishLaunching" method-
if(![[NSFileManager defaultManager] fileExistsAtPath:[[[NSBundle mainBundle] appStoreReceiptURL] path]]) {
NSLog(#"to get sandbox receipt, the app must be launched from outside xcode");
exit(173);
}
and run ur code for first time outside the XCode. then after receiving the recipt u can debug again from the XCode.
Every time you clean the build u have to run ur app outside the XCode.
Is the receipt for the application that you run was also for the same test user as the one that you try to perform In-App purchase for?
If your debug version runs without a proper receipt (from the same test user) I doubt the In-App purchase will work. Don't use the sample receipt when you want to test In-App purchase, use a real one from the same test user as you're going to buy the In-App product.
I have succeeded performing In-App purchase in my own Mac App (though it's still not in the store) so if you have more questions, fire away.