[SOLVED] Create class with Objective-C header



  • Hi everyone!

    I need help with integration of Objective-C/C++ code to my QtQuick Plugin. The problem is that I want to use “Notification Center” from Mac OS X 10.9 and later to show user some update information from my app (new posts from blogs). The code how to use this notification center I've implemented but it’s works without pop dialog. To show dialog I need to implement one delegate method to my class. The problem is that this delegate method has a Objective-C types and I can’t implement it to my header file of class where I need to use it. I’ve tried to create class as Objective-C implementation and call it from another class (.mm) but I receive error message because Qt can’t use Objective-C code in header.

    here is my header file:
    @
    #ifndef QFNOTIFICATIONMANAGER_H
    #define QFNOTIFICATIONMANAGER_H

    #include <QtCore>
    #include <Foundation/Foundation.h> //This is a problem

    class QfNotificationManager : public QObject
    {
    Q_OBJECT
    public:
    explicit QfNotificationManager(QObject *parent = 0);

        static QfNotificationManager* defaultManager(QObject *parent = 0);
    
        void postNotification(QString title, QString message);
    
        BOOL shouldPresentNotification(NSUserNotificationCenter *center, NSUserNotification *notification);        //I can't use Objective-C/C++ code here because I need to include/import the Objective-C header
    signals:
    
    public slots:
    

    };

    #endif // QFNOTIFICATIONMANAGER_H
    @

    and implementation of class:
    @
    #include "qfnotificationmanager.h"
    #include <Foundation/Foundation.h>

    static QfNotificationManager* g_notificationManager = NULL;

    QfNotificationManager::QfNotificationManager(QObject *parent) :
    QObject(parent)
    {
    id<NSUserNotificationCenterDelegate> self = (id<NSUserNotificationCenterDelegate>)this;
    [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
    }

    QfNotificationManager* QfNotificationManager::defaultManager(QObject *parent)
    {
    if(!g_notificationManager)
    {
    g_notificationManager = new QfNotificationManager(parent);
    }

    return g_notificationManager;
    

    }

    void QfNotificationManager::postNotification(QString title, QString message)
    {
    NSString* objcTitle = title.toNSString();
    NSString* objcMessage = message.toNSString();

    NSUserNotification* notification = [[NSUserNotification alloc] init];
    notification.title = objcTitle;
    notification.informativeText = objcMessage;
    
    [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification: notification];
    

    }

    BOOL QfNotificationManager::shouldPresentNotification(NSUserNotificationCenter *center, NSUserNotification *notification)
    {
    return YES;
    }
    @

    Could you help me to solve this problem? Thanks for the any help!

    P.S. I've found "this post":http://stackoverflow.com/questions/22142592/mac-os-usernotificationcenter-in-qt where user solve this problem but I don't understand how he solve problems with Objective-C headers in his Qt/C++ class header.


  • Lifetime Qt Champion

    Hi,

    Depending on your use case, you could use QSystemTrayIcon. It provides the showMessage method that does exactly what you want.

    However if you still want to go the custom route it can also be done.



  • Thanks for the reply!

    I'll check QSystemTrayIcon. But I want learn how to use Objective-C with header. Could you send me docs where I can learn more about this? Thanks!



  • I don't know whether books exist on this topic, but I would google "mix objectiv_c and C++"



  • Ok!

    I've found the solution.
    The first you need to create the Objective-C class which will implement all logic to methods:
    header file (notificationmanager.h) of ObjC:
    @
    #ifndef NOTIFICATIONMANAGER_H
    #define NOTIFICATIONMANAGER_H

    #ifdef __cplusplus
    extern "C" {
    #endif

    #import <Foundation/Foundation.h>

    @interface NotificationManager : NSObject

    • (instancetype)init;
    • (void)postNotificationWithTitle:(NSString*)title message:(NSString*)msg;
    • (BOOL)isObjectCreated;
    • (NotificationManager*)defaultManager;
    • (void)clearAllDatas;

    @end

    #ifdef __cplusplus
    }
    #endif

    #endif // NOTIFICATIONMANAGER_H
    @

    the implementation (notificationmanager.mm) of ObjC:
    @
    #include "notificationmanager.h"
    #include <QtCore>

    @interface NotificationManager () <NSUserNotificationCenterDelegate>
    @end

    @implementation NotificationManager

    static NotificationManager* g_notificationManager = nil;

    • (instancetype)init
      {
      self = [super init];

      if(self)
      {
      [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
      }

      return self;
      }

    • (void)postNotificationWithTitle:(NSString*)title message:(NSString*)msg
      {
      NSUserNotification* notification = [[NSUserNotification alloc] init];
      notification.title = title;
      notification.informativeText = msg;

      [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification: notification];
      }

    • (BOOL)isObjectCreated
      {
      return (g_notificationManager != nil);
      }

    • (NotificationManager*)defaultManager
      {
      if(!g_notificationManager)
      {
      g_notificationManager = [[NotificationManager alloc] init];
      }

      return g_notificationManager;
      }

    • (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification
      {
      Q_UNUSED(center);
      Q_UNUSED(notification);

      return YES;
      }

    • (void)clearAllDatas
      {
      [g_notificationManager release];
      g_notificationManager = nil;
      }

    • (void)dealloc
      {
      [super dealloc];

      qDebug()<<"Object released!!!!";
      }
      @end
      @

    Second you need create C++ class with .mm file implementation (qfnotificationmanager.h):
    @
    #ifndef QFNOTIFICATIONMANAGER_H
    #define QFNOTIFICATIONMANAGER_H

    #include <QtCore>

    #ifdef __cplusplus
    extern "C" {
    #endif

    class QfNotificationManager : public QObject
    {
    // Q_OBJECT
    public:
    explicit QfNotificationManager(QObject *parent = 0);
    ~QfNotificationManager();

        static QfNotificationManager* defaultManager(QObject *parent = 0);
    
        void postNotification(QString title, QString message);
    signals:
    
    public slots:
    

    };

    #ifdef __cplusplus
    }
    #endif

    #endif // QFNOTIFICATIONMANAGER_H
    @

    and implementation (qfnotificationmanager.mm):
    @
    #include "qfnotificationmanager.h"
    #include <Foundation/Foundation.h>
    #include "notificationmanager.h"

    static QfNotificationManager* g_notificationManager = NULL;

    QfNotificationManager::QfNotificationManager(QObject *parent) :
    QObject(parent)
    {
    [NotificationManager defaultManager];
    }

    QfNotificationManager::~QfNotificationManager()
    {
    [[NotificationManager defaultManager] clearAllDatas];
    }

    QfNotificationManager* QfNotificationManager::defaultManager(QObject *parent)
    {
    if(!g_notificationManager)
    {
    g_notificationManager = new QfNotificationManager(parent);
    }

    return g_notificationManager;
    

    }

    void QfNotificationManager::postNotification(QString title, QString message)
    {
    NSString* objcTitle = title.toNSString();
    NSString* objcMessage = message.toNSString();

    [[NotificationManager defaultManager] postNotificationWithTitle: objcTitle message: objcMessage];
    

    }
    @

    How to use (from .cpp file you need to call this):
    @
    QfNotificationManager::defaultManager(this);
    QfNotificationManager::defaultManager()->postNotification("Qt Forum Reader", "This is test notification message");
    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.