Recent

Author Topic: Anyone have any sample code to use the Mac notification center such as Banner?  (Read 18149 times)

vonskie

  • Full Member
  • ***
  • Posts: 139
Okay this is far as I can get I am stuck anyone want to add to this or fix it.. Please.

Code: [Select]
{ Parsed from Foundation.framework (MacOSX10.8) NSUserNotification.h }
{ Created on Fri Mar 21 17:48:09 2014 }
unit UserNotification;

{$mode objfpc}{$H+}
{$modeswitch objectivec1}
 
interface
 
{$linkframework AppKit}
 
uses
  Classes, SysUtils, CocoaAll, MacOSAll, CarbonProc;

 
{$ifdef TYPES}

type
  NSUserNotificationPtr = ^NSUserNotification;
  NSUserNotificationCenterPtr = ^NSUserNotificationCenter;
  NSUserNotificationCenterDelegateProtocolPtr = ^NSUserNotificationCenterDelegateProtocol;
{$endif}

{$ifdef TYPES}
type
  NSUserNotificationActivationType = NSInteger;
  NSUserNotificationActivationTypePtr = ^NSUserNotificationActivationType;

const
  NSUserNotificationActivationTypeNone = 0;
  NSUserNotificationActivationTypeContentsClicked = 1;
  NSUserNotificationActivationTypeActionButtonClicked = 2;
{$endif}

{$ifdef CLASSES}


type

{NSUserNotification}

  NSUserNotification = objcclass external (NSObject, NSCopyingProtocol)
  private
    _internal: id;
  public
    procedure setTitle(newValue: NSString); message 'setTitle:';
    function title: NSString; message 'title';
    procedure setSubtitle(newValue: NSString); message 'setSubtitle:';
    function subtitle: NSString; message 'subtitle';
    procedure setInformativeText(newValue: NSString); message 'setInformativeText:';
    function informativeText: NSString; message 'informativeText';
    procedure setActionButtonTitle(newValue: NSString); message 'setActionButtonTitle:';
    function actionButtonTitle: NSString; message 'actionButtonTitle';
    procedure setUserInfo(newValue: NSDictionary); message 'setUserInfo:';
    function userInfo: NSDictionary; message 'userInfo';
    procedure setDeliveryDate(newValue: NSDate); message 'setDeliveryDate:';
    function deliveryDate: NSDate; message 'deliveryDate';
    procedure setDeliveryTimeZone(newValue: NSTimeZone); message 'setDeliveryTimeZone:';
    function deliveryTimeZone: NSTimeZone; message 'deliveryTimeZone';
    procedure setDeliveryRepeatInterval(newValue: NSDateComponents); message 'setDeliveryRepeatInterval:';
    function deliveryRepeatInterval: NSDateComponents; message 'deliveryRepeatInterval';
    function actualDeliveryDate: NSDate; message 'actualDeliveryDate';
    function isPresented: boolean; message 'isPresented';
    function isRemote: boolean; message 'isRemote';
    procedure setSoundName(newValue: NSString); message 'setSoundName:';
    function soundName: NSString; message 'soundName';
    procedure setHasActionButton(newValue: boolean); message 'setHasActionButton:';
    function hasActionButton: boolean; message 'hasActionButton';
    function activationType: NSUserNotificationActivationType; message 'activationType';
    procedure setOtherButtonTitle(newValue: NSString); message 'setOtherButtonTitle:';
    function otherButtonTitle: NSString; message 'otherButtonTitle';

    { Adopted protocols }
    function copyWithZone (zone: NSZonePtr): id; message 'copyWithZone:';
  end;
{$endif}

{$ifdef EXTERNAL_SYMBOLS}
var
  NSUserNotificationDefaultSoundName: NSString { available in 10_8, NA }; cvar; external;
{$endif}

{$ifdef CLASSES}

