Search code examples
iosdelphiframeworksfiremonkey

How to obtain CFStringRef value from iOS API function in Delphi 10.3 Rio


Cannot obtain CFStringRef value from iOS API function (framework) in Delphi 10.3 Rio

// external call bridge function to iOS:
function MIDIObjectGetStringProperty(obj: MIDIObjectRef;
            propertyID: CFStringRef;
            out str: CFStringRef):OSStatus; cdecl; external libCoreMidi name _PU + 'MIDIObjectGetStringProperty'; 

Function MIDIObjectGetStringProperty (iOS CoreMIDI function) return in str:CFStringRef name of MIDI ports ...

How can I obtain value of CFString variable in Delphi? In this example str:CFStringRef value?

I try it in my func.:

function getDisplayName(obj: MIDIEndpointRef):string;
var 
    EndPointName: CFStringRef;
    i:integer;
begin
    //EndPointName:= nil; // when I assign nil value, function return i=-50 otherwise raise Access Violation error ...

    i := MIDIObjectGetStringProperty(obj, kMIDIPropertyDisplayName , EndPointName); --> AV error !!!

    //in EndPointName should be returned CFStringRef value from iOS 

    getDisplayName :=  CFToDelphiString(EndPointName); // convert to string
end;

Probably EndPointName need to be allocated ... else I give AV error. Please got someone solution how obtain ANY CFStringRef value from iOS framework and convert to string? Thanx.

Adds:

I build crossplatform (iOS, Android, W64) app in Delphi Rio via FireMonkey frameforks api - for CoreMIDI I use this interface https://github.com/FMXExpress/ios-object-pascal-wrapper/blob/master/iOSapi.CoreMIDI.pas

So the externall call and constants are defined in iOSapi.CoreMIDI there:

function MIDIObjectGetStringProperty (obj: MIDIObjectRef; propertyID: CFStringRef; str: CFStringRef) : OSStatus; cdecl; external libCoreMIDI name _PU + 'MIDIObjectGetStringProperty';

and iOS pointer const:

function kMIDIPropertyDisplayName: Pointer;
begin
  Result := CocoaPointerConst(libCoreMIDI, 'kMIDIPropertyDisplayName');
end;

Otherwies compiled app work on real iOS (iPad) very well (reading MIDI message from connected MIDI keyboard) based on this solution https://pjstrnad.com/reading-data-midi-keyboard-ios-probably-also-mac/

obj: MIDIObjectRef is source pointer from source:= MIDIGetSource(ci);

Problem is calling API function MIDIObjectGetStringProperty. In pointer str: CFStringRef (EndPointName) should be VALUE of MIDIportNAME. I cannot obtain this value and parse to delphi string ...

I tried declared this poiter CFStringRef as:

var
EndPointName: pointer;
EndPointName1: array of Byte;
EndPointName2: TBytes;
EndPointName3: TPtrWrapper;
M: TMarshaller;

and construction as:

SetLength(EndPointName1, 255);
GetMem(EndPointName2,255);
EndPointName3 := M.AllocMem(255);

i := MIDIObjectGetStringProperty(obj, kMIDIPropertyDisplayName , @EndPointNameX);

--> nothing works, AV error !!!

I thing it must be solution how to obtain CFStringRef and convert to delphi string ...


Solution

  • The kMIDIPropertyDisplayName is broken on iOS, but you can replace it with CFSTR('displayName'). It works for me. So your function looks like this:

    function getDisplayName(aEndPointRef: MIDIEndpointRef):string;
    var 
      LEndPointName: CFStringRef;
      i:integer;
    begin
      getDisplayName := 'MIDI endpoint';
      LEndPointName:= nil; 
      i := MIDIObjectGetStringProperty(aEndPointRef, CFSTR('displayName'), LEndPointName);
      if (i=0) and (LEndPointName<>nil) then
        getDisplayName := CFStringRefToStr(LEndPointName);
    end;
    

    Add Macapi.CoreFoundation and Macapi.Helpers to your USES clause to get access to CFSTR and CFStringRefToStr