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.