Jump to content
Sign in to follow this  
kabiri

The problem of running the app on IOS

Recommended Posts

I had an app that works well on Android and Windows.

I added the IOS platform yesterday. But the program remains on the splash screen.

 

uses
  System.StartUpCopy,
  FMX.Forms,
  untMain in 'untMain.pas' {frmMain},
  untDataModule in 'untDataModule.pas' {frmDataModule: TDataModule},
  untAddTitle in 'untAddTitle.pas' {frmAddTitle: TFrame},
  untCategoryList in 'untCategoryList.pas' {frmCategory: TFrame},
  untPlay in 'untPlay.pas' {frmPlay},
  {$IFDEF android}
  Androidapi.JNI.Toast in 'Androidapi.JNI.Toast.pas',
  {$endif}
  untServerCategory in 'untServerCategory.pas' {frmServerCategory},
  untReport in 'untReport.pas' {frmReport},
  untSelectCategoryList in 'untSelectCategoryList.pas' {frmSelectCategoryList},
  untCategoryItem in 'untCategoryItem.pas' {frmCategoryItem: TFrame},
  untHelp in 'untHelp.pas' {frmHelp};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TfrmDataModule, frmDataModule);
  Application.CreateForm(TfrmMain, frmMain);
  Application.CreateForm(TfrmPlay, frmPlay);
  Application.CreateForm(TfrmServerCategory, frmServerCategory);
  Application.CreateForm(TfrmSelectCategoryList, frmSelectCategoryList);
  Application.CreateForm(TfrmHelp, frmHelp);
  Application.Run;
end.

All FormCreate events except frmMain are executed.

 

When I change the main form in the project settings and select another form, it displays that form.

err4.png

Share this post


Link to post
  1. verify if any component is trying access your database - verify DB connection if true on design-time or in some place?
  2. it's preferable dont create all forms/datamodules automatically! try create it after main-form on memory!
Edited by programmerdelphi2k

Share this post


Link to post

It's not advisable to have conditionals in your .dpr because the IDE can be prone to mess it up. In this case, the conditional for the Android unit is pointless anyway, since nothing from it is being referenced in the .dpr. This would not be the cause of your issue, but it's still something to consider.

 

As @programmerdelphi2k inferred, it may be being caused by something happening in untDataModule. You could use the debugger to see what is executed there when it is created.

 

Has it ever run OK on iOS? Either way, you could remove parts of the application that were previously added, to help isolate what is causing the lockup.

 

Share this post


Link to post
7 hours ago, programmerdelphi2k said:

verify if any component is trying access your database - verify DB connection if true on design-time or in some place?

DB is created at runtime and does not exist at design time. But to be sure, I checked its connection value is False.

In TfrmMain.FormCreate and TfrmMain.FormShow TfrmMain.FormActivate events, I have nothing to do with the database.

 

7 hours ago, programmerdelphi2k said:

it's preferable dont create all forms/datamodules automatically! try create it after main-form on memory!

begin
  Application.Initialize;
  Application.CreateForm(TfrmMain, frmMain);
  Application.Run;
end.
procedure TfrmMain.FormCreate(Sender: TObject);
begin
  //Application.Create(TfrmDataModule, frmDataModule);
  frmDataModule:=TfrmDataModule.Create(self);
  isEmpty:=True;

I gave these changes and it didn't make any difference.

Line frmDataModule:=TfrmDataModule.Create(self); I deleted
Now it displays the main form, but breakpoints are still disabled.

Share this post


Link to post

 

8 minutes ago, kabiri said:

Line frmDataModule:=TfrmDataModule.Create(self); I deleted
Now it displays the main form

So the problem is with the datamodule.

8 minutes ago, kabiri said:

but breakpoints are still disabled.

Still? The screenshot you showed in an earlier message indicates they were not. Are you compiling for Debug?

Share this post


Link to post

The previous post was about 2 hours ago, I don't know why it was not sent!

 

