/ src / qt / macnotificationhandler.mm
macnotificationhandler.mm
 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  }