Lazarus

Programming => Operating Systems => macOS / Mac OS X => Topic started by: trev on December 31, 2019, 07:14:03 am

Title: [SOLVED] initWithURL() - wrong number of parameters :(
Post by: trev on December 31, 2019, 07:14:03 am
Code: Pascal  [Select][+][-]
  1. unit Unit2;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$modeswitch objectivec1}
  5. {$linkframework AVFoundation}
  6.  
  7. interface
  8.  
  9. uses
  10.   Classes, Dialogs, CocoaAll, MacOSAll;
  11.  
  12. type
  13.   AVAudioRecorder = objcclass external(NSObject)
  14.   ...
  15.   end;
  16.  
  17. var
  18.   MyAudioRecorder : AVAudioRecorder = Nil;
  19.  
  20. implementation
  21. ...
  22. procedure RecordAudio(audioFileName : NSString);
  23. var
  24.   path : NSString;
  25.   url : NSURL;
  26.   settings: NSDictionary;
  27.   err : NSError;
  28. begin
  29.   ...
  30.   MyAudioRecorder := AVAudioRecorder.alloc.initWithURL(url, settings, @err);
  31.  

Code: [Select]
Compile Project, Target: MyApp: Exit code 1, Errors: 2
unit2.pas(50,76) Error: Wrong number of parameters specified for call to "initWithURL"
NSBundle.inc(38,14) Error: Found declaration: initWithURL(NSURL):^objc_object;

Where am I going wrong?
Title: Re: initWithURL() - wrong number of parameters :(
Post by: skalogryz on December 31, 2019, 07:42:27 am
try this:
Code: Pascal  [Select][+][-]
  1. MyAudioRecorder := AVAudioRecorder(AVAudioRecorder.alloc).initWithURL(url, settings, @err);
or
Code: Pascal  [Select][+][-]
  1. MyAudioRecorder := AVAudioRecorder.alloc.initWithURL_settings_error(url, settings, @err)

method alloc() returns id type. FPC compiler allows to call of ANY ObjC declared method to be called for "id" type.
initWithURL: exists at NSURLRequest class. And it seems that the compiler is trying to use this particular type (as it only accepts 1 parameter).

AVAudioRecorder doesn't have "initWithURL:" instead it has two methods "initWithURL:settings:error:" and "initWithURL:format:error:". Those are typically converted as:
initWithURL_settings_error() and initWithURL_format_error() respectivly


Title: Re: initWithURL() - wrong number of parameters :(
Post by: trev on December 31, 2019, 03:06:36 pm
1. Yields: unit1.pas(311,61) Error: Identifier idents no member "initWithURL"

2. Yields: unit1.pas(312,44) Error: Method identifier expected
              unit1.pas(312,70) Fatal: Syntax error, ";" expected but "(" found

Title: Re: initWithURL() - wrong number of parameters :(
Post by: skalogryz on December 31, 2019, 03:12:14 pm
then
Code: Pascal  [Select][+][-]
  1. MyAudioRecorder := AVAudioRecorder.alloc.initWithURL_settings_error(url, settings, @err);
?

what's the full declaration of
Code: Pascal  [Select][+][-]
  1. AVAudioRecorder = objcclass external(NSObject)
  2.   ...
  3. end;
?
Title: Re: initWithURL() - wrong number of parameters :(
Post by: trev on January 01, 2020, 05:11:43 am
then
Code: Pascal  [Select][+][-]
  1. MyAudioRecorder := AVAudioRecorder.alloc.initWithURL_settings_error(url, settings, @err);
?

As above: unit1.pas(312,44) Error: Method identifier expected
               unit1.pas(312,70) Fatal: Syntax error, ";" expected but "(" found

Quote
what's the full declaration of
Code: Pascal  [Select][+][-]
  1. AVAudioRecorder = objcclass external(NSObject)
  2.   ...
  3. end;
?

Code: Pascal  [Select][+][-]
  1. AVAudioRecorder = objcclass external(NSObject)
  2.   public
  3.     function avrecord: Boolean; message 'record';
  4.     function prepareToRecord: Boolean; message 'prepareToRecord';
  5.     procedure pause; message 'pause';
  6.     procedure stop; message 'stop';
  7.     function deleteRecording: Boolean; message 'deleteRecording';
  8.     function isRecording: Boolean; message 'isRecording';
  9.   end;        
  10.  
Title: Re: initWithURL() - wrong number of parameters :(
Post by: skalogryz on January 01, 2020, 09:59:50 pm
let's add a missing method then
Code: Pascal  [Select][+][-]
  1.   AVAudioRecorder = objcclass external(NSObject)
  2.   public
  3.     function avrecord: Boolean; message 'record';
  4.     function prepareToRecord: Boolean; message 'prepareToRecord';
  5.     procedure pause; message 'pause';
  6.     procedure stop; message 'stop';
  7.     function deleteRecording: Boolean; message 'deleteRecording';
  8.     function isRecording: Boolean; message 'isRecording';
  9.     function initWithURL_settings_error(url: NSURL; settings: NSDictionary; error: Pointer): id; message 'initWithURL:settings:error:';
  10.     //function initWithURL_format_error(url: NSURL; format: AVAudioFormat; error: Pointer): id; message 'initWithURL:format:error:';
  11.   end;
  12.  
Notes:
* I commented out initWithURL_format_error, because it requires AVAudioFormat to be declared as well.
* it's better to have error parameter to be declared as PNSError (where PNSError = ^NSError). But PNSError is not declared in CocoaAll, so we go just by a raw pointer
Title: Re: initWithURL() - wrong number of parameters :(
Post by: trev on January 02, 2020, 01:46:07 am
Thanks Dmitry - I eventually figured out that I needed to add the missing method in a moment of realising the blinding obvious after you asked for the class methods!

I added this method which I found hiding away in /usr/local/share/fpcsrc/fpc-3.3.1/packages/cocoaint/src/avfoundation/AVAudioRecorder.inc:

{Edit: I replaced InstanceType with id}

Code: [Select]
function initWithURL_settings_error (url: NSURL; settings: NSDictionary; outError:
  NSErrorPtr):id; message 'initWithURL:settings:error:';

and it compiles ... now I just need to buy a microphone to test whether it will record :)
Title: Re: [SOLVED] initWithURL() - wrong number of parameters :(
Post by: trev on January 09, 2020, 02:45:55 am
Reporting a happy ending: having now acquired a USB microphone for my Mac mini, I can now report that the code not only compiles but actually works. Full details now in the Wiki at: https://wiki.freepascal.org/macOS_Audio_Recorder

TinyPortal © 2005-2018