Images in user notifications - objective-c

How do I create user notifications with cocoa that contain Images. Like Airmail or Alfred does?
For instance Airmail includes a contact image in the mail notification if the one is present:
I haven't found any documentation how to add this via code. Do I have to use a custom notification center?
I have found the CNUserNotification project but when I use it the notifications won't show up in the notification sidebar.

If you create user notifications using NSUserNotification, on Mavericks +, setting contentImage does the trick. Strangely enough it's not documented, but it's exposed and in the release notes. OS X 10.8 or less would necessitate a custom solution.
NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.contentImage = [NSImage imageNamed:#"imageNamed"];

Related

Every Push Notification Banner is shown twice on iOS9 [duplicate]

This question already has answers here:
iOS Push Notification Banner shown twice for a single Push
(8 answers)
Closed 3 years ago.
Since a few hours we have a strange issue in our iOS app: every push notification received on the home screen of iOS will trigger/show the same notification banner twice with a 2 sec delay between them.
It only happens on devices with iOS 9.x. On iOS 8.x devices everything is still working as expected.
If I set a break point in -[AppDelegate application:didReceiveRemoteNotification:fetchCompletionHandler:] it is only called once for each push notification.
Also we did no change in the backend recently (at least a weak) and it also happens for client which are already released and we are 100% certain we did not see the issue before.
We did however change the capability in Xcode of the current development app and had to generate new provisioning profiles as the old ones where tagged as "Invalid".
So for us it looks like an issue on Apple sides. Any suggestions what more to try/check or what to do?
It seems like I had exactly the same issue as this dude had: I called [registerUserNotificationSettings:] twice.
Be aware that it might not be as obvious as you think to see if you called the method once or twice:
I called it once on purpose in specific UIViewController. Unfortunately I also called it each time in didFinishLauchingWithOptions:. Don't let yourself be fooled because you see the dialog only once.
If you want to be sure add a logging output in -[AppDelegate application:didRegisterUserNotificationSettings:]. In my case the callback was called twice after I hit OK on the permission dialog.
Since I remove the misplace call in didFinishLauchingWithOptions: I did not see anymore double notifications.
I submitted a bug report to Apple (Ticket# 23569779) and the issue appears to have been corrected in iOS 9.2.1 beta (Build: 13D11)
I was experiencing the same issue on iOS9.1 (Build: 13B143) and iOS9.2 (Build: 13c75) for both local and remote notifications across multiple apps.
The simplest way for me to recreate the issue is to schedule a local notification within my app delegate when the app is backgrounded.
- (void)applicationDidEnterBackground:(UIApplication *)application {
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.repeatInterval = NSDayCalendarUnit;
[notification setAlertBody:#"My test."];
[notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:1]];
[notification setTimeZone:[NSTimeZone defaultTimeZone]];
[application setScheduledLocalNotifications:[NSArray arrayWithObject:notification]];
}
This will result in the notification banner appearing twice:
Duplicate banner images

background location iOS 8

Hello Devs: I am working on an app where I would like to fetch users location in background and send push notifications to him as soon as the user arrives at that particular location. Here is what I have done so far with my locatioManager in my app delegate
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
if (IS_OS_8_OR_LATER) [locationManager requestAlwaysAuthorization];
[locationManager startUpdatingLocation];
I have set up my info.plist to always request location. I also get the message that my app will be using location in the background when I install the app on my device. However when I close the app and arrive at the specific location I don't get any push notifications or alerts until I launch the app. I turned on Background mode --> location updates under capabilities section and then everything works absolutely fine. I receive notification seamlessly without launching the app. This is all good but when I close the app I see a blue bar on my status bar saying that my app is tracking the location in background. How do I hide that blue bar on the top? I am pretty sure this is going to scare away my users and they will remove my app instantly. To make long story short how do I accomplish this? I know this question has been asked and answered several times in past but all those answers are 2-3 years old and don't seem to work with new iOS 8. I need to get the user location in background in order for my app to work or else its useless. I will really appreciate any help or suggestions to this.
Thanks!
What you want to do is called (background) Geofencing. Your app doesn't need to calculate it by itself since CoreLocation already offers this feature.
Please have a look at this answer from Daniel.
The Geofencing feature will wake up your app when the users gets into the target zone, and will not display the blue bar.

How to add the iOS "Open In..." feature to an app

I would like to know how to present the "Open In..." Action Sheet (iPhone) / Popover (iPad) from my app, preferably an IBAction
I would hope that it'd be similar to declaring a file type then creating the view and opening the app selected by the user, but I know it is more complicated then that.
I realize that a similar question has been asked on StackOverflow, but I cannot make sense of the answer that was accepted: How to use "open in..." feature to iOS app?, and I have found some Apple Documentation on Document Interaction Programming. But, I can't really make sense of these.
Create a UIDocumentInteractionController by using the interactionControllerWithURL: class method (pass the URL of the file you want to open in another app).
Then call either presentOpenInMenuFromRect:inView:animated: or presentOpenInMenuFromBarButtonItem:animated:. The controller takes care of presenting the popover with available apps for that file type and opening the selected app.
If you want to know when the menu was dismissed and which app was selected, you need to implement the UIDocumentInteractionControllerDelegate protocol.
omz makes some good points on how to do that in his answer, however this procedure is much easier with the introduction of new APIs in iOS 6. Here's a simple and efficient way to show the UIActionSheet Open-In-Menu in iOS 6 and up:
NSArray *dataToShare = #[contentData]; //Or whatever data you want to share - does not need to be an NSArray
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:dataToShare applicationActivities:nil];
[self presentViewController:activityViewController animated:YES completion:nil];
Also, if your app is compatible with versions of iOS lower than 6.0 you may want to check if the Share Service exists:
if ([UIActivityViewController class])
Once you present the sheet, iOS will automatically handle the rest for you. It will display a beautiful uiactionsheet with icons showing each app or service the user can open / share your data with:
Note that depending on the contents of the data, iOS will show different services in the Share Sheet
EDIT: The method above shares the file content, but not the file itself. Refer to omz's answer for more on that.
I've personally never had to do this, but your answer can most certainly be found in this Apple Documentation: http://developer.apple.com/library/ios/#documentation/FileManagement/Conceptual/DocumentInteraction_TopicsForIOS/Articles/PreviewingandOpeningItems.html#//apple_ref/doc/uid/TP40010410-SW1.

Launch Mac application when iTunes starts without background process (like last.fm)

I would like to start my OSX application when iTunes loads, without having a background process to monitor when iTunes launches. The last.fm client seems to do this; I can find no background process when iTunes is closed, but as soon as it starts the last.fm app opens right along with it. Perhaps it is using some kind of iTunes plugin that can start another process?
It seems to be fairly trivial to do this with a background process, but I'd like to do it without one so my program isn't using system resources.
One option with a background process is to use NSWorkspace's notification center, such as:
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:#selector(appDidLaunch:) name:NSWorkspaceDidLaunchApplicationNotification object:nil]
However, this obviously requires a background process. Another option I found was to use ProcessNotif, something like this:
ProcessNotif *x = [[ProcessNotif new] autorelease];
[x setProcessName: #"iTunes"];
[x setTarget: self];
[x setAction: #selector(doStuff)];
[x start];
This is probably even less ideal than the NSWorkspace method, and it too requires a background process.
So, is there some way to launch from iTunes when it launches, no background process required?
Thanks!
The last.fm client achieves that by installing an iTunes plugin. This plugin gets loaded when iTunes starts and then has a chance to start the last.fm app. To create a plugin you need the iTunes PlugIn SDK available here.

How do I draw a badge on my Dock icon using Cocoa?

How do I add a badge to the Dock icon for my app using Cocoa? Is there any roughly "standardized" way to do this?
(I'm referring to the kind of badges that show up in Mail, iChat etc. to indicate the number of unread messages and the like.)
Cocoa Touch does provide one such method, but I haven't been able to find any equivalent for a regular Cocoa application.
Use
[[[NSApplication sharedApplication] dockTile] setBadgeLabel:#"2234"];
This method, and the NSDockTile class, has been available since Leopard.
It should be noted that NSDockTile is only available on Leopard. If you need to target Tiger you'll need to use -setApplicationIconImage: on your NSApplication object and draw your badge by hand.
Also, it's not in the documentation outside of the release notes that I could find but you get your application's dock tile by sending the dockTile message to your NSApplication object.
NSDockTile *tile = [[NSApplication sharedApplication] dockTile];
[tile setBadgeLabel:#"Lots"];
A quick google search turned up the NSDockTile class. Seems pretty self-explanatory once you take a gander at the documentation.