Abläufe beim Erstellen von iOS-Builds

In diesem Leitfaden erfahren Sie, wie Sie Ihre Anwendungen zeitlich steuern und wie Sie Methoden für schnellere Builds verwenden können.

Das Entwickeln großartiger Anwendungen ist mehr als das bloße Schreiben von funktionierendem Code. Eine gut geschriebene App sollte Optimierungen aufweisen, die schnellere Builds mit kleineren und schnelleren Anwendungen ermöglichen. Diese Optimierungen führen nicht nur zu einer besseren Erfahrung für den Benutzer, sondern auch für Sie bzw. alle Entwickler, die am Projekt arbeiten. Es ist wichtig sicherzustellen, dass beim Umgang mit Ihrer App alles häufig zeitlich gesteuert wird.

Denken Sie daran, dass die Standardoptionen sicher und schnell, aber nicht für jede Situation optimal sind. Darüber hinaus können viele Optionen den Entwicklungszyklus je nach Projekt verlangsamen oder beschleunigen. Beispielsweise nimmt natives Entfernen Zeit in Anspruch, aber wenn nur eine sehr geringe Größe erreicht wird, lässt sich der Zeitaufwand für das Entfernen nicht durch eine schnellere Bereitstellung zurückgewinnen. Andererseits kann natives Entfernen die App erheblich verkleinern, wodurch die Bereitstellung schneller erfolgt. Dies variiert je nach Projekt und kann nur durch Testen festgestellt werden.

Das Tempo von Xamarin-Builds kann auch durch verschiedene Kapazitäten und Fähigkeiten eines Computers beeinflusst werden, die die Leistung beeinflussen können: Prozessorleistung, Busgeschwindigkeiten, die Größe des physischen Speichers, Festplattengeschwindigkeit, Netzwerkgeschwindigkeit. Diese Leistungseinschränkungen sind nicht Gegenstand dieses Dokuments und liegen in der Verantwortung des Entwicklers.

Zeitsteuerung-Apps

So aktivieren Sie die Diagnoseausgabe von MSBuild in Visual Studio für Mac

  1. Klicken Sie auf Visual Studio für Mac > Einstellungen...
  2. Wählen Sie in der linken Strukturansicht Die Option Projekte > erstellen aus.
  3. Legen Sie im rechten Bereich die Dropdownliste Protokoll-Ausführlichkeit auf Diagnose: Festlegen der Ausführlichkeit des Protokolls fest.
  4. Klicken Sie auf OK.
  5. Starten Sie Visual Studio für Mac neu.
  6. Bereinigen Sie Ihr Paket, und erstellen Sie es erneut.
  7. Zeigen Sie die Diagnoseausgabe im Fehlerpad an ( Fehler > anzeigen von Pads > ), indem Sie auf die Schaltfläche Buildausgabe klicken.

Zeitliche Steuerung von mtouch

Um spezifische Informationen zum mtouch-Buildprozess anzuzeigen, übergeben Sie in Ihren Projektoptionen--time --time an die mtouch-Argumente. Die Ergebnisse finden Sie in der Buildausgabe, indem Sie den Task MTouch suchen:

Setup: 36 ms
Resolve References: 982 ms
Extracted native link info: 987 ms
...
Total time: 1554 ms

Herstellen einer Verbindung von Visual Studio mit dem Buildhost

Die Xamarin-Tools funktionieren technisch auf jedem Mac, auf dem OS X 10.10 Yosemite oder höher ausgeführt werden kann. Allerdings können Entwicklererfahrungen und Buildzeiten durch die Leistung des Mac beeinträchtigt werden.

Im getrennten Zustand führt Visual Studio unter Windows nur die C#-Kompilierungsphase durch und versucht nicht, eine Verknüpfung oder AOT-Kompilierung auszuführen, die Anwendung in ein .app-Bundle zu packen oder das App Bundle zu signieren. (Die C#-Kompilierungsphase ist selten ein Leistungsengpass.) Versuchen Sie herauszufinden, wo in der Pipeline der Build verlangsamt wird, indem Sie direkt auf dem Mac-Buildhost in Visual Studio für Mac einen Build erstellen.

Darüber hinaus ist einer der häufigsten Gründe für Langsamkeit die Netzwerkverbindung zwischen dem Windows-Computer und dem Mac-Buildhost. Dies kann durch eine physische Einschränkung im Netzwerk, eine drahtlose Verbindung oder einen überlasteten Computer (z. B. einen Mac-in-the-Cloud-Dienst) verursacht werden.