@Dave Nottage & @programmerdelphi2k Thankful
Yes, I had tried the blank project, it work.

One of the problems is that the main file is not debugged.

I first tested the things I knew, then I asked a question here because I couldn't debug.

I don't know why unit main is not traceable and debug is disabled only in this form.

Share this post


Link to post
3 minutes ago, Dave Nottage said:

Still? The screenshot you showed in an earlier message indicates they were not. Are you compiling for Debug?

Yes, it is in debug mode. Breakpoint works in other forms, but it does not work in this form(frmMain/untMain)

 

6 minutes ago, Dave Nottage said:

So the problem is with the datamodule.

What could be the problem that only happens on IOS?

Share this post


Link to post
1 minute ago, kabiri said:

Breakpoint works in other forms, but it does not work in this form(frmMain/untMain)

There's a difference between a breakpoint being disabled (which is indicated visually), versus one where the debugger does not stop. The latter can happen because the code where you have the breakpoint is never reached and/or you have a unit with the same name, and you're looking at the wrong one.

4 minutes ago, kabiri said:

What could be the problem that only happens on IOS?

Something specific to the platform. Detailing what you have in your datamodule might help (eg. data components used, what type of connection e.g SQLite, etc)

Share this post


Link to post
18 minutes ago, Dave Nottage said:

Something specific to the platform. Detailing what you have in your datamodule might help (eg. data components used, what type of connection e.g SQLite, etc)

In the DataModuleCreate function, if the sqlite database and tables do not exist, they are created. This part apparently runs without errors because it works correctly during debugging and the first time it creates the tables and inserts the default value, and the second time the app is run it receives the information from the tables correctly.

 

18 minutes ago, Dave Nottage said:

There's a difference between a breakpoint being disabled (which is indicated visually), versus one where the debugger does not stop. The latter can happen because the code where you have the breakpoint is never reached and/or you have a unit with the same name, and you're looking at the wrong one.

If I put breakpoints in all lines of unit main, it doesn't make any difference and the execution doesn't stop at breakpoints.

Share this post


Link to post
8 minutes ago, kabiri said:

If I put breakpoints in all lines of unit main, it doesn't make any difference and the execution doesn't stop at breakpoints.

If the breakpoints are not disabled - ie like this:

 

image.thumb.png.9ce182d474d5fccb0693eaa10bb210a7.png

 

Then the code isn't being reached.

14 minutes ago, kabiri said:

This part apparently runs without errors because it works correctly during debugging...

Yet when you removed that part, the code in unit main executes?

This is where a reproducible example would help.

Share this post


Link to post
uses
  uDMMain;

var
  MyDM_on_Init_Section: TMyDataModule; // You wouldn't need this variable if you were going to use the global var "MyDataModule"

procedure TForm1.FormCreate(Sender: TObject);
begin
  // using global "var" on "uDMMain.pas"
  MyDataModule := TMyDataModule.Create(nil); // called: 2º
  //
  if (MyDM_on_Init_Section <> nil) then // accessing objects from "MyDM_on_Init_Section"
    MyDM_on_Init_Section.FDConnection1.LoginPrompt := false;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  // try comment this lines...
  MyDataModule.Free;   // called: 3º
  MyDataModule := nil; // avoid "AV" on "finalization section"... "Free" dont release pendent pointers on memory!
end;

initialization

MyDM_on_Init_Section := TMyDataModule.Create(nil); // called: 1º

finalization

MyDM_on_Init_Section.Free; // called: 4º
//
if (MyDataModule <> nil) then // if on memory and "valid object"...
  MyDataModule.FDConnection1.LoginPrompt := false;

 

Edited by programmerdelphi2k

Share this post


Link to post

I will check again.

But my breakpoints work on Android and Windows.

I've used global variables and functions elsewhere and it's unlikely that they were removed by the compiler optimizer.

 

windows:

err5.png

 

IOS:

err6.thumb.png.f964ea17211455ed45cf1d76a620eca6.png

