Recent

Author Topic: handler EventKit can't get it to work  (Read 2134 times)

BVale

  • Newbie
  • Posts: 6
handler EventKit can't get it to work
« on: February 19, 2024, 10:32:45 am »
hi everyone,

here is my code, its just a simple form with a button.
I tried already several things but it just dont work out. The way I want to.
The following code works kinda. the system asks me if I want to access the calendar. But I can't handle the event. 

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode delphi}{$H+}
  4. {$modeswitch objectivec1}
  5. {$modeswitch cblocks}
  6. {$linkframework EventKit}
  7. interface
  8.  
  9. uses
  10.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  11.   CocoaAll, MacOSAll, EventKit;
  12.  
  13. type
  14.  
  15.   { TForm1 }
  16.  
  17.   TForm1 = class(TForm)
  18.     Button1: TButton;
  19.     procedure Button1Click(Sender: TObject);
  20.   private
  21.  
  22.  
  23.   public
  24.  
  25.  
  26.   end;
  27.  
  28. var
  29.   Form1: TForm1;
  30.  
  31. implementation
  32.  
  33. {$R *.lfm}
  34.  
  35. { TForm1 }
  36. //
  37. //procedure CompletionHandler(granted: boolean; error: NSError)cdecl;
  38. //begin
  39. //  if granted then
  40. //    ShowMessage('Zugriff gewährt')
  41. //  else
  42. //    ShowMessage('Zugriff verweigert oder Fehler aufgetreten: ' +
  43. //      error.localizedDescription.utf8string);
  44. //end;
  45.  
  46. procedure TForm1.Button1Click(Sender: TObject);
  47. var
  48.   handler: EKEventStoreRequestAccessCompletionHandler;
  49.   store: EKEventStore;
  50. begin
  51.   store := EKEventStore.alloc.init;
  52.   store.requestAccessToEntityType_completion(EKEntityTypeEvent, handler);
  53.  
  54. end;
  55.  
  56. end.
  57.  


this one crashes
when I press the button


Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode delphi}{$H+}
  4. {$modeswitch objectivec1}
  5. {$modeswitch cblocks}
  6. {$linkframework EventKit}
  7. interface
  8.  
  9. uses
  10.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  11.   CocoaAll, MacOSAll, EventKit;
  12.  
  13. type
  14.  
  15.   { TForm1 }
  16.  
  17.   TForm1 = class(TForm)
  18.     Button1: TButton;
  19.     procedure Button1Click(Sender: TObject);
  20.   private
  21.  
  22.  
  23.   public
  24.  
  25.  
  26.   end;
  27.  
  28. var
  29.   Form1: TForm1;
  30.  
  31. implementation
  32.  
  33. {$R *.lfm}
  34.  
  35. { TForm1 }
  36.  
  37. procedure CompletionHandler(granted: boolean; error: NSError)cdecl;
  38. begin
  39.   if granted then
  40.     ShowMessage('Zugriff gewährt')
  41.   else
  42.     ShowMessage('Zugriff verweigert oder Fehler aufgetreten: ' +
  43.       error.localizedDescription.utf8string);
  44. end;
  45.  
  46. procedure TForm1.Button1Click(Sender: TObject);
  47. var
  48.  // handler: EKEventStoreRequestAccessCompletionHandler;
  49.   store: EKEventStore;
  50. begin
  51.   store := EKEventStore.alloc.init;
  52.   store.requestAccessToEntityType_completion(EKEntityTypeEvent, @CompletionHandler);
  53.  
  54. end;
  55.  
  56. end.
  57.  
  58.  

does anyone knows how "to handle" this?

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1060
Re: handler EventKit can't get it to work
« Reply #1 on: February 19, 2024, 10:08:50 pm »
The first example doesn't make any sense. You're not assigning anything handler, so you're passing a random pointer value there. Additionally, the "boolean" parameter of the completion handler needs to be "ObjCBOOL".

The second one won't work because the Cocoa header parser has not been adjusted since FPC got support for C-blocks, so it defines all "block" parameters as a plain pointer.

If you fix the completion handler's booleanm parameter and assign its address to "handler", then I think the first example will work.

BVale

  • Newbie
  • Posts: 6
Re: handler EventKit can't get it to work
« Reply #2 on: February 20, 2024, 12:38:46 am »
thank you for the answer.

Code: Pascal  [Select][+][-]
  1.  
  2. unit Unit1;
  3.  
  4. {$mode delphi}{$H+}
  5. {$modeswitch objectivec1}
  6. {$modeswitch cblocks}
  7. {$linkframework EventKit}
  8. interface
  9.  
  10. uses
  11.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  12.   CocoaAll, MacOSAll, EventKit;
  13.  
  14. type
  15.  
  16.   { TForm1 }
  17.  
  18.   TForm1 = class(TForm)
  19.     Button1: TButton;
  20.     procedure Button1Click(Sender: TObject);
  21.   private
  22.  
  23.  
  24.   public
  25.  
  26.  
  27.   end;
  28.  
  29. var
  30.   Form1: TForm1;
  31.  
  32.  
  33. implementation
  34.  
  35. {$R *.lfm}
  36.  
  37. { TForm1 }
  38.  
  39. procedure CompletionHandler(granted: ObjCBOOL; error: NSError);
  40. begin
  41.   if granted then
  42.     ShowMessage('Zugriff gewährt')
  43.   else
  44.     ShowMessage('Zugriff verweigert oder Fehler aufgetreten: ' +
  45.       error.localizedDescription.utf8string);
  46. end;
  47.  
  48. procedure TForm1.Button1Click(Sender: TObject);
  49. var
  50.   store: EKEventStore;
  51.   myAccessHandler: EKEventStoreRequestAccessCompletionHandler;
  52. begin
  53.    myAccessHandler:=@CompletionHandler;
  54.   store := EKEventStore.alloc.init;
  55.   store.requestAccessToEntityType_completion(EKEntityTypeEvent, myAccessHandler);
  56.  
  57. end;
  58.  
  59. end.
  60.  
probably u mean something like this. it won't work either.

all I get is allways this error. like in the picture

its so frustrating... u have no idea how I long I am already trying to get this to work the only chance for me to get no crash is to send the handler to nirvana. maybe u have or someone else has an other idea, or maybe is trying for a second to get this to work too... dont know. 

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2236
  • Fifty shades of code.
    • Delphi & FreePascal
Re: handler EventKit can't get it to work
« Reply #3 on: February 20, 2024, 01:20:18 am »
I have no MacOS but from my Windows experience Handlers or Callbacks must be outside of methods that need them, so I would modify your code into this:
(added OnCreate() event for Form1)
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode delphi}{$H+}
  4. {$modeswitch objectivec1}
  5. {$modeswitch cblocks}
  6. {$linkframework EventKit}
  7. interface
  8.  
  9. uses
  10.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  11.   CocoaAll, MacOSAll, EventKit;
  12.  
  13. type
  14.  
  15.   { TForm1 }
  16.  
  17.   TForm1 = class(TForm)
  18.     Button1: TButton;
  19.     procedure FormCreate(Sender: TObject);  
  20.     procedure Button1Click(Sender: TObject);
  21.   strict private
  22.     FHandler: EKEventStoreRequestAccessCompletionHandler;
  23.     FStore: EKEventStore;
  24.   protected
  25.     procedure CompletionHandler(granted: ObjCBOOL; error: NSError);
  26.   private
  27.   public
  28.   end;
  29.  
  30. var
  31.   Form1: TForm1;
  32.  
  33.  
  34. implementation
  35.  
  36. {$R *.lfm}
  37.  
  38. { TForm1 }
  39.  
  40. procedure TForm1.CompletionHandler(granted: ObjCBOOL; error: NSError);
  41. begin
  42.   if granted then
  43.     ShowMessage('Zugriff gewährt')
  44.   else
  45.     ShowMessage('Zugriff verweigert oder Fehler aufgetreten: ' +
  46.       error.localizedDescription.utf8string);
  47. end;
  48.  
  49. procedure TForm1.Button1Click(Sender: TObject);
  50. begin
  51.   if FHandler = nil then
  52.     FHandler := @CompletionHandler;
  53.   if FStore = nil then
  54.     FStore := EKEventStore.alloc.init;
  55.   FStore.requestAccessToEntityType_completion(EKEntityTypeEvent, FHandler);
  56. end;
  57.  
  58. procedure TForm1.FormCreate(Sender: TObject);  
  59. begin
  60.   FHandler := nil;
  61.   FStore := nil;
  62. end;
  63.  
  64. end.
