macnotificationhandler.mm raw
1 // Copyright (c) 2011-present The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include "macnotificationhandler.h"
6
7 #undef slots
8 #import <objc/runtime.h>
9 #include <Cocoa/Cocoa.h>
10
11 // Add an obj-c category (extension) to return the expected bundle identifier
12 @implementation NSBundle(returnCorrectIdentifier)
13 - (NSString *)__bundleIdentifier
14 {
15 if (self == [NSBundle mainBundle]) {
16 return @"org.bitcoinfoundation.Bitcoin-Qt";
17 } else {
18 return [self __bundleIdentifier];
19 }
20 }
21 @end
22
23 void MacNotificationHandler::showNotification(const QString &title, const QString &text)
24 {
25 // check if users OS has support for NSUserNotification
26 if(this->hasUserNotificationCenterSupport()) {
27 NSUserNotification* userNotification = [[NSUserNotification alloc] init];
28 userNotification.title = title.toNSString();
29 userNotification.informativeText = text.toNSString();
30 [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification: userNotification];
31 [userNotification release];
32 }
33 }
34
35 bool MacNotificationHandler::hasUserNotificationCenterSupport(void)
36 {
37 Class possibleClass = NSClassFromString(@"NSUserNotificationCenter");
38
39 // check if users OS has support for NSUserNotification
40 if(possibleClass!=nil) {
41 return true;
42 }
43 return false;
44 }
45
46
47 MacNotificationHandler *MacNotificationHandler::instance()
48 {
49 static MacNotificationHandler *s_instance = nullptr;
50 if (!s_instance) {
51 s_instance = new MacNotificationHandler();
52
53 Class aPossibleClass = objc_getClass("NSBundle");
54 if (aPossibleClass) {
55 // change NSBundle -bundleIdentifier method to return a correct bundle identifier
56 // a bundle identifier is required to use OSXs User Notification Center
57 method_exchangeImplementations(class_getInstanceMethod(aPossibleClass, @selector(bundleIdentifier)),
58 class_getInstanceMethod(aPossibleClass, @selector(__bundleIdentifier)));
59 }
60 }
61 return s_instance;
62 }
63