Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   PListPatcher für die iOS-Entwicklung (https://www.delphipraxis.net/179507-plistpatcher-fuer-die-ios-entwicklung.html)

Union 11. Mär 2014 17:22


PListPatcher für die iOS-Entwicklung
 
Liste der Anhänge anzeigen (Anzahl: 1)
Wenn man für seine mit Firemonkey für iOS entwickelten Apps zusätzliche Einstellungen benötigt, musste man bisher die durch die IDE erstellte plist anpassen und im Bereitstellungmanager als separaten Eintrag hinzufügen. Und dies natürlich jedes Mal wiederholen, wenn man im Projekt Einstellungen geändert hat, die sich ebenfalls in der plist niederschlagen sollen (Icons, Versionsnummer usw.).

Um das zu vereinfachen, habe ich diesen PlistPatcher erstellt. Sehr primitiv aber funktioniert. Er muß in den Post-Build-Einstellungen in der IDE eingebunden werden, z.b.:
Code:
PlistPatcher.exe ".\$(Platform)\$(Config)\$(ProjectName).info.plist" "$(ProjectDir)\include.plist"
Hat man eine vom Standard abweichende Build-Ausgabe muß das natürlich angepasst werden.

Dabei darauf achten, dass die Build-Konfigurationen für iOS-Gerät und Simulator bearbeitet werden - es sei denn dort wären Unterschiede gewünscht.

Der Aufruf erfolgt mit dem Namen der von der IDE erstellten plist-Datei sowie einer weiteren, die nur die hinzuzufügenden Fragmente enthält. Optional kann man noch einen driten Parameter für die Ausgabedatei angeben. Fehlt der, wird in die Eingabedatei zurückgeschrieben.

Beispiel eines Fragments um beim iOS-Ladevorgang bereits die Statuszeile auszuschalten:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>UIStatusBarHidden</key>
  <true/>
</dict>
</plist>
Hier der Code zum Tool. Viel Spaß!
Delphi-Quellcode:
program PlistPatcher;

{$APPTYPE CONSOLE}
{$WEAKLINKRTTI ON}
uses
  Sysutils,
  Winapi.Windows,
  PlistFuncs in 'PlistFuncs.pas';

{$R *.res}

begin
  if ParamCount < 2 then
  begin
    writeln('Usage : PlistPatcher <PlistFile|PlistOutput> <PlistFragment> [<PlistOutput>]');
    ExitCode := ERROR_INVALID_PARAMETER;
  end
  else
  try
    ExitCode := MergePlist(Paramstr(1), Paramstr(2), Paramstr(3));
  except
    on e : exception do
    begin
      write(e.Message);
      ExitCode := 1;
      if e is EOSError then
      begin
        ExitCode := EOSError(e).ErrorCode;
        writeln(' (' +ExitCode.ToString + ')');
      end;
    end;
  end;
end.
Delphi-Quellcode:
unit PlistFuncs;

interface
  function MergePlist(const AFile, AFragment : string; AOutFile : string = '') : integer;

implementation

uses
  Sysutils,
  IOUtils,
  Winapi.Windows;

// Fügt in die Eingabedatei den Inhalt der Fragmentdatei ein.
function MergePlist(const AFile, AFragment : string; AOutFile : string = '') : integer;
const
  DictStart = '<dict>';
  DictEnd  = '</dict>';
var
  LFile, LFragment : string;
  LInsertPos : integer;
  LStartPos : integer;
  LEndPos : integer;
begin
  Result := ERROR_INVALID_PARAMETER;
  // Diese beiden lösen ggf. Exceptions aus, macht nix
  LFile    := TFile.ReadAllText(AFile);
  LFragment := TFile.ReadAllText(AFragment);
  // Position an der eingefügt wird
  LInsertPos := Pos(DictEnd, LFile);
  // Startposition des einzufügenden Blocks
  LStartPos := Pos(DictStart, LFragment);
  // Endposition des einzufügenden Blocks
  LEndPos   := Pos(DictEnd, LFragment);

  // Nur durchführen wenn auch etwas eingefügt werden kann
  if (LInsertPos > 0) and
     (LStartPos > 0) and
     (LEndPos > 0) and
     (LEndPos > LStartPos) then
  begin
    // In die ursprüngliche plist den Inhalt der zweiten plist einfügen
    LFile := Copy(LFile, 1, LInsertPos-1) +
             Copy(LFragment, LStartPos + length(DictStart) + 1, LEndPos-LStartPos-length(DictEnd))+
             Copy(LFile, LInsertPos, Length(LFile) - LInsertPos);
    // Wenn keine Ausgabedatei angegeben wurde, in Eingabedatei zurückschreiben
    if AOutFile = '' then
      AOutFile := AFile;

    TFile.WriteAllText(AOutFile, LFile);
    Result := NO_ERROR;
  end;
end;

end.

Thomas_K 12. Mai 2015 10:25

AW: PListPatcher für die iOS-Entwicklung
 
Es gibt eine alternative um einen Schlüssel/Wert in die Info.plist hinzuzufügen, dieser ist ziemlich versteckt hier beschrieben http://docwiki.embarcadero.com/RADSt...sinformationen

Hier mal die Schnellfassung Menu -> Projekt -> Optionen… Dann befindet man sich in den Projektoptionen und wählt die Seite „Versionsinformationen“ auf -> mit der rechten Maustaste klickt man in die Schlüssel/Werte –Liste, was wiederum ein Popupmenu, mit den Einträge Schlüssel hinzufügen/entfernen öffnet.

Diese Option ermöglicht aber nicht das hin zufügen von Array/Feldwerte, das müsste man dann doch wieder hinten rum lösen.

Ich konnte zwar den Schlüssel „UIStatusBarHidden“ mit dem „true“ hinzufügen und er befindet sich auch in der info.plist doch hat er keinen Effekt, zumindest nicht unter XE8 und iPad mit iOS 8.1.2 .

Sir Rufo 12. Mai 2015 11:41

AW: PListPatcher für die iOS-Entwicklung
 
Das liegt ganz einfach daran, dass der Eintrag wie folgt in die PLIST wandert
XML-Code:
<key>UIStatusBarHidden</key>
  <string>true</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
  <string>false</string>
und so müsste er sein, damit es auch die erwünschte Auswirkung hat:
XML-Code:
<key>UIStatusBarHidden</key>
  <true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
  <false/>

Union 12. Mai 2015 14:01

AW: PListPatcher für die iOS-Entwicklung
 
Deshalb habe ich das Tool ja gemacht, weil die IDE den falschen XML-Typen verwendet.

Sir Rufo 12. Mai 2015 14:06

AW: PListPatcher für die iOS-Entwicklung
 
Zitat:

Zitat von Thomas_K (Beitrag 1301162)
Ich konnte zwar den Schlüssel „UIStatusBarHidden“ mit dem „true“ hinzufügen und er befindet sich auch in der info.plist doch hat er keinen Effekt, zumindest nicht unter XE8 und iPad mit iOS 8.1.2 .

Kurzer Nachtrag dazu:

Um die StatusBar auszublenden muss man einfach den
Delphi-Quellcode:
BorderStyle
der Form auf
Delphi-Quellcode:
TFmxFormBorderStyle.None
setzen.

Allerdings gibt es auf dem iOS-Simulator beim Umschalten gerne auch mal eine Zugriffsverletzung oder die App stürzt einfach ins Nirwana ...

Thomas_K 12. Mai 2015 15:03

AW: PListPatcher für die iOS-Entwicklung
 
@Union und @Sir Rufo

Ich hab es hinbekommen das iOS Launch Image ohne iOS-Statusbar-Einblendung, ich musste aber den PlistPatcher leicht modifizieren, damit er mit XE8 unter Windows 7 funktioniert.

Die iOS Statusbar zur Laufzeit aus und wieder einzublenden funktioniert unter XE7 mit Sephen Ball’s Beispiel http://delphiaball.co.uk/2014/10/16/...tformservices/ problemlos, dasselbe Beispiel unter XE8 funktioniert nur zu 50%, wenn die App unter dem Debugger läuft. Direkt gestartet auf einem iPhone oder iPad schmiert es zu 100% ab.

Sir Rufo 12. Mai 2015 15:08

AW: PListPatcher für die iOS-Entwicklung
 
Also unter XE8 stelle ich in der MainForm einfach den
Delphi-Quellcode:
BorderStyle
auf
Delphi-Quellcode:
None
und die StatusBar ist weg.

Nix PList-Patch, noch sonst irgendwas -> einfach eine einfache Einstellung, fertig.

Und wenn man sich die Mühe macht, den Code zu dem FullScreenService anzuschauen, was finden wir da? - Genau, da wird einfach der Border-Style gesetzt :roll:

Thomas_K 13. Mai 2015 11:21

AW: PListPatcher für die iOS-Entwicklung
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab meine Anpassungen (quick and dirty) zusammen mit Thread Beispiel versehen, außerdem noch ein kleines Howto.txt dazugepackt alles in eine zip-Datei gesteckt. Den Exe-name musste ich ändert, damit die Windows UAC nicht dazwischen funkt.

Union 13. Mai 2015 11:33

AW: PListPatcher für die iOS-Entwicklung
 
Schön gemacht, das mit dem RPos fängt jetzt auch Fälle mit verschachtelten <dict>. :thumb:

Thomas_K 13. Mai 2015 14:11

AW: PListPatcher für die iOS-Entwicklung
 
Zitat:

Zitat von Union (Beitrag 1301350)
Schön gemacht, das mit dem RPos fängt jetzt auch Fälle mit verschachtelten <dict>. :thumb:

Ja machmal muss man das Pferd von hinten aufzäumen, ich muss aber gestehen Google hat mir bei der Umsetzung etwas geholfen, ich brauche die Routine nur in die Neu-Zeit zu überführen.

Den iOS Full-Screen-Bug hab ich auch mal gemeldet - https://quality.embarcadero.com/browse/RSP-11142


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz