How to get started or am I mad ?

LiveCode Builder is a language for extending LiveCode's capabilities, creating new object types as Widgets, and libraries that access lower-level APIs in OSes, applications, and DLLs.

Moderators: LCMark, LCfraser

Post Reply
Simon Knight
Posts: 845
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

How to get started or am I mad ?

Post by Simon Knight » Sat Feb 01, 2020 12:33 pm

Hi all,

I should caveat this post by saying that I don't really have a clue what I am doing.

What I would like to do is create a LCB library to wrap the commands that Apple provides in its EventKit framework to expose these functions to Livecode Script

Yesterday I completed the "hello world" tutorial for LCB and then I started googling, searching the dictionary etc. I may have missed a lot of information but as someone new to LCB it seems that there is not much in the way of what I will call intermediate level teaching. So my first question is what other teaching material would you recommend ? For instance is there any thing that extends on the great information in this post : viewtopic.php?f=93&t=30429 . Is there anything of similar detail about wrapping commands from a framework?

I have tried reading the dictionary but I find that the entries rely on background knowledge of "C" and other low level programming terms and techniques that I don't understand (yet).

One last thing that concerns me is that Apple state that any application that accesses the Calendar data using EventKit should ask permission to do so first. Does anyone how complex this is to implement?
best wishes
Skids

mrcoollion
Posts: 719
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Re: How to get started or am I mad ?

Post by mrcoollion » Sun Feb 02, 2020 10:31 am


Simon Knight
Posts: 845
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: How to get started or am I mad ?

Post by Simon Knight » Sun Feb 02, 2020 1:03 pm

Thanks,

Unfortunately its a bit more complex than a simple hello world. I've spent the past day and a bit reading about Objective-C and frankly I'm barely any the wiser. To me it seems to be a language written mostly for the benefit of the compiler but then I have been spoilt by using Livecode Script for the past few years.

The problem starts with understanding what this Objective-C command is doing and then trying to wrap the command with LCB scripts:

Code: Select all

EKEventStore *store = [[EKEventStore alloc] initWithAccessToEntityTypes:EKEntityMaskReminder];
I believe that the command initialises an instance of an EKEventStore and stores a reference to the new object in the pointer store. The command is a compound and also allocates memory for the new object. EKEntityMaskReminder is probably a constant but I am unable to confirm this.

The documentation shows an example of using a SpeechSynthesizer object. The code examples use single "methods" rather than a compound statement implying that I should create a bound allocation handler and an 'init' handler. The example then declares a local var tSynthesizer as an ObjcObject which makes sense but it passes this into a foreign handler where it is typed as type "ObjcID" .

At times the documentation gets a bit heavy on terminology for example the following note:
Note: No bridging of types will occur when passing a parameter in the non-fixed section of a variadic argument list. You must ensure the arguments you pass there are of the appropriate foreign type (e.g. CInt, CDouble).
I'm not sure that variadic argument list is ever fixed.

This note seems to require greater knowledge than I have. It would also be quite a good memory test at parties:
Note: When an ObjcId is converted to ObjcObject, the id is retained; when an ObjcObject converted to an ObjcId, the id is not retained. Conversely, when an ObjcRetainedId is converted to an ObjcObject, the object takes the +1 reference count (so does not retain); when an ObjcObject is put into an ObjcRetainedId, a +1 reference count is taken (so does retain).
So thats clear then !

So after many hours of reading here is the start of my library. I have no idea if it works or if I am even close, so feel free to get the red pen out:

Code: Select all

private foreign handler ObjC_EKEventStoreAlloc() returns objcRetainedID binds to "objC:EKEventstore.+alloc"

private handler CreateEventStore() returns ObjcObject
	unsafe
		variable tEventStore as ObjcObject
		put ObjC_EKEventStoreAlloc() into tEventStore
		return tEventStore
	end unsafe
end handler
best wishes
Skids

trevordevore
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1005
Joined: Sat Apr 08, 2006 3:06 pm
Location: Overland Park, Kansas
Contact:

Re: How to get started or am I mad ?

Post by trevordevore » Mon Feb 03, 2020 6:31 am

Simon,

You can find Objective-C LCB examples in the following Github repo:

https://github.com/trevordevore/lc-macos-toolset

There are a couple of examples of allocating an object and then initializing it in the files in the repo. the NSURL file is one such example:

https://github.com/trevordevore/lc-maco ... /nsurl.lcb

As for the EKEntityMaskReminder constant, you can often find the values with a Google search. I just searched on it and came across this page:'

https://developer.apple.com/documentati ... guage=objc

It shows this for the definition:

Code: Select all

EKEntityMaskReminder = (1 << EKEntityTypeReminder)
When searching for EKEntityTypeReminder I found this:

https://github.com/phracker/MacOSX-SDKs ... pes.h#L117

Based on the above I would try to use the following to represent EKEntityReminder:

Code: Select all

1 shifted left by 1 bitwise
Hopefully the example code will help you out.
Trevor DeVore
ScreenSteps - https://www.screensteps.com

LiveCode Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode
LiveCode Builder Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode-builder

Simon Knight
Posts: 845
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: How to get started or am I mad ?