err7.thumb.png.5df9c9bcb640487dcfe1f3f65c78a0b5.png

err8.png.7b4010356bc209eaf4ea5e6f3942cee5.png

Edited by kabiri

Share this post


Link to post

Maybe the problem is Delphi.
Because I recently had several problems with the IDE (especially after installing the patch).

 

The back button does not work in the toolbar

err10.png.deb2a3724f6ab0e90ace81f53403fb06.png

 

Also these buttons. I use a shortcut:

err11.png.ad5c32215ded8dda7a7d36dc51f10b8f.png

 

Sometimes I see the selection form like this in the settings:

err9.thumb.png.665abc08c850c671c16220f991facdd0.png

 

When I change the platform in the toolbar, it does not change in the project manager panel. Exactly like this:

https://quality.embarcadero.com/browse/RSP-30799?jql=text ~ "select platform"

Share this post


Link to post
10 hours ago, Dave Nottage said:

Yet when you removed that part, the code in unit main executes?

No, It does not run

Share this post


Link to post
1 hour ago, kabiri said:

No, It does not run

Earlier, you said:

12 hours ago, kabiri said:

Line frmDataModule:=TfrmDataModule.Create(self); I deleted
Now it displays the main form

If it does not run, the main form would not be displayed

Share this post


Link to post
On 12/22/2022 at 1:40 PM, Dave Nottage said:

Earlier, you said:

Sorry, I forgot that

 

I rewrote untMain from scratch and it only has the TfrmMain.FormCreate event. Now the breakpoint works.
Now the event time of TfrmDataModule.DataModuleCreate ends, the program stops in the System.Generics.Collections unit, I have not put a breakpoint here.

I didn't understand anything from Call Stack which routine made me go here

 

err13.thumb.png.6aecf1594f12b265926e6c1223468603.png

 

Share this post


Link to post
48 minutes ago, programmerdelphi2k said:

what is done (code) on DM.Create(...)?

Yes

Share this post


Link to post

Create database :

 

procedure TfrmDataModule.DataModuleCreate(Sender: TObject);
var
  DBN: string;
  NewDb: Boolean;
  pth: string;
  applayUpdate: Boolean;
  newVersion: Integer;
begin

  DBCon:=TFDConnection.Create(Self);
  qryTmp.Connection:=DBCon;
  newVersion := 14;
  DBN := 'myDB.db3';



{$IF Defined(MSWINDOWS)}
  pth := ExtractFilePath(ParamStr(0)) + DBN;
{$ENDIF}

{$IF Defined(ANDROID)}
  pth := GetHomePath + '/' + DBN;
{$ENDIF}
{$IF Defined(IOS)}
  pth := TPath.Combine(TPath.GetDocumentsPath, DBN);
{$ENDIF}
  DBCon.Close();
  DBCon.DriverName := 'SQLite';
  with DBCon.Params as TFDPhysSQLiteConnectionDefParams do
  begin
    DriverID:='SQLite';
    Database:=pth;
    Password:='159753';
    Encrypt:=TFDSQLiteEncrypt.enAes_256;
  end;

  if not FileExists(pth) then
  begin
    NewDb := True;
  end
  else
  begin
    NewDb := False;
  end;
  DBCon.Open;