type
  NSUserNotificationCenter = objcclass external (NSObject)
  private
    _internal: id;
  public
    class function defaultUserNotificationCenter: NSUserNotificationCenter; message 'defaultUserNotificationCenter';
    procedure setDelegate(newValue: NSUserNotificationCenterDelegateProtocol); message 'setDelegate:';
    function delegate: NSUserNotificationCenterDelegateProtocol; message 'delegate';
    procedure setScheduledNotifications(newValue: NSArray); message 'setScheduledNotifications:';
    function scheduledNotifications: NSArray; message 'scheduledNotifications';
    procedure scheduleNotification (notification: NSUserNotification); message 'scheduleNotification:';
    procedure removeScheduledNotification (notification: NSUserNotification); message 'removeScheduledNotification:';
    function deliveredNotifications: NSArray; message 'deliveredNotifications';
    procedure deliverNotification (notification: NSUserNotification); message 'deliverNotification:';
    procedure removeDeliveredNotification (notification: NSUserNotification); message 'removeDeliveredNotification:';
    procedure removeAllDeliveredNotifications; message 'removeAllDeliveredNotifications';
  end;
{$endif}

{$ifdef PROTOCOLS}

type
  NSUserNotificationCenterDelegateProtocol = objcprotocol external name 'NSUserNotificationCenterDelegate' (NSObjectProtocol)
  optional
    procedure userNotificationCenter_didDeliverNotification (center: NSUserNotificationCenter; notification: NSUserNotification); message 'userNotificationCenter:didDeliverNotification:';
    procedure userNotificationCenter_didActivateNotification (center: NSUserNotificationCenter; notification: NSUserNotification); message 'userNotificationCenter:didActivateNotification:';
    function userNotificationCenter_shouldPresentNotification (center: NSUserNotificationCenter; notification: NSUserNotification): boolean; message 'userNotificationCenter:shouldPresentNotification:';
  end;
{$endif}



« Last Edit: March 22, 2014, 03:28:56 am by skalogryz »

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2345
    • havefunsoft.com
Okay this is far as I can get I am stuck anyone want to add to this or fix it.. Please.
you can go further. ... but, what is the exact problem?
btw, try to change {$linkframework AppKit} to {$linkframework Foundation}


My exposure to free pascal is about 30 days so there is much I do not understand.
Lol, you pushed an application live, it's too late to make excuses!
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2345
    • havefunsoft.com
any luck?
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

vonskie

  • Full Member
  • ***
  • Posts: 139

exodusd

  • New member
  • *
  • Posts: 9
Hi,

since I was also looking for a way to use the Mac OS X user notifications, I took the code you posted and tried to get it running. I've removed the ifdefs, because if I understand that correctly, they are for inclusion in the CocoaAll unit (they are defined there when other files are included). I've also commented out the "copyWithZone" stuff, because I got a "duplicate symbol" error. Unfortunately I have no clue about the Cocoa stuff or the details of how it is integrated in fpc/lazarus, so I just commented it out.  ;)

Anyway, I've added two procedures called DeliverUserNotification that you can use to show a user notification with title, subtitle, message and (optionally) sound. The procedure without the sound parameter will play the default sound - if you want a notification without sound, then just call the other one and pass an empty string for the sound parameter.

Cheers,
  Robert


Code: [Select]
unit UserNotification;

{$mode objfpc}{$H+}
{$modeswitch objectivec1}

interface

{$linkframework Foundation}

uses
  Classes, SysUtils, CocoaAll, CarbonProc;

const
  NSUserNotificationActivationTypeNone = 0;
  NSUserNotificationActivationTypeContentsClicked = 1;
  NSUserNotificationActivationTypeActionButtonClicked = 2;

