ertank
Members-
Content Count
246 -
Joined
-
Last visited
-
Days Won
1
Everything posted by ertank
-
Lots of errors when trying to compile an old project
ertank replied to ertank's topic in General Help
I have been using Delphi 1 until Delphi 7. Then I stop programming for long years and started again recently. Yes, they exists under project directory with DPR file itself. It is not about search paths. It is something with Delphi not able to cope with very fast drives or something else that I do not know. DPR file has following lines: uses Forms, UnitLogin in 'UnitLogin.pas' {Login}, UnitMainForm in 'UnitMainForm.pas' {MAINFORM}, Error is not on same file each time. It changes. I just give some examples there. However, it mostly stops either at first or second file defined in DPR. -
Hello, I am using Delphi 10.3.2. I used to parse date string "Tue 17 Sep 2019" in an e-mail message using VarToDateTime() which served its purpose well. Now, format changed to "Sunday, 22 September 2019" and that function is not so helpful as before. I am trying not to manually parse the string as it is due to change in the future, too. My questions are; 1- It is always possible one cannot see a simple solution. I appreciate if you can point me to right existing Delphi solution. I could not make StrToDate() working for me even with TFormatSettings provided and even with several different input strings like "22 September 2019", "22/September/2019", etc. 2- It would be great if anybody have a unit or a function he/she can share which handles provided date format like 'dddd, dd mmmm yyyy' and convert the input string to TDateTime using that given format. I do not know C#. I saw several examples of DateTime.ParseExact() which seems like what I am searching for. I might be completely wrong about that though. Thanks & regards, Ertan
-
String to Date conversion (yet another one)
ertank replied to ertank's topic in RTL and Delphi Object Pascal
Seems like initial code I share is faster than RegEx after initial call. Moreover, RegEx is failing at certain formats at the moment which will probably make it slower in all cases when all features added. Timing test code: program Project2; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, uUtils.ParseExact, System.RegularExpressions, System.Diagnostics; function Test(const Value: string; const fmtset: TFormatSettings): TDateTime; var pattern: string; match: TMatch; day: word; month: word; year: word; begin pattern := // '(' + string.Join('|', fmtset.LongDayNames) + ')' + // "dddd" ', ' + // ", " '(\d{2})' + // "dd" ' ' + // " " '(' + string.Join('|', fmtset.LongMonthNames) + ')' + // "mmmm" ' ' + // " " '(\d{4})'; // "yyyy" match := TRegEx.match(Value, pattern); if not match.Success then raise Exception.Create('Invalid data'); day := word.Parse(match.Groups.Item[2].Value); month := 1; while (month <= 12) and (fmtset.LongMonthNames[month] <> match.Groups.Item[3].Value) do inc(month); year := word.Parse(match.Groups.Item[4].Value); try Result := EncodeDate(year, month, day); except Result := 0; end; end; const Date1 = 'Sunday, 22 September 2019'; Date2 = 'Monday, 20 January 2018'; Date3 = 'Sun 15 Sep 2019'; var ADate: TDateTime; AFormatSettings: TFormatSettings; Timing: TStopWatch; begin try AFormatSettings := TFormatSettings.Create('en-US'); WriteLn('Long code timings'); Timing := TSTopWatch.StartNew(); ADate := TDateTime.ParseExact(Date1, 'dddd, dd mmmm yyyy', AFormatSettings); Timing.Stop(); WriteLn(DateToStr(ADate), 'Time: ' + Timing.Elapsed); Timing := TStopwatch.StartNew(); ADate := TDateTime.ParseExact(Date2, 'dddd, dd mmmm yyyy', AFormatSettings); Timing.Stop(); WriteLn(DateToStr(ADate), 'Time: ' + Timing.Elapsed); Timing := TStopwatch.StartNew(); ADate := TDateTime.ParseExact(Date2, 'dddd, dd mmmm yyyy', AFormatSettings); Timing.Stop(); WriteLn(DateToStr(ADate), 'Time: ' + Timing.Elapsed); Timing := TStopwatch.StartNew(); ADate := TDateTime.ParseExact(Date3, 'ddd dd mmm yyyy', AFormatSettings); Timing.Stop(); WriteLn(DateToStr(ADate), 'Time: ' + Timing.Elapsed); WriteLn('RegEx code timings'); Timing := TSTopWatch.StartNew(); ADate := Test(Date1, AFormatSettings); Timing.Stop(); WriteLn(DateToStr(ADate), 'Time: ' + Timing.Elapsed); Timing := TSTopWatch.StartNew(); ADate := Test(Date2, AFormatSettings); Timing.Stop(); WriteLn(DateToStr(ADate), 'Time: ' + Timing.Elapsed); Timing := TSTopWatch.StartNew(); ADate := Test(Date2, AFormatSettings); Timing.Stop(); WriteLn(DateToStr(ADate), 'Time: ' + Timing.Elapsed); Timing := TSTopWatch.StartNew(); ADate := Test(Date3, AFormatSettings); Timing.Stop(); WriteLn(DateToStr(ADate), 'Time: ' + Timing.Elapsed); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; ReadLn; end. My system output: Long code timings 22.09.2019Time: 00:00:00.0001696 20.01.2018Time: 00:00:00.0000132 20.01.2018Time: 00:00:00.0000157 15.09.2019Time: 00:00:00.0000134 RegEx code timings 22.09.2019Time: 00:00:00.0001281 20.01.2018Time: 00:00:00.0000404 20.01.2018Time: 00:00:00.0000255 Exception: Invalid data -
String to Date conversion (yet another one)
ertank replied to ertank's topic in RTL and Delphi Object Pascal
Only thing that maybe missing is "ddd" and "mmm" aka ShortDayNames and ShortMonthNames above. I find RegEx powerful. Unfortunately, I am not familiar with it at all. Would you add these two possible patterns in your sample code, please? -
String to Date conversion (yet another one)
ertank replied to ertank's topic in RTL and Delphi Object Pascal
Shared C# code conversion is out of my league. I would vote for such a function to be implemented in Delphi by Embarcadero though. For now, I have written something as following. My two versions are parsed OK with that. I might improve this code to have time part and to handle my possible fail cases in the future. I am not after very fast code at the moment. For now I will keep that one. unit uUtils.ParseExact; interface uses System.SysUtils; type TDateTimeHelper = record helper for TDateTime public class function ParseExact(const Value, Format: string; AFormatSettings: TFormatSettings): TDateTime; static; end; implementation procedure GetNumber(const InValue: string; out OutValue: Integer); var Finish: Integer; begin Finish := 1; while CharInSet(InValue.Chars[Finish], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']) do Inc(Finish); if not TryStrToInt(InValue.Substring(0, Finish), OutValue) then raise Exception.Create('Cannot convert to number'); end; class function TDateTimeHelper.ParseExact(const Value, Format: string; AFormatSettings: TFormatSettings): TDateTime; label Again; var Day: Integer; Month: Integer; Year: Integer; TempString: string; TempFormat: string; I: Integer; begin Result := 0; TempString := Value.ToLower(); TempFormat := Format.ToLower(); if TempFormat.Contains('mmm') or TempFormat.Contains('mmmm') then begin // month string literals converted to numbers for I := Low(AFormatSettings.LongMonthNames) to High(AFormatSettings.LongMonthNames) do begin TempString := TempString.Replace(AFormatSettings.LongMonthNames[I].ToLower(), I.ToString()); TempString := TempString.Replace(AFormatSettings.ShortMonthNames[I].ToLower(), I.ToString()); end; TempFormat := TempFormat.Replace('mmmm', 'mm'); TempFormat := TempFormat.Replace('mmm', 'mm'); end; if TempFormat.Contains('ddd') or TempFormat.Contains('dddd') then begin // day string literals are simply removed for I := Low(AFormatSettings.LongDayNames) to High(AFormatSettings.LongDayNames) do begin TempString := TempString.Replace(AFormatSettings.LongDayNames[I].ToLower(), EmptyStr); TempString := TempString.Replace(AFormatSettings.ShortDayNames[I].ToLower(), EmptyStr); end; TempFormat := TempFormat.Replace('dddd', EmptyStr); TempFormat := TempFormat.Replace('ddd', EmptyStr); end; TempFormat := TempFormat.Trim(); TempString := TempString.Trim(); Again: // remove non relevant chars at beginning while not CharInSet(TempFormat.Chars[0], ['a'..'z']) do begin TempFormat := TempFormat.Substring(1, MaxInt); TempString := TempString.Substring(1, MaxInt); end; if TempString.Length > 0 then begin case TempFormat[1] of 'd': begin if Day = 0 then GetNumber(TempString, Day); I := 0; while CharInSet(TempString.Chars[I], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', AFormatSettings.DateSeparator]) do Inc(I); TempString := TempString.Substring(I, MaxInt); TempFormat := TempFormat.Replace('dd', EmptyStr); goto Again; end; 'm': begin if Month = 0 then GetNumber(TempString, Month); I := 0; while CharInSet(TempString.Chars[I], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']) do Inc(I); TempString := TempString.Substring(I, MaxInt); TempFormat := TempFormat.Replace('mm', EmptyStr); goto Again; end; 'y': begin if Year = 0 then GetNumber(TempString, Year); I := 0; while CharInSet(TempString.Chars[I], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']) do Inc(I); TempString := TempString.Substring(I, MaxInt); goto Again; end; end; end; if (Day > 0) and (Month > 0) and (Year > 0) then begin try Result := EncodeDate(Year, Month, Day); except raise Exception.Create('uUtils.ParseExact(): Cannot encode.' + sLineBreak + sLineBreak + 'Year: ' + Year.ToString() + sLineBreak + 'Month: ' + Month.MaxValue.ToString() + sLineBreak + 'Day: ' + Day.ToString()); end; end else begin raise Exception.Create('uUtils.ParseExact(): Cannot parse all day, month and year'); end; end; end. Usage is as following: uses uUtils.ParseExact; var ADate: TDateTime; AFormatSettings: TFormatSettings; begin AFormatSettings := TFormatSettings.Create('en-US'); ADate := TDateTime.ParseExact('Sunday, 22 September 2019', 'dddd, dd mmmm yyyy', AFormatSettings); ShowMessage(DateToStr(ADate)); ADate := TDateTime.ParseExact('Sun 15 Sep 2019', 'ddd dd mmm yyyy', AFormatSettings); ShowMessage(DateToStr(ADate)); end; -
Hello, There is that WSDL here: http://messaging.yemeksepeti.com/messagingwebservice/integration.asmx?WSDL I need to read data from method named "GetRestaurantList" actually that is my starting method. I hopefully will need to use other methods later. I do not get exception on user level. But there is below error in Delphi while in debug run. First chance exception at $767DC762. Exception class ESOAPDomConvertError with message 'Conversion from class TList<System.IInterface> to SOAP is not supported - SOAP classes must derive from TRemotable'. Process YemekSepeti_WebServis.exe (9024) Here is the raw response from server: <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Body> <GetRestaurantListResponse xmlns="http://tempuri.org/"> <GetRestaurantListResult> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="RestaurantList"> <xs:element name="RestaurantList" msdata:IsDataSet="true" msdata:Locale=""> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="Restaurants"> <xs:complexType> <xs:sequence> <xs:element name="CatalogName" type="xs:string" minOccurs="0" /> <xs:element name="CategoryName" type="xs:string" minOccurs="0" /> <xs:element name="DisplayName" type="xs:string" minOccurs="0" /> <xs:element name="ServiceTime" type="xs:int" minOccurs="0" /> <xs:element name="Speed" type="xs:decimal" minOccurs="0" /> <xs:element name="Serving" type="xs:decimal" minOccurs="0" /> <xs:element name="Flavour" type="xs:decimal" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema> <diffgr:diffgram xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <RestaurantList xmlns=""> <Restaurants diffgr:id="Restaurants1" msdata:rowOrder="0"> <CatalogName>testname</CatalogName> <CategoryName>4f1cc1a8-bf2e-4eab-8dd5-34f37857911a</CategoryName> <DisplayName>Pizza, Test</DisplayName> <ServiceTime>45</ServiceTime> </Restaurants> </RestaurantList> </diffgr:diffgram> </GetRestaurantListResult> </GetRestaurantListResponse> </soap:Body> </soap:Envelope> Honestly, this is the first time I am reading such a response myself. Is there any way that I can consume that web service? Any help is appreciated. Thanks & regards, Ertan
-
I am not designing SOAP server side. It is a production server running for years. Very much likely that it is designed using Microsoft tools. I am to consume it using Delphi. I already did that. Using generated web service file, I am doing below request. <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Header> <NS1:AuthHeader xmlns:NS1="http://tempuri.org/"> <UserName xmlns="http://tempuri.org/">myuser</UserName> <Password xmlns="http://tempuri.org/">mypassword</Password> </NS1:AuthHeader> </SOAP-ENV:Header> <SOAP-ENV:Body> <GetRestaurantList xmlns="http://tempuri.org/" /> </SOAP-ENV:Body> </SOAP-ENV:Envelope> Response I get is already shared in my initial post. Web service consuming is not open to public. It has IP restrictions and so it will not help even if I share my login credentials to anybody for doing some tests. Problem as to my understanding is that, Delphi cannot parse response from server. I cannot suppress raised exception and such an exception stops me doing anything like trying to manually parse the raw XML as I always get a dialog displayed on the screen. That application I need to run headless and do web server requests in intervals automatically. An error message with a dialog stops me doing so.
-
Hello, I cannot compile latest revision of Indy using fpcupdeluxe. Below is log of errors I receive: Compiling Debug Version (1002) Target OS: Win64 for x64 (3104) Compiling indylaz.pas (3104) Compiling .\Core\IdAboutVCL.pas (3104) Compiling .\Core\IdDsnCoreResourceStrings.pas (1010) Writing Resource String Table file: IdDsnCoreResourceStrings.rsj (3104) Compiling .\System\IdGlobal.pas (3104) Compiling .\System\IdException.pas (3104) Compiling .\System\IdResourceStrings.pas (1010) Writing Resource String Table file: IdResourceStrings.rsj (3104) Compiling .\System\IdStream.pas (3104) Compiling .\System\IdStreamVCL.pas (3104) Compiling .\Core\IdAntiFreeze.pas (3104) Compiling .\System\IdAntiFreezeBase.pas (3104) Compiling .\System\IdBaseComponent.pas C:\fpcupdeluxe\ccr\indy\Lib\.\Core\IdAntiFreeze.pas(101,96) Error: (2021) ENDIF without IF(N)DEF C:\fpcupdeluxe\ccr\indy\Lib\.\Core\IdAntiFreeze.pas(103,91) Error: (2021) ENDIF without IF(N)DEF C:\fpcupdeluxe\ccr\indy\Lib\.\Core\IdAntiFreeze.pas(104,82) Error: (2021) ENDIF without IF(N)DEF C:\fpcupdeluxe\ccr\indy\Lib\.\Core\IdAntiFreeze.pas(112,83) Error: (2021) ENDIF without IF(N)DEF C:\fpcupdeluxe\ccr\indy\Lib\.\Core\IdAntiFreeze.pas(113,80) Error: (2021) ENDIF without IF(N)DEF C:\fpcupdeluxe\ccr\indy\Lib\.\Core\IdAntiFreeze.pas(114,81) Error: (2021) ENDIF without IF(N)DEF C:\fpcupdeluxe\ccr\indy\Lib\.\Core\IdAntiFreeze.pas(115,78) Error: (2021) ENDIF without IF(N)DEF C:\fpcupdeluxe\ccr\indy\Lib\.\Core\IdAntiFreeze.pas(118,91) Error: (2021) ENDIF without IF(N)DEF C:\fpcupdeluxe\ccr\indy\Lib\.\Core\IdAntiFreeze.pas(119,86) Error: (2021) ENDIF without IF(N)DEF C:\fpcupdeluxe\ccr\indy\Lib\.\Core\IdAntiFreeze.pas(121,12) Error: (2021) ENDIF without IF(N)DEF C:\fpcupdeluxe\ccr\indy\Lib\.\Core\IdAntiFreeze.pas(122,3) Fatal: (2003) Syntax error, "=" expected but ")" found Fatal: (1018) Compilation aborted Error: C:\fpcupdeluxe\fpc\bin\x86_64-win64\ppcx64.exe returned an error exitcode Error: (lazarus) Compile package indylaz 10.6.2: stopped with exit code 1 Error: (lazarus) [TLazPackageGraph.CompileRequiredPackages] "Exit code 1" Error: (lazarus) Building IDE: Compile AutoInstall Packages failed. make: *** [useride] Error 2 fpcupdeluxe: ERROR: UniversalInstaller (ConfigModule: indy): Failure trying to rebuild Lazarus. Details: ERROR: Fpcupdeluxe fatal error ! I checked IdAntiFreeze.pas, but it is slightly complicated IF conditionals in there for me. I do not have a spare VM with Delphi to test if it is compiled fine with Delphi. Using stock Indy delivered with Delphi installation for now. Thanks & regards, Ertan
-
That just worked. Thanks a lot.
-
Hello, You did not clarify if you need FMX or VCL or both in your question. I am using SMImport, SMExport suite from http://www.scalabium.com for years. Never had the need to look for another solution. They are VCL only.
-
Hello, There is an app ready to be put on App Store. That app was previously deployed using another development tool that I do not know. This will be an update for that successor. However, it cannot be deployed using Application Store configuration. As far as I can tell. MacOS already have deployment certificate installed. However, that cannot be seen in Delphi Project options->Deployment-Provisioning There is no problem on deploying using development configuration on a physical iPhone at all. There is no problem on deploying on Simulator as well. None of the documentation that we read so far helped us. There is no problem viewing development certificate on same options page. Any help is appreciated. Thanks & regards, Ertan
-
Following following steps, I finally can deploy for Application Store and have my IPA file generated. 1. revoke your active certificate in the provisioning portal 2. create new developer certificate (keychain access/.../request for csr...etc.) 3. download and install a new certificate 4. create a new provisioning profile for existing app id (on provisioning portal) 5. download and install new provisioning profile and in the build, settings set the appropriate code signing identities More details can be found at here: https://stackoverflow.com/questions/12867878/missing-private-key-in-the-distribution-certificate-on-keychain Thanks to everyone.
-
As it is explained, it is in the "menu" of Keychain application. Below screen capture is from my system. Highlighting the relevant menu item. Even if my system is not English, location should be same in your system.
-
There is such a menu item. Nothing is listed when I click on it. Seems I don't have any expired certificate at all. that makes sense as initially that app distributed by some other developer using some other development tool. However, I finally found reason. I go to Preferences under XCode menu item. Under accounts, I click Manage Certificates and below is what I see. Even if I have found reason, I still do not know how to fix that.
-
Actually, I already have a certificate linked to it. That same certificate is already loaded on MacOS, too. I see it in KeyChain. I am confused. Here is a screen shot:
-
Here is a screen shot from options page And here is error I receive when I click on "Deploy" button: No certificate found in provisioning profile "12021c75-fa17-4838-9834-39593ec234eb" Thanks.
-
App was distributed at least once (maybe more, I do not know) before. It is not developed and distributed using Delphi, before. There is a distribution certificate as far as I can tell on the MacOS. I will read linked steps and advise if they are of any help.
-
I see one "iPhone Distribution: <Company name>" in Keychain (under login, and My Certificates) and its expiration date is 16th of June 2020.
-
Hello, There is that custom build old DataSnap application. It works with Firebird database and only provides 3 methods; GetData, ExecuteQuery, SwitchDatabase. Their use is as their names indicate. All of the methods are called in a single long URL such as datasnapserver/GetData/SELECT * FROM EMPLOYEE That returns SQL result as JSON string. Other 2 methods simply return True/False and error message if False. As the nature of the GetData method, it sometimes gets quite long and complicated URL including all that JOINs, WHERE and conditions added. I wonder if similar can be done using MARS, and have it handle returned data to be filled in a memory table. This maybe a long shot, but I also would like to put all these SQLs in body of the GET request, if such a thing is possible. Thanks.
-
I knew that there has to be an easier way. That did work nicely. I have one question standing in my mind. As I know current code in mobile app, I may need to make synchronous calls to server, just because to let user know there is something going on at the moment (screen wait text is changing with each SQL command run). I appreciate an example on a synchronous call, please. I am starting to implement my UPDATE/INSERT/DELETE handling now. I believe that will be easier having all these SELECT working. They will reply as a simple True/False after all. Thank you.
-
It will be easier for me to use any preferred http component on client side. I am going to have one dataset per request, always. Now, I have some JSON received at client like following: [ { "EMP_NO": 2, "FIRST_NAME": "Robert", "LAST_NAME": "Nelson", "PHONE_EXT": "250", "HIRE_DATE": "1988-12-28T00:00:00.000+02:00", "DEPT_NO": "600", "JOB_CODE": "VP", "JOB_GRADE": 2, "JOB_COUNTRY": "USA", "SALARY": 105900, "FULL_NAME": "Nelson, Robert" }, { "EMP_NO": 4, "FIRST_NAME": "Bruce", "LAST_NAME": "Young", "PHONE_EXT": "233", "HIRE_DATE": "1988-12-28T00:00:00.000+02:00", "DEPT_NO": "621", "JOB_CODE": "Eng", "JOB_GRADE": 2, "JOB_COUNTRY": "USA", "SALARY": 97500, "FULL_NAME": "Young, Bruce" } ] In brief, I am getting what I want. Now, I would like to make life much easier on client side to manipulate that data and decrease lines of code. That is if such a thing is possible... As this is a simple JSON string, there is no datatype information like TDateTime, Integer, Double, etc. Is it possible to receive raw memory table data which contains all necessary information to build back easily TDataSet or TFDMemTable at client side? My current server code is as following: unit Server.Resources; interface uses SysUtils, Classes, MARS.Core.Attributes, MARS.Core.MediaType, MARS.Core.JSON, MARS.Core.Response, MARS.Core.URL, MARS.Core.Token.Resource, Data.DB, MARS.Data.FireDAC, FireDAC.Phys.FB; type TStatement = record SQL: string; Name: string; end; [Path('helloworld')] THelloWorldResource = class protected [Context] FD: TMARSFireDAC; public [POST, Produces(TMediaType.APPLICATION_JSON)] function GetData([BodyParam] AStatement: TStatement): TDataSet; end; [Path('token')] TTokenResource = class(TMARSTokenResource) end; implementation uses MARS.Core.Registry; { THelloWorldResource } function THelloWorldResource.GetData(AStatement: TStatement): TDataSet; begin Result := FD.SetName<TDataSet>(FD.Query(AStatement.SQL), AStatement.Name); end; initialization TMARSResourceRegistry.Instance.RegisterResource<THelloWorldResource>; TMARSResourceRegistry.Instance.RegisterResource<TTokenResource>; end. I already tried and failed to convert [POST, Produces(TMediaType.APPLICATION_JSON)] to [POST, Produces(TMediaType.APPLICATION_JSON_FireDAC)] which I suppose is what I need to achieve above. I solved one error and that lead to another one. Just could not solve them all. Again, this is a Delphi to Delphi solution. Client here is FMX mobile. Data is for reporting purposes and it is read-only on client. Thanks for all your help. Regards, Ertan
-
Hello, Thanks for step by step instructions. I am informed that I do not need multiple SQL results to be returned at once. So I choose not to use an array here. That will be a "Delphi to Delphi" solution. I would like to use MARS Client for requests. I have following setup in DataModule: MARSApplication -> MARSClient1 -> MARSFDResource1 One question here: How should I set POST BODY (TStatement) before I call MARSFDResource1.POST() or MARSClient1.Post()? I am not even sure which component to use for doing post request here. I would like MARSFDResource1 to fill up TFDMemTable right after receiving response. Sorry for all these newbie questions. I hope some other new starters will benefit in the future 🙂 Thanks & regards, Ertan
-
Hello, I am asked for some raw data including header and body between a rest server and android mobile app. My search on internet lead me to use TIdLogEvent (I am not sure that is the right component for job. Since I do communication in a thread, I select to create everything using code at run-time. I have following procedures to be assigned at run-time procedure TfrmMain.IdLogEvent1Received(ASender: TComponent; const AText, AData: string); var Filename: string; begin Filename := TPath.Combine(TPath.GetSharedDocumentsPath(), 'response_'); Filename := Filename + FormatDateTime('yyyy-mm-dd_hh.nn.ss', Now()) + '.log'; TFile.WriteAllText(Filename, AData); end; procedure TfrmMain.IdLogEvent1Sent(ASender: TComponent; const AText, AData: string); var Filename: string; begin Filename := TPath.Combine(TPath.GetSharedDocumentsPath(), 'request_'); Filename := Filename + FormatDateTime('yyyy-mm-dd_hh.nn.ss', Now()) + '.log'; TFile.WriteAllText(Filename, AData); end; I am trying to create TIdHTTP and others in a thread as following: var NewsRec: TGetNewsRequest; Json: string; SS: TStringStream; Http: TIdHTTP; IOHandler: TIdIOHandlerStack; LogEvent: TIdLogEvent; Response: string; ResponseRec: TGetNewsResponse; begin // some non-relevant code for json preperation, etc. deleted Http := nil; IOHandler := nil; SS := nil; LogEvent := nil; try SS := TStringStream.Create(Json); LogEvent := TIdLogEvent.Create(nil); LogEvent.OnSent := frmMain.IdLogEvent1Sent; LogEvent.OnReceived := frmMain.IdLogEvent1Received; Http := TIdHTTP.Create(nil); IOHandler := TIdIOHandlerStack.Create(Http); Http.IOHandler := IOHandler; Http.IOHandler.Intercept := LogEvent; Http.Request.ContentType := 'application/x-www-form-urlencoded'; Response := Http.Post(GetNewsURL, SS); // try..except removed to simplify code finally LogEvent.Free(); Http.Free(); SS.Free(); end; // some non-relevant code to deal with result deleted end; Communication is not secured. It is plain "http". I could not figure what I am doing wrong as I always get Abstract error. That stands true no matter I assign to TIdHTTP.IOHandler be it TIdIOHandler, TIdIOHandlerSocket, TIdIOHandlerStack. I cannot get past to that error and save raw communication dumped in log files. Any help is appreciated. Thank & regards, Ertan
-
Yes. It is clear now. Converted to TFile.AppendText and changed filename not to include seconds. I most of the time do not change stock Indy version if there is a reason to. I am using Delphi 10.3.1 installed Indy on my system and there is no version mixing or similar. That was missing. Now logging is working fine. Thanks.
-
That is the first time I am dealing with raw logging using Indy. I will have a look at it if they are to stay in the app for long. All this I am trying to log is only for checking some headers for web service developers. Thanks for the warning. There are not many calls to web service done. Logs needed after something like button click or similar. I received that abstract error maybe because I tried to use TIdHTTP.IOHandler.Intercept and not TIdHTTP.Intercept? This is something I read in one of the Indy 10.0.0.50 version or similar post that I found. I did not understand why abstract error received and so I wrote in here thinking there maybe changes from the time of that posts to Indy 10.6.2.xxxx Now, project compile and run fine using your sample code. There is no abstract error. However, unseen part of the code is that I am always receiving "Connection closed gracefully" exception on debug run in thread. There are no files saved, too. When debugging execution does not come in assigned TIdLogEvent.OnSent() or TIdLogEvent.Received() functions. I could not understand why there is such an exception. Web service is built with PHP. Laravel v5.8 or something used as I am told. I do not know PHP and web service developers cannot answer most of my questions, unfortunately. That ContentType is also enforced by that PHP developers to me. I started using that TStrings overloaded function at the beginning. That did not work with that web services. Framework exception or no communication happens. Above code could communicate. But, it does not log raw communication data.