AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte PListPatcher für die iOS-Entwicklung
Thema durchsuchen
Ansicht
Themen-Optionen

PListPatcher für die iOS-Entwicklung

Ein Thema von Union · begonnen am 11. Mär 2014 · letzter Beitrag vom 13. Mai 2015
Antwort Antwort
Benutzerbild von Union
Union
Registriert seit: 18. Mär 2004
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.
Angehängte Dateien
Dateityp: zip PlistPatcher.zip (170,4 KB, 14x aufgerufen)
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all

Geändert von Union (12. Mai 2015 um 15:00 Uhr)
 
Thomas_K

 
Delphi XE8 Professional
 
#2
  Alt 12. Mai 2015, 11:25
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 .
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

 
Delphi 10 Seattle Enterprise
 
#3
  Alt 12. Mai 2015, 12:41
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/>
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

 
Delphi 7 Enterprise
 
#4
  Alt 12. Mai 2015, 15:01
Deshalb habe ich das Tool ja gemacht, weil die IDE den falschen XML-Typen verwendet.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

 
Delphi 10 Seattle Enterprise
 
#5
  Alt 12. Mai 2015, 15:06
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 BorderStyle der Form auf 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 ...
  Mit Zitat antworten Zitat
Thomas_K

 
Delphi XE8 Professional
 
#6
  Alt 12. Mai 2015, 16:03
@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.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

 
Delphi 10 Seattle Enterprise
 
#7
  Alt 12. Mai 2015, 16:08
Also unter XE8 stelle ich in der MainForm einfach den BorderStyle auf 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

Geändert von Sir Rufo (12. Mai 2015 um 16:16 Uhr)
  Mit Zitat antworten Zitat
Thomas_K

 
Delphi XE8 Professional
 
#8
  Alt 13. Mai 2015, 12:21
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.
Angehängte Dateien
Dateityp: zip PListChanger.zip (289,7 KB, 3x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

 
Delphi 7 Enterprise
 
#9
  Alt 13. Mai 2015, 12:33
Schön gemacht, das mit dem RPos fängt jetzt auch Fälle mit verschachtelten <dict>.
  Mit Zitat antworten Zitat
Thomas_K

 
Delphi XE8 Professional
 
#10
  Alt 13. Mai 2015, 15:11
Schön gemacht, das mit dem RPos fängt jetzt auch Fälle mit verschachtelten <dict>.
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
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:35 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