type
  NSUserNotificationPtr = ^NSUserNotification;
  NSUserNotificationCenterPtr = ^NSUserNotificationCenter;
  NSUserNotificationCenterDelegateProtocolPtr = ^NSUserNotificationCenterDelegateProtocol;

  NSUserNotificationActivationType = NSInteger;
  NSUserNotificationActivationTypePtr = ^NSUserNotificationActivationType;

  //NSUserNotification = objcclass external (NSObject, NSCopyingProtocol)
  NSUserNotification = objcclass external (NSObject)
  private
    _internal: id;
  public
    procedure setTitle(newValue: NSString); message 'setTitle:';
    function title: NSString; message 'title';
    procedure setSubtitle(newValue: NSString); message 'setSubtitle:';
    function subtitle: NSString; message 'subtitle';
    procedure setInformativeText(newValue: NSString); message 'setInformativeText:';
    function informativeText: NSString; message 'informativeText';
    procedure setActionButtonTitle(newValue: NSString); message 'setActionButtonTitle:';
    function actionButtonTitle: NSString; message 'actionButtonTitle';
    procedure setUserInfo(newValue: NSDictionary); message 'setUserInfo:';
    function userInfo: NSDictionary; message 'userInfo';
    procedure setDeliveryDate(newValue: NSDate); message 'setDeliveryDate:';
    function deliveryDate: NSDate; message 'deliveryDate';
    procedure setDeliveryTimeZone(newValue: NSTimeZone); message 'setDeliveryTimeZone:';
    function deliveryTimeZone: NSTimeZone; message 'deliveryTimeZone';
    procedure setDeliveryRepeatInterval(newValue: NSDateComponents); message 'setDeliveryRepeatInterval:';
    function deliveryRepeatInterval: NSDateComponents; message 'deliveryRepeatInterval';
    function actualDeliveryDate: NSDate; message 'actualDeliveryDate';
    function isPresented: boolean; message 'isPresented';
    function isRemote: boolean; message 'isRemote';
    procedure setSoundName(newValue: NSString); message 'setSoundName:';
    function soundName: NSString; message 'soundName';
    procedure setHasActionButton(newValue: boolean); message 'setHasActionButton:';
    function hasActionButton: boolean; message 'hasActionButton';
    function activationType: NSUserNotificationActivationType; message 'activationType';
    procedure setOtherButtonTitle(newValue: NSString); message 'setOtherButtonTitle:';
    function otherButtonTitle: NSString; message 'otherButtonTitle';

    // Adopted protocols
    //function copyWithZone (zone: NSZonePtr): id; message 'copyWithZone:';
  end;

  NSUserNotificationCenterDelegateProtocol = objcprotocol;

  NSUserNotificationCenter = objcclass external (NSObject)
  private
    _internal: id;
  public
    class function defaultUserNotificationCenter: NSUserNotificationCenter; message 'defaultUserNotificationCenter';
    procedure setDelegate(newValue: NSUserNotificationCenterDelegateProtocol); message 'setDelegate:';
    function delegate: NSUserNotificationCenterDelegateProtocol; message 'delegate';
    procedure setScheduledNotifications(newValue: NSArray); message 'setScheduledNotifications:';
    function scheduledNotifications: NSArray; message 'scheduledNotifications';
    procedure scheduleNotification (notification: NSUserNotification); message 'scheduleNotification:';
    procedure removeScheduledNotification (notification: NSUserNotification); message 'removeScheduledNotification:';
    function deliveredNotifications: NSArray; message 'deliveredNotifications';
    procedure deliverNotification (notification: NSUserNotification); message 'deliverNotification:';
    procedure removeDeliveredNotification (notification: NSUserNotification); message 'removeDeliveredNotification:';
    procedure removeAllDeliveredNotifications; message 'removeAllDeliveredNotifications';
  end;

  NSUserNotificationCenterDelegateProtocol = objcprotocol external name 'NSUserNotificationCenterDelegate' (NSObjectProtocol)
  optional
    procedure userNotificationCenter_didDeliverNotification (center: NSUserNotificationCenter; notification: NSUserNotification); message 'userNotificationCenter:didDeliverNotification:';
    procedure userNotificationCenter_didActivateNotification (center: NSUserNotificationCenter; notification: NSUserNotification); message 'userNotificationCenter:didActivateNotification:';
    function userNotificationCenter_shouldPresentNotification (center: NSUserNotificationCenter; notification: NSUserNotification): boolean; message 'userNotificationCenter:shouldPresentNotification:';
  end;