Simulatortricks

Bei der Entwicklung mobiler Anwendungen ist die schnelle Bereitstellung von Code unerlässlich. Aus einer Vielzahl von Gründen, darunter Geschwindigkeit und fehlende Anforderungen an die Gerätebereitstellung, entscheiden sich Entwickler häufig für die Bereitstellung auf einem vorinstallierten Simulator oder Emulator. Für Hersteller von Entwicklertools ist die Entscheidung, einen Simulator oder Emulator zur Verfügung zu stellen, ein Kompromiss zwischen Geschwindigkeit und Kompatibilität.

Apple stellt einen Simulator für die iOS-Entwicklung zur Verfügung, der Geschwindigkeit über Kompatibilität stellt, indem er eine weniger restriktive Umgebung für die Ausführung von Code schafft. Diese weniger restriktive Umgebung erlaubt es Xamarin, den JIT-Compiler (Just In Time) für den Simulator zu verwenden (im Gegensatz zu AOT auf einem Gerät), was bedeutet, dass der Build zur Laufzeit in nativen Code kompiliert wird. Da der Mac viel schneller als ein Gerät ist, ermöglicht dies eine bessere Leistung.

Der Simulator verwendet einen gemeinsam genutzten Anwendungsstarter, sodass der Starter wiederverwendet werden kann, anstatt jedes Mal neu erstellt zu werden, wie es auf dem Gerät erforderlich ist.

Unter Berücksichtigung der obigen Informationen bietet die nachstehende Liste einige Informationen zu den Schritten, die Sie beim Erstellen und Bereitstellen Ihrer App im Simulator durchführen müssen, um die beste Leistung zu erzielen.

Tipps

  • Für Builds:
    • Deaktivieren Sie in „Projektoptionen“ die Option PNG-Bilder optimieren. Diese Optimierung ist für Builds im Simulator nicht notwendig.
    • Legen Sie den Linker auf Nicht verknüpfen fest. Das Deaktivieren des Linkers sorgt für Beschleunigung, da die Ausführung des Linkers viel Zeit in Anspruch nimmt.
    • Das Deaktivieren des gemeinsam genutzten Anwendungsstarters durch Verwendung des Flags --nofastsim führt dazu, dass Simulatorbuilds wesentlich langsamer werden. Entfernen Sie dieses Flag, wenn es nicht mehr benötigt wird.
    • Die Verwendung nativer Bibliotheken ist langsamer, da die gemeinsam genutzte Hauptausführungsdatei von simlauncher in solchen Fällen nicht wiederverwendet werden kann und für jeden Build eine anwendungsspezifische ausführbare Datei kompiliert werden muss.
  • Für die Bereitstellung
    • Lassen Sie den Simulator nach Möglichkeit immer in Betrieb. Der Kaltstart des Simulators kann bis zu 12 Sekunden dauern.
  • Weitere Tipps
    • Ziehen Sie das Erstellen dem Neuerstellen vor, da beim Neuerstellen vor dem Erstellen des Builds eine Bereinigung erfolgt. Das Bereinigen kann sehr lange dauern, da Verweise entfernt werden, die verwendet werden könnten.
    • Nutzen Sie die Tatsache aus, dass der Simulator die Sandbox nicht erzwingt. Wenn Sie große Ressourcen wie Videos oder andere Objekte in Ihr Projekt einbinden, kann es bei jedem Start der Anwendung im Simulator zu aufwändigen Dateikopiervorgängen kommen. Vermeiden Sie diese aufwändigen Vorgänge, indem Sie diese Dateien im Basisverzeichnis ablegen und in Ihrer Anwendung über den vollständigen Dateipfad auf sie verweisen.
    • Verwenden Sie im Zweifelsfall das Flag --time --time, um Ihre Änderung zu messen.

Der folgende Screenshot zeigt, wie Sie in Ihren iOS-Optionen diese Optionen für den Simulator festlegen:

Screenshot: Projektoptionen einschließlich „Linkerverhalten“, „Weitere mtouch-Argumente“ und „PNG-Bilder optimieren“

Gerätetricks

Die Bereitstellung auf dem Gerät ist vergleichbar mit der Bereitstellung auf dem Simulator, da der Simulator eine kleine Teilmenge des Builds ist, der für das iOS-Gerät verwendet wird. Das Erstellen eines Builds für ein Gerät erfordert viele weitere Schritte, hat aber den Vorteil, dass es zusätzliche Möglichkeiten zur Optimierung Ihrer App bietet.

Buildkonfigurationen

Es gibt eine Reihe von Buildkonfigurationen, die bei der Bereitstellung von iOS-Apps zur Verfügung stehen. Es ist wichtig, ein gutes Verständnis der einzelnen Konfigurationen zu haben, um zu wissen, wann und warum Sie optimieren sollten.

  • Debug
    • Dies ist die Hauptkonfiguration, die während der Entwicklung einer App verwendet werden sollte und daher so schnell wie möglich sein sollte.
  • Freigabe
    • Releasebuilds sind diejenigen, die an Ihre Benutzer ausgeliefert werden. Bei ihnen liegt der Schwerpunkt auf der Leistung. Wenn Sie die Releasekonfiguration verwenden, empfiehlt es die Verwendung des LLVM-Optimierungscompilers und Optimierung von PNG-Dateien.

Wichtig ist es auch, die Beziehung zwischen dem Erstellen des Builds und Bereitstellen zu verstehen. Die Bereitstellungszeit richtet sich nach der Größe der Anwendung. Eine größere Anwendung benötigt mehr Zeit zum Bereitstellen. Durch Minimieren der App-Größe können Sie die Bereitstellungszeit verkürzen.

Durch Minimieren der App-Größe verkürzt sich auch die Buildzeit. Das liegt daran, dass das Entfernen von Code aus der Anwendung weniger Zeit in Anspruch nimmt, als das native Kompilieren des Codes, der nicht verwendet werden soll. Kleinere Objektdateien bedeuten eine schnellere Verknüpfung, wodurch eine kleinere ausführbare Datei mit weniger zu erzeugenden Symbolen erstellt wird. Das Einsparen von Speicherplatz zahlt sich also doppelt aus, weshalb SDK verknüpfen der Standard für alle Gerätebuilds ist.

Hinweis

Die Option SDK verknüpfen kann je nach verwendeter IDE als „Nur Framework-SDKs verknüpfen“ oder „Nur SDK-Assemblys verknüpfen“ angezeigt werden.

Tipps

  • Build:
    • Das Erstellen einer einzelnen Architektur (z. B. ARM64) erfolgt schneller als das einer FAT-Binärdatei (z. B. ARMv7 + ARM64).
    • Vermeiden Sie die Optimierung von PNG-Dateien beim Debuggen.
    • Erwägen Sie, alle Assemblys zu verknüpfen. Optimieren Sie jede Assembly.
    • Deaktivieren Sie die Erstellung von Debugsymbolen mit --dsym=false. Sie sollten sich jedoch im Klaren sein, dass das Deaktivieren dieser Option bedeutet, dass Absturzberichte nur auf dem Computer, auf dem die Anwendung erstellt wurde, durch Symbole dargestellt werden können, und nur dann, wenn aus der Anwendung kein nicht verwendeter Code entfernt wurde.

Die folgenden Dinge sollten vermieden werden:

  • FAT-Binärdateien (Debuggen)
  • Deaktivieren des Linkers --nolink
  • Deaktivieren der Entfernung von nicht verwendetem Code
    • Symbole --nosymbolstrip
    • IL (Release) --nostrip.

Weitere Tipps

  • Ziehen Sie wie beim Simulator das Erstellen dem Neuerstellen vor.
    • AOT kompilierte Assemblys (Objektdateien) werden zwischengespeichert.
  • Debugbuilds dauern wegen der Symbole länger, da dsymutil ausgeführt wird. Und weil sie letztendlich größer werden, dauert das Hochladen auf Geräte länger.
  • Releasebuilds wenden standardmäßig eine IL-Entfernung auf die Assemblys an. Das dauert nur kurze Zeit, die wahrscheinlich zurückgewonnen wird, weil eine kleinere App auf dem Gerät bereitgestellt wird.
  • Vermeiden Sie das Bereitstellen großer statischer Dateien bei jedem Build (Debug).
    • Verwenden Sie „UIFileSharingEnabled“ (Info.plist).
      • Objekte können einmal hochgeladen werden.
  • Verwenden Sie im Zweifelsfall das Flag --time --time, um Ihre Änderung zu messen.

Der folgende Screenshot zeigt, wie Sie in Ihren iOS-Optionen diese Optionen für den Simulator festlegen:

Screenshot: Projektoptionen einschließlich „Linkerverhalten“, „Unterstützte Architekturen“ und weiteren Einstellungen

Verwenden des Linkers

Beim Erstellen Ihrer Anwendung verwendet mtouch einen Linker für verwalteten Code, der Code entfernt, den die Anwendung nicht verwendet. Theoretisch ergeben sich dadurch kleinere und damit schnellere Builds. Weitere Informationen zum Linker finden Sie in der Anleitung Verknüpfung unter iOS.

Beachten Sie beim Verwenden des Linkers die folgenden Punkte:

  • Die Auswahl von Nicht verknüpfen für einen Gerätebuild bringt einen höheren Zeitaufwand mit sich und erzeugt auch eine größere App.
    • Apple lehnt Apps ab, die die Größenbeschränkung überschreiten. Abhängig von kann dies MinimumOSVersionbis zu 60 MB sein.
    • Der native ausführbare Datei wird dabei eingerechnet.
    • Bei Simulatorbuilds ist die Verwendung von „Nicht verknüpfen“ schneller, da die JIT-Kompilierung zum Einsatz kommt (im Gegensatz zu AOT auf einem Gerät).
  • „SDK verknüpfen“ ist die Standardoption.
  • Das Verwenden von „Alle verknüpfen“ ist möglicherweise nicht sicher, insbesondere wenn Sie mit Code arbeiten, der nicht Ihr eigener ist, wie z.B. NuGet-Pakete oder Komponenten. Wenn Sie sich dafür entscheiden, Assemblys nicht zu verknüpfen, wird der gesamte Code aus diesen Diensten in Ihre Anwendung eingebunden, wodurch möglicherweise größere Apps entstehen.
    • Wenn Sie jedoch Alle verknüpfen wählen, kann die Anwendung abstürzen, insbesondere wenn externe Komponenten verwendet werden. Der Grund dafür ist, dass einige Komponenten für bestimmte Typen Reflektion verwenden.
    • Statische Analyse und Reflektion funktionieren nicht zusammen.

Die Tools können angewiesen werden, Dinge innerhalb der Anwendung zu behalten, indem das [Preserve]-Attribut verwendet wird.

Wenn Sie keinen Zugriff auf den Quellcode haben oder er von einem Tool generiert wird und Sie ihn nicht ändern möchten, können Sie ihn trotzdem verknüpfen, indem Sie eine XML-Datei erstellen, die alle Typen und Member beschreibt, die erhalten bleiben müssen. Sie können dann das Flag --xml={file.name}.xml Ihren Projektoptionen hinzufügen, wodurch Code genau so verarbeitet wird, als ob Sie Attribute verwenden würden.

Teilweises Verknüpfen von Anwendungen

Es ist auch möglich, Anwendungen teilweise zu verknüpfen, um die Buildzeit Ihrer Anwendung zu optimieren:

  • Verwenden Sie Link All, und überspringen Sie einige Assemblys.

    • Die Optimierung der Anwendungsgröße geht teilweise verloren.
    • Es ist kein Zugriff auf den Quellcode erforderlich.
    • Beispiel: --linkall --linkskip=fieldserviceiOS.
  • Verwenden Sie Link SDK die Option, und verwenden Sie das [LinkerSafe] -Attribut für die assemblys, die Sie benötigen.

    • Zugriff auf den Quellcode ist erforderlich.
    • Teilt dem System mit, dass die Assembly sicher zu verknüpfen ist und wie ein Xamarin SDK verarbeitet wird.

Objective-CBindings

  • Durch Verwenden des [Assembly: LinkerSafe]-Attributs für Ihre Bindungen können Sie Zeit sparen und die Größe reduzieren.

  • SmartLink

    • Erfolgt auf nativer Seite.
    • Verwenden Sie das Attribut [LinkWith (SmartLink=true)].
    • Dies hilft dem nativen Linker, nativen Code aus der Bibliothek zu entfernen, mit der Sie eine Verknüpfung herstellen.
    • Beachten Sie, dass die dynamische Suche nach Symbolen in diesem Fall nicht funktioniert.

Zusammenfassung

In dieser Anleitung wurde untersucht, wie eine iOS-Anwendung zeitlich gesteuert werden kann und welche Optionen zu berücksichtigen sind, die von der Buildkonfiguration und den Optionen des Projekts abhängen.