Post by Simon Knight » Mon Feb 03, 2020 10:09 am

Hi Trevor,

Many thanks for your detailed post. I'll start working through the links you provide later today. I've spent a large proportion of the past two days googling Objective-C and Eventkit so much that I'm going goggle eyed. It seems to me that Objective-C is written backwards when compared with other programming languages and I can see why Apple developed Swift.

So far I have written code based on the example from the LCB documentation that wraps the SpeechSynth commands as I think the requirements seem similar. My next task is to write the code that uses the constant to check access permission so the timing of your reply is excellent.

Thanks again

Simon
best wishes
Skids

Simon Knight
Posts: 845
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: How to get started or am I mad ?

Post by Simon Knight » Mon Feb 03, 2020 8:27 pm

Hi all,

This post is a note for anyone else who tries to wrap some objective-c handlers, without the background in C, objective-C or Cocoa to help.

The specific problem I have been wrestling with is how to use what I thought was an Objective-C constant. Trevor's post above gives the solution but until now I did not understand how he arrived at his answer.

I need to pass the variable EKEntityMaskReminder which is only available from within Objective-C (or Swift) i.e. not LCB. So I need to know its type and its value.

Trevor found that this constant is defined as

Code: Select all

EKEntityMaskReminder = (1 << EKEntityTypeReminder)
which is a bit shift operation on a second constant "EKEntityTypeReminder". Trevor then suggests the value of EKEntityMaskReminder is given by

Code: Select all

1 shifted left by 1 bitwise
which implies that EKEntityTypeReminder has a value of 1. So where does this value of 1 come from? Well again Trevor provides the answer by providing a link to file EkTypes.h which is one of the header files used by the EventKit. Unfortunately my almost total lack of knowledge about "C" meant I was unable to see the obvious (see below). In this case the key lines from Apple's file are :

Code: Select all

enum {
    EKEntityTypeEvent,
    EKEntityTypeReminder
};
typedef NSUInteger EKEntityType;


enum {
    EKEntityMaskEvent      = (1 << EKEntityTypeEvent),
    EKEntityMaskReminder   = (1 << EKEntityTypeReminder)
};
typedef NSUInteger EKEntityMask;
What I did not know was this :
In C programming, an enumeration type (also called enum) is a data type that consists of integral constants. To define enums, the enum keyword is used.

Code: Select all

enum flag {const1, const2, ..., constN};
By default, const1 is 0, const2 is 1 and so on. You can change default values of enum elements during declaration (if necessary).
Quoted from this site : https://www.programiz.com/c-programming/c-enumeration

So in short EKEntityTypeEvent is an unsigned integer value 0 and EKEntityTypeEvent is equal to 1.

phew!

I hope that someone else will find the information useful. If not then I apologise for taking up your time.
best wishes
Skids

Simon Knight
Posts: 845
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: How to get started or am I mad ?

Post by Simon Knight » Tue Feb 04, 2020 11:48 am

Hi,
This is a request for help in spotting where I am going wrong.

The apple documentation is here : https://developer.apple.com/documentati ... guage=objc

At present my LCB code is throwing an unable to bind to foreign handler error. I am attempting to call the "alloc" method of the EKEventStore class. In example Objective-C code a variable is defined and initialised with the following command:

Code: Select all

EKEventStore *eventStore = [[EKEventStore alloc] init];
First am I correct that I have to break this code line up in order to use the class in LCB ? I am attempting to call "alloc" before initialising my object variable (not shown here)

My LCB script that tries to calls the alloc method is here :

Code: Select all

library net.anvic.skids.debugek

use com.livecode.foreign
use com.livecode.objc

metadata title is "DebugEventKit"
metadata author is "Simon Knight"
metadata version is "1.0.0"

/**
Summary : Debug code for EventKit
Returns: String  reporting success
Description : An attempt at wrapping the commands provided by Apple in their EventKit framework.  Initially this library will only read data from the calendar.
**/

-- bind the memory allocation handler
private foreign handler ObjC_EKEventStoreAlloc() returns ObjcRetainedID binds to "objc:EKEventstore.+alloc"

public handler InitialiseEventStore() returns String

	unsafe
		variable tEventStore as optional ObjcObject
		put ObjC_EKEventStoreAlloc() into tEventStore  // throws an unable to bind to foreign handler error

		return "Success"
	end unsafe
end handler

end library
I feel I must have either completely misunderstood (highly possible) or that I have made a silly typo. Any thoughts?
best wishes
Skids

Simon Knight
Posts: 845
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: How to get started or am I mad ?

Post by Simon Knight » Wed Feb 05, 2020 12:27 pm

Well I continued to bang my head against a wall until I noticed that other code (e.g. AppleScript) that uses EventKit always had a "use Eventkit" type statement. I believe that this functionality is all part of the "binds" command.

I modified the foreign handler line to include the filesystem path to the framework based on some calls to windows dll's found on this forum:

Code: Select all

private foreign handler ObjC_EKEventStoreAlloc() returns optional ObjcID binds to :"objc:~system/library/frameworks/EventKit>EKEventStore.+alloc"
and it seems to work - phew!
best wishes
Skids

Post Reply

Return to “LiveCode Builder”