procedure DeliverUserNotification(const Title, Subtitle, Message: string);
procedure DeliverUserNotification(const Title, Subtitle, Message, Sound: string);

var
  NSUserNotificationDefaultSoundName: NSString { available in 10_8, NA }; cvar; external;

implementation

procedure DeliverUserNotification(const Title, Subtitle, Message: string);
var
  Notification: NSUserNotification;

begin
  Notification := NSUserNotification.alloc.init;

  try
    Notification.setTitle(NSStr(PChar(Title)));
    Notification.setSubtitle(NSStr(PChar(Subtitle)));
    Notification.setInformativeText(NSStr(PChar(Message)));
    Notification.setSoundName(NSUserNotificationDefaultSoundName);
    NSUserNotificationCenter.defaultUserNotificationCenter.deliverNotification(Notification);

  finally
    Notification.release;
  end;
end;



procedure DeliverUserNotification(const Title, Subtitle, Message, Sound: string);
var
  Notification: NSUserNotification;

begin
  Notification := NSUserNotification.alloc.init;

  try
    Notification.setTitle(NSStr(PChar(Title)));
    Notification.setSubtitle(NSStr(PChar(Subtitle)));
    Notification.setInformativeText(NSStr(PChar(Message)));

    if Sound <> '' then
      Notification.setSoundName(NSStr(PChar(Sound)));

    NSUserNotificationCenter.defaultUserNotificationCenter.deliverNotification(Notification);

  finally
    Notification.release;
  end;
end;



end.
« Last Edit: May 05, 2014, 12:00:54 pm by exodusd »

exodusd

  • New member
  • *
  • Posts: 9
I just noticed some charset problems with that code. Here's a modified version using NSString(CFStringCreateWithPascalString(kCFAllocatorDefault, Str, kCFStringEncodingUTF8)) for the pascal to NSString conversion. I got that from a different example and it seems to do the trick.

I'm not sure if there's an easier way to deal with this, but at least this one seems to work:

Code: [Select]
unit UserNotification;

interface

{$mode objfpc}{$H+}
{$modeswitch objectivec1}
{$linkframework Foundation}

uses
  Classes, SysUtils, MacOSAll, CocoaAll, CarbonProc;

const
  NSUserNotificationActivationTypeNone = 0;
  NSUserNotificationActivationTypeContentsClicked = 1;
  NSUserNotificationActivationTypeActionButtonClicked = 2;