{$REGION 'Database'}
  if NewDb then
  begin
    qryTmp.SQL.Clear;
    qryTmp.SQL.Add
      ('CREATE TABLE [Category] ([ID] INTEGER PRIMARY KEY AUTOINCREMENT');
    qryTmp.SQL.Add(',[ServerCategoryID] INTEGER');
    qryTmp.SQL.Add(',[FreeDownload] INTEGER');
    qryTmp.SQL.Add(',[Name] NVARCHAR(200) NOT NULL);');
    try
      qryTmp.ExecSQL;
    except
    end;

    .

    .

    .

    //other tables

    qryTmp.SQL.Clear;
    qryTmp.SQL.Add('insert into version (ver) values (' +
      inttostr(newVersion) + ')');
    try
      qryTmp.ExecSQL;
    except
    end;

    FirstRun := True;

  end
  else
  begin
    FirstRun := False;
    applayUpdate := False;
    //update table here for example

    if Version <= 13 then
    begin
      qryTmp.SQL.Clear;
      qryTmp.SQL.Add('alter TABLE Category add COLUMN [FreeDownload] INTEGER;');
      try
        qryTmp.ExecSQL;
      except
      end;

      qryTmp.SQL.Clear;
      qryTmp.SQL.Add('update Category set FreeDownload=1');
      try
        qryTmp.ExecSQL;
      except
      end;

      qryTmp.SQL.Clear;
      qryTmp.SQL.Add('CREATE TABLE WorkTime(');
      qryTmp.SQL.Add('[Date_] string(10)');
      qryTmp.SQL.Add(',[TimeInSec] INTEGER);');
      try
        qryTmp.ExecSQL;
      except
      end;

      applayUpdate := True;
    end;

    if applayUpdate then
    begin
      qryTmp.SQL.Clear;
      qryTmp.SQL.Add('update version set ver=' + inttostr(newVersion));
      try
        qryTmp.ExecSQL;
      except
      end;
    end;

  end;

  GetDefaltCategory;
  //GetTotalTime;
end;
Edited by kabiri

Share this post


Link to post

NOTE: SQLite allow "create database/table" in your SQL instruction!!! no needs workaround!!

Quote

CREATE TABLE IF NOT EXISTS TABLE_NAME (column_name datatype, column_name datatype);

var { ... any place visible for all tables (in any form) tasks! }
  FDConn: TFDConnection;

procedure MyCreateFDConn; // any place visible!!!
begin
  FDConn             := TFDConnection.Create(nil); // release when no more necessary... in any place on project!
  FDConn.LoginPrompt := false;                     // avoid show default dialog!!!
  FDConn.Params.Clear;
  // verify your PATH it's ok for found DB on smartphone!!!
  FDConn.Params.Add('...');
  // or
  FDConn.Params.AddStrings(['...', '...']);
  // ...
end;

procedure TForm1.FormCreate(Sender: TObject); // just for my tests... Adapt it for your case!
var
  FDQry: TFDQuery;
begin
  //
  FDQry := TFDQuery.Create(nil);
  try
    FDQry.Connection := FDConn;
    FDQry.Open('...your Select statement');
    // or
    FDQry.ExecSQL('...your Insert, Delete, Update statement');
  finally
    FDQry.Free; // when it's not more necessary!!! if used in many places, then, use a "global var"... if you want! or not!
  end;
end;

initialization // if used on first unit of your project and used for all units

MyCreateFDConn;

finalization

FDConn.Free;

end.

 

Edited by programmerdelphi2k

Share this post


Link to post

NOTE:

  • you are using a "DataModule" then, there is not necessity create a "FDConnection" by code! just use a component FDConnection!
  • same to "FDQuery"... just use a component with no-statement SQL!
    • close, change the sql, open!
      • if needs in many place, then, use another FDQuery!
  • that way, you avoid create and kill it all time!

 

look my sample using SQLite

https://mega.nz/file/T34mlZ7J#L-wpnR2kes5NU9cRyTD1dYMmYLKq4EtroWETVjwYfuk

Edited by programmerdelphi2k
  • Thanks 1

Share this post


Link to post
17 hours ago, programmerdelphi2k said:
  • you are using a "DataModule" then, there is not necessity create a "FDConnection" by code! just use a component FDConnection!

Yes , i khow. but when a put TFDConnection on the form delphi add "FireDAC.VCLUI.Wait" to DataModule unit!!!

I add FireDAC.FMXUI.Wait myself, but it didn't help. That's why I didn't put the component on the form.

This code is also {%CLASSGROUP 'FMX.Controls.TControl'} in the unit.

I even created a new form Datamodule and it was the same.

Edited by kabiri

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×