Additional, set in line "if granted then" a breakpoint, run app, do something that the event has a chance to get fired, will it stop in the CompletionHandler?
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

BVale

  • Newbie
  • Posts: 6
Re: handler EventKit can't get it to work
« Reply #4 on: February 20, 2024, 09:57:31 am »
hi kodezwerg, that don't work either.

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1060
Re: handler EventKit can't get it to work
« Reply #5 on: February 20, 2024, 09:05:00 pm »
The issue is that the type definition for all of the C-block types in the CocoaInt headers is wrong. It's defined as Pointer, but it should be a C-block procvar type. These are records, and are passed by value rather than by reference (so just passing @cblockvar won't work).

To fix this for individual cases, you'll need to redefine the relevant methods using correct parameter types. You can do so by creating a category for the relevant class with a method that has the correct signature. I.e., in this case, something like this (untested):
Code: [Select]
type
  EKEventStoreRequestAccessCompletionHandler_Fixed = reference to Procedure(granted: ObjCBOOL; error: NSError); cdecl; cblock;

  EKEventStore_FixedMethods = objccategory(EKEventStore)
    procedure requestAccessToEntityType_completion_fixed (entityType: EKEntityType; completion: EKEventStoreRequestAccessCompletionHandler_Fixed); message 'requestAccessToEntityType:completion:';
  end;

And then call requestAccessToEntityType_completion_fixed instead of requestAccessToEntityType_completion.

It would be very nice if someone could take responsibility to fixing and maintaining the Cocoa headers, because the original creator hasn't done so for quite a while and never added support for blocks after the compiler got support for it. You can find the converter used to create the header translations at https://github.com/genericptr/Framework-Parser

BVale

  • Newbie
  • Posts: 6
Re: handler EventKit can't get it to work
« Reply #6 on: February 21, 2024, 08:41:51 am »
jonas maebe, thank you for the answer, I have tried that also... it will just rise an error as well.

my knowledge of development is not that advance... the framework-parser dont work here couse it needs php7... and  I just get php8 installed and forcing it to run on 8 doesn't work that well.




BVale

  • Newbie
  • Posts: 6
Re: handler EventKit can't get it to work
« Reply #7 on: March 05, 2024, 11:35:13 pm »
found the solution


Code: Pascal  [Select][+][-]
  1. type
  2.  
  3.   EKEventStoreRequestAccessCompletionHandler = procedure(granted: Boolean; error: NSError) of object; cblock; cdecl;
  4.  
  5.    EKEventStore = objcclass external (NSObject)
  6.      procedure requestFullAccessToEventsWithCompletion(completion: EKEventStoreRequestAccessCompletionHandler); message 'requestFullAccessToEventsWithCompletion:'; // Beachten Sie die Verwendung der message-Direktive
  7.      function calendarsForEntityType(entityType: EKEntityType): NSArray; message 'calendarsForEntityType:';      
  8.  
  9.  
  10.  

Code: Pascal  [Select][+][-]
  1. procedure TForm1.RequestAccessHandler(granted: Boolean; error: NSError);
  2. begin
  3.   if granted then
  4.     //FMessage := 'Zugriff gewährt'
  5.   else if Assigned(error) then
  6.     //FMessage := 'Fehler: ' + error.localizedDescription.UTF8String
  7.   else
  8.     //FMessage := 'Zugriff verweigert';
  9.  
  10. end;
  11.  
  12.  
  13. procedure TForm1.Button1Click(Sender: TObject);
  14. var
  15.   store: EKEventStore;
  16. begin
  17.   store := EKEventStore.alloc.init;
  18.   store.requestFullAccessToEventsWithCompletion(RequestAccessHandler);
  19.  
  20. end;  
  21.  



Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1060
Re: handler EventKit can't get it to work
« Reply #8 on: March 06, 2024, 09:39:26 pm »
You really should use ObjCBool instead of boolean, otherwise it's guaranteed to break on some platforms.

BVale

  • Newbie
  • Posts: 6
Re: handler EventKit can't get it to work
« Reply #9 on: March 08, 2024, 10:10:44 am »
@Jonas maebe oh yeah u are right!
thanks for the reminder.

do u have an idea how to integrate that into the eventstore.inc? so I have not to include everything from there to my working unit?...

 

TinyPortal © 2005-2018