type
  NSUserNotificationPtr = ^NSUserNotification;
  NSUserNotificationCenterPtr = ^NSUserNotificationCenter;
  NSUserNotificationCenterDelegateProtocolPtr = ^NSUserNotificationCenterDelegateProtocol;

  NSUserNotificationActivationType = NSInteger;
  NSUserNotificationActivationTypePtr = ^NSUserNotificationActivationType;

  //NSUserNotification = objcclass external (NSObject, NSCopyingProtocol)
  NSUserNotification = objcclass external (NSObject)
  private
    _internal: id;
  public
    procedure setTitle(newValue: NSString); message 'setTitle:';
    function title: NSString; message 'title';
    procedure setSubtitle(newValue: NSString); message 'setSubtitle:';
    function subtitle: NSString; message 'subtitle';
    procedure setInformativeText(newValue: NSString); message 'setInformativeText:';
    function informativeText: NSString; message 'informativeText';
    procedure setActionButtonTitle(newValue: NSString); message 'setActionButtonTitle:';
    function actionButtonTitle: NSString; message 'actionButtonTitle';
    procedure setUserInfo(newValue: NSDictionary); message 'setUserInfo:';
    function userInfo: NSDictionary; message 'userInfo';
    procedure setDeliveryDate(newValue: NSDate); message 'setDeliveryDate:';
    function deliveryDate: NSDate; message 'deliveryDate';
    procedure setDeliveryTimeZone(newValue: NSTimeZone); message 'setDeliveryTimeZone:';
    function deliveryTimeZone: NSTimeZone; message 'deliveryTimeZone';
    procedure setDeliveryRepeatInterval(newValue: NSDateComponents); message 'setDeliveryRepeatInterval:';
    function deliveryRepeatInterval: NSDateComponents; message 'deliveryRepeatInterval';
    function actualDeliveryDate: NSDate; message 'actualDeliveryDate';
    function isPresented: boolean; message 'isPresented';
    function isRemote: boolean; message 'isRemote';
    procedure setSoundName(newValue: NSString); message 'setSoundName:';
    function soundName: NSString; message 'soundName';
    procedure setHasActionButton(newValue: boolean); message 'setHasActionButton:';
    function hasActionButton: boolean; message 'hasActionButton';
    function activationType: NSUserNotificationActivationType; message 'activationType';
    procedure setOtherButtonTitle(newValue: NSString); message 'setOtherButtonTitle:';
    function otherButtonTitle: NSString; message 'otherButtonTitle';

    // Adopted protocols
    //function copyWithZone (zone: NSZonePtr): id; message 'copyWithZone:';
  end;

  NSUserNotificationCenterDelegateProtocol = objcprotocol;

  NSUserNotificationCenter = objcclass external (NSObject)
  private
    _internal: id;
  public
    class function defaultUserNotificationCenter: NSUserNotificationCenter; message 'defaultUserNotificationCenter';
    procedure setDelegate(newValue: NSUserNotificationCenterDelegateProtocol); message 'setDelegate:';
    function delegate: NSUserNotificationCenterDelegateProtocol; message 'delegate';
    procedure setScheduledNotifications(newValue: NSArray); message 'setScheduledNotifications:';
    function scheduledNotifications: NSArray; message 'scheduledNotifications';
    procedure scheduleNotification (notification: NSUserNotification); message 'scheduleNotification:';
    procedure removeScheduledNotification (notification: NSUserNotification); message 'removeScheduledNotification:';
    function deliveredNotifications: NSArray; message 'deliveredNotifications';
    procedure deliverNotification (notification: NSUserNotification); message 'deliverNotification:';
    procedure removeDeliveredNotification (notification: NSUserNotification); message 'removeDeliveredNotification:';
    procedure removeAllDeliveredNotifications; message 'removeAllDeliveredNotifications';
  end;

  NSUserNotificationCenterDelegateProtocol = objcprotocol external name 'NSUserNotificationCenterDelegate' (NSObjectProtocol)
  optional
    procedure userNotificationCenter_didDeliverNotification (center: NSUserNotificationCenter; notification: NSUserNotification); message 'userNotificationCenter:didDeliverNotification:';
    procedure userNotificationCenter_didActivateNotification (center: NSUserNotificationCenter; notification: NSUserNotification); message 'userNotificationCenter:didActivateNotification:';
    function userNotificationCenter_shouldPresentNotification (center: NSUserNotificationCenter; notification: NSUserNotification): boolean; message 'userNotificationCenter:shouldPresentNotification:';
  end;

procedure DeliverUserNotification(const Title, Subtitle, Message: string);
procedure DeliverUserNotification(const Title, Subtitle, Message, Sound: string);

var
  NSUserNotificationDefaultSoundName: NSString { available in 10_8, NA }; cvar; external;

implementation

procedure DeliverUserNotification(const Title, Subtitle, Message: string);
begin
  DeliverUserNotification(Title, Subtitle, Message, CFStringToStr(CFStringRef(NSUserNotificationDefaultSoundName)));
end;



procedure DeliverUserNotification(const Title, Subtitle, Message, Sound: string);
var
  Notification: NSUserNotification;
  TmpNSStr: NSString;

begin
  Notification := NSUserNotification.alloc.init;

  try
    TmpNSStr := NSString(CFStringCreateWithPascalString(kCFAllocatorDefault, Title, kCFStringEncodingUTF8));

    try
      Notification.setTitle(TmpNSStr);

    finally
      TmpNSStr.release;
    end;

    TmpNSStr := NSString(CFStringCreateWithPascalString(kCFAllocatorDefault, Subtitle, kCFStringEncodingUTF8));

    try
      Notification.setSubtitle(TmpNSStr);

    finally
      TmpNSStr.release;
    end;

    TmpNSStr := NSString(CFStringCreateWithPascalString(kCFAllocatorDefault, Message, kCFStringEncodingUTF8));

    try
      Notification.setInformativeText(TmpNSStr);

    finally
      TmpNSStr.release;
    end;

    if Sound <> '' then
    begin
      TmpNSStr := NSString(CFStringCreateWithPascalString(kCFAllocatorDefault, Sound, kCFStringEncodingUTF8));

      try
        Notification.setSoundName(TmpNSStr);

      finally
        TmpNSStr.release;
      end;
    end;

    NSUserNotificationCenter.defaultUserNotificationCenter.deliverNotification(Notification);

  finally
    Notification.release;
  end;
end;



end.
« Last Edit: May 05, 2014, 10:59:02 pm by exodusd »

esvignolo

  • Full Member
  • ***
  • Posts: 150
  • Using FPC in Windows, Linux, Macos
Thanks exodusd, work well, but by default is not showing the popup, i search and found this:

http://blog.mahasoftware.com/post/28968246552/how-to-use-the-10-8-notification-center-api

By default, Notification Center only displays notifications if the application is not frontmost. To always present the notification, you need to set the delegate on the NSUserNotificationCenter as shown above, and implement the NSUserNotification

CenterDelegate as follows:

- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification
{
    return YES;
}


Can you add this to your unit?

Thanks again

exodusd

  • New member
  • *
  • Posts: 9
Ok, it took a while to figure this out. I took some inspiration from this wiki: http://wiki.lazarus.freepascal.org/Mac_OS_X_Text-to-Speech and read a bit about the delegates. I finally got it to work, but it would be great if someone with more experience could test this for memory leaks etc in Mac OS X, since I mostly put together code without really understanding what I'm doing. I tried using release for each alloc.init, but I lack the experience to know whether this is the right way to do it. ;)

Anyway, here's the code I came up with. I added some ifdefs to make sure that the unit is empty for other platforms than Mac OS X (Darwin), so that you can add it to crossplatform programs without running into any problems (as long as you're using the code only on Mac OS X - e.g. as a replacement for the TrayIcon baloon-tips - that's what I'm using it for).

Cheers,
  Robert

Code: [Select]
unit UserNotification;

interface

{$ifdef Darwin}
{$mode objfpc}{$H+}
{$modeswitch objectivec1}
{$linkframework Foundation}

uses
  Classes, SysUtils, MacOSAll, CocoaAll, CarbonProc;



const
  NSUserNotificationActivationTypeNone = 0;
  NSUserNotificationActivationTypeContentsClicked = 1;
  NSUserNotificationActivationTypeActionButtonClicked = 2;



type
  NSUserNotificationPtr = ^NSUserNotification;
  NSUserNotificationCenterPtr = ^NSUserNotificationCenter;
  NSUserNotificationCenterDelegateProtocolPtr = ^NSUserNotificationCenterDelegateProtocol;

  NSUserNotificationActivationType = NSInteger;
  NSUserNotificationActivationTypePtr = ^NSUserNotificationActivationType;



  //NSUserNotification = objcclass external (NSObject, NSCopyingProtocol)
  NSUserNotification = objcclass external (NSObject)
  private
    _internal: id;
  public
    procedure setTitle(newValue: NSString); message 'setTitle:';
    function title: NSString; message 'title';
    procedure setSubtitle(newValue: NSString); message 'setSubtitle:';
    function subtitle: NSString; message 'subtitle';
    procedure setInformativeText(newValue: NSString); message 'setInformativeText:';
    function informativeText: NSString; message 'informativeText';
    procedure setActionButtonTitle(newValue: NSString); message 'setActionButtonTitle:';
    function actionButtonTitle: NSString; message 'actionButtonTitle';
    procedure setUserInfo(newValue: NSDictionary); message 'setUserInfo:';
    function userInfo: NSDictionary; message 'userInfo';
    procedure setDeliveryDate(newValue: NSDate); message 'setDeliveryDate:';
    function deliveryDate: NSDate; message 'deliveryDate';
    procedure setDeliveryTimeZone(newValue: NSTimeZone); message 'setDeliveryTimeZone:';
    function deliveryTimeZone: NSTimeZone; message 'deliveryTimeZone';
    procedure setDeliveryRepeatInterval(newValue: NSDateComponents); message 'setDeliveryRepeatInterval:';
    function deliveryRepeatInterval: NSDateComponents; message 'deliveryRepeatInterval';
    function actualDeliveryDate: NSDate; message 'actualDeliveryDate';
    function isPresented: boolean; message 'isPresented';
    function isRemote: boolean; message 'isRemote';
    procedure setSoundName(newValue: NSString); message 'setSoundName:';
    function soundName: NSString; message 'soundName';
    procedure setHasActionButton(newValue: boolean); message 'setHasActionButton:';
    function hasActionButton: boolean; message 'hasActionButton';
    function activationType: NSUserNotificationActivationType; message 'activationType';
    procedure setOtherButtonTitle(newValue: NSString); message 'setOtherButtonTitle:';
    function otherButtonTitle: NSString; message 'otherButtonTitle';

    // Adopted protocols
    //function copyWithZone (zone: NSZonePtr): id; message 'copyWithZone:';
  end;



  NSUserNotificationCenterDelegateProtocol = objcprotocol;



  NSUserNotificationCenter = objcclass external (NSObject)
  private
    _internal: id;
  public
    class function defaultUserNotificationCenter: NSUserNotificationCenter; message 'defaultUserNotificationCenter';
    //procedure setDelegate(newValue: NSUserNotificationCenterDelegateProtocol); message 'setDelegate:';
    procedure setDelegate(newValue: NSObject); message 'setDelegate:';
    function delegate: NSUserNotificationCenterDelegateProtocol; message 'delegate';
    procedure setScheduledNotifications(newValue: NSArray); message 'setScheduledNotifications:';
    function scheduledNotifications: NSArray; message 'scheduledNotifications';
    procedure scheduleNotification (notification: NSUserNotification); message 'scheduleNotification:';
    procedure removeScheduledNotification (notification: NSUserNotification); message 'removeScheduledNotification:';
    function deliveredNotifications: NSArray; message 'deliveredNotifications';
    procedure deliverNotification (notification: NSUserNotification); message 'deliverNotification:';
    procedure removeDeliveredNotification (notification: NSUserNotification); message 'removeDeliveredNotification:';
    procedure removeAllDeliveredNotifications; message 'removeAllDeliveredNotifications';
  end;



  NSUserNotificationCenterDelegateProtocol = objcprotocol external name 'NSUserNotificationCenterDelegate' (NSObjectProtocol)
  optional
    procedure userNotificationCenter_didDeliverNotification (center: NSUserNotificationCenter; notification: NSUserNotification); message 'userNotificationCenter:didDeliverNotification:';
    procedure userNotificationCenter_didActivateNotification (center: NSUserNotificationCenter; notification: NSUserNotification); message 'userNotificationCenter:didActivateNotification:';
    function userNotificationCenter_shouldPresentNotification (center: NSUserNotificationCenter; notification: NSUserNotification): boolean; message 'userNotificationCenter:shouldPresentNotification:';
  end;



  NSUserNotificationCenterAlwaysShowDelegate = objcclass(NSObject)
  public
    function shouldPresentNotification ({%H-}center: NSUserNotificationCenter; {%H-}notification: NSUserNotification): boolean; message 'userNotificationCenter:shouldPresentNotification:';
  end;



procedure DeliverUserNotification(const Title, Subtitle, Message: string);
procedure DeliverUserNotification(const Title, Subtitle, Message, Sound: string);



var
  NSUserNotificationDefaultSoundName: NSString { available in 10_8, NA }; cvar; external;

{$endif}

implementation

{$ifdef Darwin}

var
  UserNotificationCenterDelegate: NSUserNotificationCenterAlwaysShowDelegate;



function NSUserNotificationCenterAlwaysShowDelegate.shouldPresentNotification (center: NSUserNotificationCenter; notification: NSUserNotification): boolean;
begin
  Result := True;
end;



procedure DeliverUserNotification(const Title, Subtitle, Message: string);
begin
  DeliverUserNotification(Title, Subtitle, Message, CFStringToStr(CFStringRef(NSUserNotificationDefaultSoundName)));
end;



procedure DeliverUserNotification(const Title, Subtitle, Message, Sound: string);
var
  Notification: NSUserNotification;
  TmpNSStr: NSString;

begin
  Notification := NSUserNotification.alloc.init;

  try
    TmpNSStr := NSString(CFStringCreateWithPascalString(kCFAllocatorDefault, Title, kCFStringEncodingUTF8));

    try
      Notification.setTitle(TmpNSStr);

    finally
      TmpNSStr.release;
    end;

    TmpNSStr := NSString(CFStringCreateWithPascalString(kCFAllocatorDefault, Subtitle, kCFStringEncodingUTF8));

    try
      Notification.setSubtitle(TmpNSStr);

    finally
      TmpNSStr.release;
    end;

    TmpNSStr := NSString(CFStringCreateWithPascalString(kCFAllocatorDefault, Message, kCFStringEncodingUTF8));

    try
      Notification.setInformativeText(TmpNSStr);

    finally
      TmpNSStr.release;
    end;

    if Sound <> '' then
    begin
      TmpNSStr := NSString(CFStringCreateWithPascalString(kCFAllocatorDefault, Sound, kCFStringEncodingUTF8));

      try
        Notification.setSoundName(TmpNSStr);

      finally
        TmpNSStr.release;
      end;
    end;

    NSUserNotificationCenter.defaultUserNotificationCenter.deliverNotification(Notification);

  finally
    Notification.release;
  end;
end;



initialization
  UserNotificationCenterDelegate := NSUserNotificationCenterAlwaysShowDelegate.alloc.init;
  NSUserNotificationCenter.defaultUserNotificationCenter.setDelegate(UserNotificationCenterDelegate);



finalization
  NSUserNotificationCenter.defaultUserNotificationCenter.setDelegate(nil);
  UserNotificationCenterDelegate.release;

{$endif}



end.

esvignolo

  • Full Member
  • ***
  • Posts: 150
  • Using FPC in Windows, Linux, Macos
Thanks!!!! work fine!!!  :D :D :D :D :D :D

Hansaplast

  • Hero Member
  • *****
  • Posts: 569
  • Tweaking4All.com
    • Tweaking4All
I realize this topic is old, but I assume others may stumble on this one as well.
It seems that "NSUserNotification" is deprecated (source).


Maybe it's an idea to update TPopupNotifier to accommodate these kind of "new" notifications for macOS (link), Windows (link), Growl, LibNotify (link), and whatever is out there (using the current TPopupNotifier as a fall back).