<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Entwicklerblog für Windows 8-Apps</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/windowsappdev_de/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/windowsappdev_de/feed.xml</link>
    <description>Ein Einblick in die Entwicklung von Apps im Metro-Stil – präsentiert vom Windows 8-Entwicklerteam</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:28:45 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Alles über Zusagen (für in JavaScript geschriebene Windows Store-Apps)</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_de/alles-ber-zusagen-fr-in-javascript-geschriebene-windows-store-apps</link>
      <pubDate>Wed, 26 Jun 2013 15:52:17 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_de/2013/06/26/alles-ber-zusagen-fr-in-javascript-geschriebene-windows-store-apps/</guid>
      <description><![CDATA[Wenn Sie beim Schreiben von Windows Store-Apps in JavaScript asynchrone APIs verwenden, werden Sie...]]></description>
      <content:encoded><![CDATA[<div class="PostContent"> <p>Wenn Sie beim Schreiben von Windows Store-Apps in JavaScript asynchrone APIs verwenden, werden Sie Konstrukte verwenden, die als <i><a href="http://msdn.microsoft.com/de-de/library/windows/apps/Hh700339.aspx">Zusagen</a> </i>(„Promise“) bezeichnet werden. Das Schreiben von Zusagenketten für sequenzielle asynchrone Vorgänge wird schnell zur Routine.</p>  <p>Im Rahmen Ihrer Entwicklungsarbeit werden Sie es jedoch wahrscheinlich noch mit anderen Anwendungen von Zusagen zu tun haben, deren Funktion nicht klar ersichtlich ist. Ein gutes Beispiel hierfür ist das Optimieren der Elementrenderingfunktionen für ein ListView-Steuerelement, wie unter <a href="http://code.msdn.microsoft.com/windowsapps/ListView-performance-39fb71f0">HTML ListView optimizing performance sample</a> dargestellt. Wir werden darauf in einem späteren Beitrag genauer eingehen. Sehen Sie sich auch dieses kleine Kunststück an, das Josh Williams auf der //build 2012 in seinem Vortrag <a href="https://channel9.msdn.com/Events/Build/2012/4-101">Deep Dive into WinJS</a> vorstellte (leicht geändert):</p>  <blockquote>   <div id="codeSnippetWrapper">     <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">list.reduce(<span style="color: rgb(0, 0, 255);">function</span> callback (prev, item, i) {<br />    <span style="color: rgb(0, 0, 255);">var</span> result = doOperationAsync(item);<br />    <span style="color: rgb(0, 0, 255);">return</span> WinJS.Promise.join({ prev: prev, result: result}).then(<span style="color: rgb(0, 0, 255);">function</span> (v) {<br />        console.log(i + <span style="color: rgb(0, 96, 128);">&quot;, item: &quot;</span> + item+ <span style="color: rgb(0, 96, 128);">&quot;, &quot;</span> + v.result);<br />    });<br />})<br /></pre>
  </div>
</blockquote>

<p>Durch dieses Snippet werden Zusagen für parallele asynchrone Vorgänge zusammengefügt, deren Ergebnisse sequenziell in der mit <i>list</i> festgelegten Reihenfolge bereitgestellt werden. Wenn Sie die Funktionalität dieses Codes auf Anhieb verstehen, können Sie den Rest dieses Beitrags getrost überspringen. Falls nicht, gehen wir genauer auf die eigentliche Funktionsweise von Zusagen und deren Bedeutung in WinJS (der Windows-Bibliothek für JavaScript) ein, um ein besseres Verständnis dieser Muster zu entwickeln.</p>

<h2>Was genau ist eine Zusage? Zusagenbeziehungen</h2>

<p>Fangen wir mit einer grundlegenden Wahrheit an: Bei einer Zusage handelt es sich im Wesentlichen nur um ein Codekonstrukt bzw. eine Aufrufkonvention. Zusagen haben daher keine besondere Beziehung zu asynchronen Vorgängen, sie sind diesbezüglich nur äußerst <i>nützlich</i>. Eine Zusage ist lediglich ein Objekt, das einen Wert darstellt, der möglicherweise zukünftig verfügbar wird oder schon verfügbar ist. Gewissermaßen haben Zusagen also die gleiche Bedeutung wie im normalen Sprachgebrauch. Wenn ich Ihnen zusage, ein Dutzend Donuts zu bringen, muss ich diese Donuts in diesem Moment nicht unbedingt besitzen, nehme jedoch mit Sicherheit an, dass ich sie erhalten <i>werde</i>. Sobald ich die Donuts habe, liefere ich.</p>

<p>Eine Zusage impliziert also eine Beziehung zwischen zwei Parteien: dem <i>Urheber</i>, der die Zusage für eine Warenlieferung tätigt, und dem <i>Verbraucher</i>, der sowohl die Zusage als auch die eigentlichen Waren erhält. Die Beschaffung der Waren fällt in die alleinige Verantwortung des Urhebers, und auch der Verbraucher kann mit der Zusage und den gelieferten Waren beliebig verfahren. Er kann die Zusage sogar mit anderen Verbrauchern teilen.</p>

<p>Die Beziehung zwischen Urheber und Verbraucher weist außerdem zwei Phasen auf, <i>Erstellung</i> und <i>Erfüllung</i>. Sämtliche dieser Aspekte werden in folgendem Diagramm dargestellt.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0844.promise_diagram_577C7B9B.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0844.promise_5F00_diagram_5F00_577C7B9B.png"><img title="Diagramm – Zusagen" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Diagramm – Zusagen" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0458.promise_diagram_thumb_0FBAF2B4.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0458.promise_5F00_diagram_5F00_thumb_5F00_0FBAF2B4.png" width="700" height="341" /></a></p>

<p>Wenn wir dem Diagrammfluss folgen, wird deutlich, weshalb Zusagen aufgrund der beiden Beziehungsphasen gut für eine asynchrone Bereitstellung geeignet sind. Das Wichtigste ist, dass der Verbraucher nach Erhalt der Anforderungsbestätigung (der Zusage) anderen Aufgaben nachgehen kann (asynchron), anstelle zu warten (synchron). Der Verbraucher kann so die Zeit, während der er auf die Erfüllung der Zusage wartet, für Anderes nutzen, z. B. zum Beantworten weiterer Anforderungen. Dies ist der eigentliche Zweck asynchroner APIs. Falls die Waren bereits verfügbar sind, kann die Zusage unmittelbar erfüllt werden, wodurch der gesamte Vorgang zu einer Art synchroner Aufrufkonvention wird.</p>

<p>Natürlich müssen im Zusammenhang mit dieser Beziehung noch einige weitere Aspekte berücksichtigt werden. Sie haben sicherlich im wirklichen Leben schon Zusagen getätigt und erhalten. Sicher wurden viele dieser Zusagen erfüllt, einige jedoch auch nicht eingehalten: Der Pizzalieferant kann auf dem Weg zu Ihnen durchaus in einen Unfall verwickelt werden! Nicht eingehaltene Zusagen sind unumgänglich und können weder im echten Leben noch bei der asynchronen Programmierung vermieden werden.</p>

<p>In Bezug auf die Zusagenbeziehung benötigt der Urheber daher eine Möglichkeit zur Mitteilung, dass er die Zusage nicht einhalten kann, und der Verbraucher muss darüber informiert werden können. Zudem werden Verbraucher möglicherweise auch ungeduldig, wenn Zusagen längere Zeit nicht erfüllt werden. Wenn der Urheber also den Fortschritt bis zur Erfüllung der Zusage nachverfolgen kann, ist auch eine entsprechende Methode zum Informieren des Verbrauchers erforderlich. Drittens ist es außerdem möglich, dass der Verbraucher den Auftrag abbricht und dem Urheber mitteilt, dass die Waren nicht mehr benötigt werden.</p>

<p>Wenn diese Anforderungen im Diagramm berücksichtigt werden, ergibt sich ein Bild der vollständigen Beziehung:</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/4251.promise_diagram_2_23D40F3D.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/4251.promise_5F00_diagram_5F00_2_5F00_23D40F3D.png"><img title="Diagramm – Zusagen 2" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Diagramm – Zusagen 2" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0550.promise_diagram_2_thumb_1CB4D2C5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0550.promise_5F00_diagram_5F00_2_5F00_thumb_5F00_1CB4D2C5.png" width="700" height="432" /></a></p>

<p>Betrachten wir nun, wie diese Beziehungen in Code umgesetzt werden.</p>

<h2>Das Zusagenkonstrukt und Zusagenketten</h2>

<p>Tatsächlich gibt es für Zusagen eine Reihe verschiedener Vorschläge oder Spezifikationen. In Windows und WinJS werden als <a href="http://wiki.commonjs.org/wiki/Promises/A">Common JS/Promises A</a> bezeichnete Zusagen verwendet, wobei eine Zusage (der Rückgabewert eines Urhebers, der einen zukünftig bereitzustellenden Wert repräsentiert) ein Objekt mit einer <b>then</b> genannten Funktion darstellt. Die Verbraucher abonnieren die Einhaltung der Zusage durch das Aufrufen von <b>then</b>. (Für Zusagen in Windows wird auch die ähnliche Funktion <b>done</b> unterstützt, die wie in Kürze erläutert in Zusagenketten verwendet wird.)</p>

<p>An diese Funktion werden vom Verbraucher in folgender Reihenfolge bis zu drei optionale Funktionen als Argumente übergeben:</p>

<ol>
  <li>Ein <i>Completed-Handler</i>. Diese Funktion wird vom Urheber aufgerufen, sobald der zugesagte Wert zur Verfügung steht. <i>Ist</i> dieser Wert bereits verfügbar, wird der Completed-Handler unmittelbar (synchron) innerhalb von <b>then</b> aufgerufen.</li>

  <li>Ein optionaler <i>Fehlerhandler</i>, der aufgerufen wird, falls der zugesagte Wert nicht beschafft werden kann. Nach einem Aufruf des Fehlerhandlers wird für die entsprechende Zusage nie der Completed-Handler aufgerufen.</li>

  <li>Ein optionaler <i>Progress-Handler</i>, der bei entsprechender Unterstützung durch den Vorgang regelmäßig für Zwischenergebnisse aufgerufen wird. (In WinRT bedeutet dies, dass die API den Rückgabewert <b>IAsync[Action | Operation]WithProgress</b> aufweist, im Gegensatz zu jenen mit <b>IAsync[Action | Operation]</b>.)</li>
</ol>

<p>Beachten Sie, dass für jedes dieser Argumente <i>null</i> übergeben werden kann, beispielsweise wenn Sie statt eines Completed-Handlers nur einen Fehlerhandler hinzufügen möchten. </p>

<p>Auf der anderen Seite der Beziehung können Verbraucher beliebig viele Handler für dieselbe Zusage abonnieren, indem sie mehrfach <b>then</b> aufrufen. Die Zusage kann auch mit anderen Verbrauchern geteilt werden, die ebenso häufig wie gewünscht <b>then</b> aufrufen können. Dies wird vollständig unterstützt.</p>

<p>Für Zusagen bedeutet dies, dass Listen aller empfangener Handler verwaltet werden müssen, um diese zum jeweils richtigen Zeitpunkt aufzurufen. Wie in der vollständigen Beziehung dargestellt, ist bei Zusagen außerdem eine Möglichkeit zum Abbrechen erforderlich.</p>

<p>Aus der <i>Promises A</i>-Spezifikation ergibt sich die zusätzliche Anforderung, dass die <b>then</b>-Methode selbst eine Zusage zurückgeben muss. Diese zweite Zusage gilt als erfüllt, sobald der an die erste <b>promise.then</b>-Methode übergebene Completed-Handler zurückgegeben wird. Der Rückgabewert wird hierbei als das Ergebnis der zweiten Zusage bereitgestellt. Gehen Sie diesen Codeausschnitt durch:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> promise1 = someOperationAsync();<br /><span style="color: rgb(0, 0, 255);">var</span> promise2 = promise1.then(<span style="color: rgb(0, 0, 255);">function</span> completedHandler1 (result1) { <span style="color: rgb(0, 0, 255);">return</span> 7103; } );<br />promise2.then(<span style="color: rgb(0, 0, 255);">function</span> completedHandler2 (result2) { });<br /></pre>
  </div>
</blockquote>

<p>Die Ausführungskette hierbei verläuft folgendermaßen: Zunächst wird <b>someOperationAsync</b> gestartet und gibt <i>promise1</i> zurück. Während dieses Vorgangs wird die <b>promise1.then</b>-Methode aufgerufen, die unmittelbar <i>promise2</i> zurückgibt. Berücksichtigen Sie stets, dass <b>completedHandler1</b> erst aufgerufen wird, wenn das Ergebnis des asynchronen Vorgangs bereits verfügbar ist. Nehmen wir an, dass noch auf das Ergebnis gewartet wird. Daher gehen wir direkt zum Aufruf von <b>promise2.then</b> über, wobei zu diesem Zeitpunkt <b>completedHandler2</b> auch hier <i>nicht</i> aufgerufen wird.</p>

<p>Etwas später wird <b>someOperationAsync</b> mit einem Wert von beispielsweise 14618 abgeschlossen. Da <i>promise1</i> nun erfüllt ist, wird mit diesem Wert <b>completedHandler1</b> aufgerufen, sodass <i>result1</i> 14618 beträgt. Jetzt wird <b>completedHandler1</b> ausgeführt und gibt den Wert 7103 zurück. Zu diesem Zeitpunkt ist <i>promise2</i> erfüllt, sodass <b>completedHandler2</b> mit dem Wert <i>result2</i> von 7103 aufgerufen wird.</p>

<p>Was jedoch geschieht, wenn ein Completed-Handler eine weitere Zusage zurückgibt? Dieser Fall wird etwas anders verarbeitet. Angenommen, der im obigen Code aufgeführte <b>completedHandler1</b> gibt eine Zusage zurück, z. B. so:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> promise2 = promise1.then(<span style="color: rgb(0, 0, 255);">function</span> completedHandler1 (result1) {<br />    <span style="color: rgb(0, 0, 255);">var</span> promise2a = anotherOperationAsync();<br />    <span style="color: rgb(0, 0, 255);">return</span> promise2a;<br />});<br /></pre>
  </div>
</blockquote>

<p>In diesem Fall ist <i>result2</i> in <b>completedHandler2</b> nicht <i>promise2a</i> selbst, sondern der <u>fulfillment</u>-Wert von <i>promise2a</i>. Da der Completed-Handler eine Zusage zurückgegeben hat, hat dies zur Folge, dass <i>promise2</i>, wie von <b>promise1.then</b> zurückgegeben, mit den Ergebnissen aus <i>promise2a</i> erfüllt wird.</p>

<p>Genau dieses Merkmal ermöglicht die Verkettung sequenzieller asynchroner Vorgänge, wobei die Ergebnisse jedes Vorgangs in der Kette vom nachfolgenden Vorgang genutzt werden. Ohne Zwischenvariablen oder benannte Handler weisen Zusagenketten häufig dieses Muster auf:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">operation1().then(<span style="color: rgb(0, 0, 255);">function</span> (result1) {<br />    <span style="color: rgb(0, 0, 255);">return</span> operation2(result1)<br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (result2) {<br />    <span style="color: rgb(0, 0, 255);">return</span> operation3(result2);<br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (result3) {<br />    <span style="color: rgb(0, 0, 255);">return</span> operation4(result3);<br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (result4) {<br />    <span style="color: rgb(0, 0, 255);">return</span> operation5(result4)<br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (result5) {<br />    <span style="color: rgb(0, 128, 0);">//And so on</span><br />});<br /></pre>
  </div>
</blockquote>

<p>Wahrscheinlich werden die empfangenen Ergebnisse von den jeweiligen Completed-Handler noch weiter verarbeitet, alle Ketten verfügen jedoch über diese Kernstruktur. Ebenso trifft zu, dass hier sämtliche <b>then</b>-Methoden direkt nacheinander ausgeführt werden, da sie lediglich den entsprechenden Completed-Handler speichern und eine weitere Zusage zurückgeben. Am Codeende wurde also lediglich <i>operation1</i> gestartet. Completed-Handler wurden nicht aufgerufen. Im Rahmen der zahlreichen <b>then</b>-Aufrufe wurde jedoch eine Reihe von Zwischenzusagen erstellt und untereinander verknüpft, um die Kette beim Fortsetzen der sequenziellen Vorgänge zu verwalten.</p>

<p>Bemerkenswerterweise kann die gleiche Sequenz durch das Schachteln aller nachfolgenden Vorgänge im vorherigen Completed-Handler erzielt werden, wobei die gesamten <i>return</i>-Anweisungen entfallen. Verschachtelungen dieser Art führen jedoch zu sehr komplizierten Einzugsszenarien, insbesondere, wenn Sie bei jedem <b>then</b>-Aufruf Progress- und Fehlerhandler hinzufügen.</p>

<p>Eine Funktion von Zusagen in WinJS ist außerdem, dass Fehler in einem beliebigen Kettenabschnitt automatisch an das Kettenende verteilt werden. Sie müssen also dem letzten <b>then</b>-Aufruf einfach nur einen einzigen Fehlerhandler hinzufügen, ohne Handler auf jeder Ebene zu verwenden. Der Haken ist jedoch, dass diese Fehler aus verschiedenen komplexen Gründen verloren gehen, wenn es sich beim letzten Kettenabschnitt um einen <b>then</b>-Aufruf handelt. Deshalb stellt WinJS für Zusagen außerdem eine <b>done</b>-Methode bereit. Diese Methode akzeptiert dieselben Argumente wie <b>then</b>, gibt jedoch an, dass die Kette abgeschlossen ist. (Anstelle einer weiteren Zusage wird <i>undefined</i> zurückgegeben.) Falls <b>done</b> ein Fehlerhandler hinzugefügt wurde, wird dieser für alle Fehler in der gesamten Kette aufgerufen. Weiterhin löst <b>done</b> eine Ausnahme auf App-Ebene aus, wenn kein Fehlerhandler verfügbar ist, die durch <b>window.onerror</b> von <b>WinJS.Application.onerror</b>-Ereignissen behandelt werden kann. Kurz gesagt: Im Idealfall sollten alle Ketten mit <b>done</b> enden, um sicherzustellen, dass Ausnahmen zum Vorschein kommen und ordnungsgemäß behandelt werden.</p>

<p>Wenn Sie natürlich eine Funktion schreiben, deren <i>Zweck</i> darin besteht, die letzte Zusage aus einer langen Kette von <b>then</b>-Aufrufen zurückzugeben, verwenden Sie am Ende weiterhin <b>then</b>. Für die Fehlerbehandlung ist dann die aufrufende Funktion zuständig, von der diese Zusage möglicherweise in einer vollkommen anderen Kette verwendet wird.</p>

<h2>Erstellen von Zusagen: die WinJS.Promise-Klasse</h2>

<p>Sie können zwar jederzeit auf Grundlage der <i>Promises A</i>-Spezifikation eigene Promise-Klassen erstellen, tatsächlich ist dies jedoch mit beträchtlichem Arbeitsaufwand verbunden, weshalb sich eine Bibliothek hierfür besser eignet. WinJS stellt daher die stabile, ausführlich getestete und flexible Promise-Klasse <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br211867.aspx"><b>WinJS.Promise</b></a> bereit. So können Sie mühelos Zusagen für verschiedene Werte und Vorgänge erstellen, ohne die Feinheiten der Urheber/Verbraucher-Beziehungen oder das Verhalten der <b>then</b>-Methode verwalten zu müssen.</p>

<p>Bei Bedarf können (und sollten) Sie die <b>neue WinJS.Promise</b>-Klasse (oder eine geeignete Hilfsfunktion, wie im nächsten Abschnitt erläutert) verwenden, um Zusagen sowohl für asynchrone Vorgänge als auch für bestehende (synchrone) Werte zu erstellen. Denken Sie daran, dass eine Zusage lediglich ein Codekonstrukt ist: Zusagen müssen weder einen asynchronen Vorgang noch <i>beliebige</i> andere asynchrone Elemente umschließen. Ebenso führt das einfache Umschließen eines Codeabschnitts mit einer Zusage nicht <i>automatisch</i> zur asynchronen Ausführung<i>. </i>Für dieses Verhalten müssen Sie weiterhin selbst sorgen.</p>

<p>Als einfaches Beispiel für eine direkte Verwendung von <b>WinJS.Promise</b> nehmen wir an, dass eine lange Berechnung ausgeführt werden soll (eine einfache Addition von Zahlen, beginnend bei 1 bis zu einem Maximalwert), jedoch als asynchroner Vorgang. Wir könnten einen eigenen Callbackmechanismus für eine derartige Routine entwickeln, wenn wir jedoch eine Zusage als Umschließung einsetzen, kann sie mit Zusagen anderer APIs verkettet oder verknüpft werden. (Auf ähnliche Weise umschließt die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br229787.aspx"><b>WinJS.xhr</b></a>-Funktion das asynchrone <b>XmlHttpRequest</b>-JavaScript-Objekt mit einer Zusage, damit Sie sich nicht mit der besonderen Ereignisstruktur des Objekts befassen müssen.)</p>

<p>Für lange Berechnungen kann natürlich auch ein JavaScript-Worker verwendet werden, zur Veranschaulichung bleiben wir jedoch im UI-Thread und nutzen <b>setImmediate</b>, um den Vorgang in Schritte zu unterteilen. Gehen Sie folgendermaßen vor, um eine Zusagenstruktur mit <b>WinJS.Promise</b> zu implementieren:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> calculateIntegerSum(max, step) {<br />    <span style="color: rgb(0, 128, 0);">//The WinJS.Promise constructor's argument is an initializer function that receives </span><br />    <span style="color: rgb(0, 128, 0);">//dispatchers for completed, error, and progress cases.</span><br />    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">new</span> WinJS.Promise(<span style="color: rgb(0, 0, 255);">function</span> (completeDispatch, errorDispatch, progressDispatch) {<br />        <span style="color: rgb(0, 0, 255);">var</span> sum = 0;<br /><br />        <span style="color: rgb(0, 0, 255);">function</span> iterate(args) {<br />            <span style="color: rgb(0, 0, 255);">for</span> (<span style="color: rgb(0, 0, 255);">var</span> i = args.start; i &lt; args.end; i++) {<br />                sum += i;<br />            };<br /><br />            <span style="color: rgb(0, 0, 255);">if</span> (i &gt;= max) {<br />                <span style="color: rgb(0, 128, 0);">//Complete--dispatch results to completed handlers</span><br />                completeDispatch(sum);<br />            } <span style="color: rgb(0, 0, 255);">else</span> {<br />                <span style="color: rgb(0, 128, 0);">//Dispatch intermediate results to progress handlers</span><br />                progressDispatch(sum);<br />                setImmediate(iterate, { start: args.end, end: Math.min(args.end + step, max) });<br />            }<br />        }<br />            <br />        setImmediate(iterate, { start: 0, end: Math.min(step, max) });<br />    });<br />}<br /></pre>
  </div>
</blockquote>

<p>Beim Aufrufen der <b>neuen WinJS.Promise</b>-Klasse erhält deren Konstruktor als einziges Argument eine <i>Initialisiererfunktion</i> (in diesem Fall anonym). Der Initialisierer kapselt den auszuführenden Vorgang. Beachten Sie jedoch stets, dass sich diese Funktion im UI-Thread <i>synchron</i> selbst ausführt. Falls wir also an dieser Stelle eine lange Berechnung ausführen, ohne <b>setImmediate</b> zu verwenden, wäre der UI-Thread während des ganzen Zeitraums blockiert. Auch in diesem Fall wird der Code durch das Umschließen mit einer Zusage nicht<i> </i>automatisch asynchron ausgeführt. Dies muss mithilfe der Initialisierungsfunktion festgelegt werden.</p>

<p>Als Argumente empfängt die Initialisiererfunktion drei <i>Verteiler</i> für die von Zusagen unterstützten Fälle Completed, Fehler und Progress. Wie Sie sehen, werden diese Verteiler während des Vorgangs zu geeigneten Zeitpunkten mit den richtigen Argumenten aufgerufen.</p>

<p>Ich bezeichne diese Funktionen als „Verteiler“, da sie sich von den Handlern unterscheiden, mit denen Verbraucher die <b>then</b>-Methode (bzw. <b>done</b>) der Zusage abonnieren. Hinter den Kulissen werden von WinJS Arrays dieser Handler verwaltet, weshalb eine beliebige Anzahl von Verbrauchern so viele Handler wie gewünscht abonnieren kann. Wenn Sie einen der Verteiler aufrufen, durchläuft WinJS die interne Liste und ruft sämtliche entsprechenden Handler für Sie auf. <b>WinJS.Promise</b> stellt außerdem sicher, dass von der <b>then</b>-Methode eine zum Verketten erforderliche weitere Zusage zurückgegeben wird.</p>

<p>Kurz gesagt: <b>WinJS.Promise</b> stellt alle erforderlichen Elemente im Zusammenhang mit Zusagen bereit. So können Sie sich auf den durch die Zusage dargestellten, von der Initialisiererfunktion gekapselten Kernvorgang konzentrieren.</p>

<h2>Hilfsfunktionen zum Erstellen von Zusagen</h2>

<p>Die statische <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br211664.aspx"><b>WinJS.Promise.as</b></a>-Methode stellt die primäre Hilfsfunktion zum Erstellen einer Zusage dar, da mit dieser Methode ein <i>beliebiger</i> Wert von einer Zusage umschlossen werden kann. Ein solcher Wrapper um einen bereits vorhandenen Wert wird einfach direkt in umgekehrter Richtung ausgeführt und ruft alle an <b>then</b> übergebenen Completed-Handler auf. Hierdurch können insbesondere beliebige bekannte Werte als Zusagen behandelt werden, um sie mit anderen Zusagen zu mischen oder zusammenzufassen (durch Verknüpfen und Verketten). Wenn Sie <b>as</b> auf eine bestehende Zusage anwenden, wird lediglich diese Zusage zurückgegeben.</p>

<p>Bei der anderen statischen Hilfsfunktion handelt es sich um <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br229729.aspx"><b>WinJS.Promise.timeout</b></a>, einen praktischen Wrapper für <b>setTimeout</b> und <b>setImmediate</b>. Außerdem können Sie eine Zusage erstellen, die eine zweite Zusage abbricht, falls letztere nicht innerhalb einer bestimmten Anzahl von Millisekunden erfüllt wird.</p>

<p>Berücksichtigen Sie, dass die <b>timeout</b>-Zusagen um <b>setTimeout</b> und <b>setImmediate</b> ebenfalls durch <i>undefined</i> erfüllt werden. Es stellt sich daher die Frage, wie nach dem Timeout von diesen Zusagen ein anderer Wert bereitgestellt werden kann. Dies ist aufgrund der Tatsache möglich, dass <b>then</b> eine weitere Zusage zurückgibt, die durch den Rückgabewert des Completed-Handlers erfüllt wird. Betrachten Sie beispielsweise diese Codezeile:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> p = WinJS.Promise.timeout(1000).then(<span style="color: rgb(0, 0, 255);">function</span> () { <span style="color: rgb(0, 0, 255);">return</span> 12345; });</pre>
  </div>
</blockquote>

<p>Dieser Code erstellt die Zusage <i>p</i>, die nach einer Sekunde durch den Wert 12345 erfüllt wird. Anders ausgedrückt: <b>WinJS.Promise.timeout(…).then(function () { return &lt;value>} )</b> stellt ein Muster dar, um nach dem angegebenen Timeout <i>&lt;value></i> bereitzustellen. Wenn es sich zudem bei <i>&lt;value></i> um eine weitere Zusage handelt, dient das Muster zum Bereitstellen des Erfüllungswerts aus dieser Zusage an einem Zeitpunkt nach dem Timeout.</p>

<h2>Abbrechen von Zusagen und Fehlergenerierung</h2>

<p>Vielleicht sind Ihnen die beiden Schwachstellen im oben dargestellten Code aufgefallen. Erstens besteht keine Möglichkeit, den Vorgang abzubrechen, sobald er gestartet wurde. Der zweite Mangel ist die unzureichende Fehlerbehandlung.</p>

<p>In beiden Fällen liegt die Lösung darin, dass zusagengenerierende Funktionen wie <b>calculateIntegerSum</b> immer eine Zusage zurückgeben müssen. Wenn ein Vorgang nicht abgeschlossen oder nicht einmal gestartet werden kann, weist diese Zusage den sogenannten <i>Fehlerzustand</i> auf. Dies bedeutet, dass die Zusage weder jetzt noch <i>irgendwann</i> über ein Ergebnis verfügt, das an Completed-Handler übergeben werden kann – es werden stets ausschließlich die Fehlerhandler der Zusage aufgerufen. Tatsächlich wird, falls ein Verbraucher <b>then</b> für eine sich bereits im Fehlerzustand befindende Zusage aufruft, von der Zusage unmittelbar (synchron) der an <b>then</b> übergebene Fehlerhandler aufgerufen.</p>

<p>Ein <b>WinJS.Promise</b>-Objekt wechselt aus zwei Gründen in den Fehlerzustand: Entweder ruft der Verbraucher die <b>cancel</b>-Methode des Objekts auf, oder der Fehlerverteiler wird durch den Code innerhalb der Initialisierfunktion aufgerufen. In diesem Fall wird jeglicher Fehlerwert, der in der Zusage aufgefangen oder propagiert wurde, an die Fehlerhandler übergeben. Beim Erstellen eines Vorgangs innerhalb eines <b>WinJS.Promise</b>-Objekts können Sie auch eine Instanz von <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br211689.aspx"><b>WinJS.ErrorFromName</b></a> verwenden. Hierbei handelt es sich einfach um ein JavaScript-Objekt mit einer <i>name</i>-Eigenschaft, die den Fehler identifiziert, und einer <i>message</i>-Eigenschaft für weitere Informationen. Beispielsweise empfangen Fehlerhandler beim Abbrechen einer Zusage ein Fehlerobjekt, in dem sowohl <i>name</i> als auch <i>message</i> auf „Abgebrochen“ festgelegt sind.</p>

<p>Welche Möglichkeiten bestehen jedoch, wenn der Vorgang überhaupt nicht gestartet werden kann? Wenn Sie beispielsweise <b>calculateIntegerSum</b> mit falschen Argumenten (wie 0, 0) aufrufen, sollte die Funktion direkt eine Zusage im Fehlerzustand zurückgeben, anstatt mit der Zählung zu beginnen. Dies ist der Zweck der statischen <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br229784.aspx"><b>WinJS.Promise.wrapError</b></a>-Methode. Diese Methode akzeptiert eine <b>WinJS.ErrorFromName</b>-Instanz und gibt eine Zusage zurück, die in diesem Fall anstelle einer neuen <b>WinJS.Promise</b>-Instanz zurückgegeben würde.</p>

<p>Der zweite Aspekt, der in diesem Zusammenhang berücksichtigt werden muss, ist folgender: Zwar versetzt das Aufrufen der <b>cancel</b>-Methode einer Zusage diese in den Fehlerzustand, wie jedoch kann der asynchrone Vorgang beendet werden, der gerade ausgeführt wird? In der vorherigen Implementierung ruft die <b>calculateIntegerSum</b>-Funktion einfach solange <b>setImmediate</b>, bis der Vorgang abgeschlossen ist, unabhängig vom Zustand der erstellten Zusage. Tatsächlich wird, falls der Vorgang nach dem Abbrechen der Zusage den Abschlussverteiler aufruft, dieser Abschluss von der Zusage einfach ignoriert.</p>

<p>Die Zusage benötigt daher eine Möglichkeit zur Benachrichtigung des Vorgangs, dass die Verarbeitung beendet werden kann. Hierfür akzeptiert der <b>WinJS.Promise</b>-Konstruktor ein zweites Funktionsargument, das beim Abbruch der Zusage aufgerufen wird. In unserem Beispiel müsste das Aufrufen dieser Funktion den nächsten Aufruf von <b>setImmediate</b> verhindern und dadurch die Berechnung stoppen. Zusammen mit ordnungsgemäßer Fehlerbehandlung ergibt sich so der folgende Code:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> calculateIntegerSum(max, step) {<br />    <span style="color: rgb(0, 128, 0);">//Return a promise in the error state for bad arguments</span><br />    <span style="color: rgb(0, 0, 255);">if</span> (max &lt; 1 || step &lt; 1) {<br />        <span style="color: rgb(0, 0, 255);">var</span> err = <span style="color: rgb(0, 0, 255);">new</span> WinJS.ErrorFromName(<span style="color: rgb(0, 96, 128);">&quot;calculateIntegerSum&quot;</span>, <span style="color: rgb(0, 96, 128);">&quot;max and step must be 1 or greater&quot;</span>);<br />        <span style="color: rgb(0, 0, 255);">return</span> WinJS.Promise.wrapError(err);<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">var</span> _cancel = <span style="color: rgb(0, 0, 255);">false</span>;<br /><br />    <span style="color: rgb(0, 128, 0);">//The WinJS.Promise constructor's argument is an initializer function that receives </span><br />    <span style="color: rgb(0, 128, 0);">//dispatchers for completed, error, and progress cases.</span><br />    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">new</span> WinJS.Promise(<span style="color: rgb(0, 0, 255);">function</span> (completeDispatch, errorDispatch, progressDispatch) {<br />        <span style="color: rgb(0, 0, 255);">var</span> sum = 0;<br /><br />        <span style="color: rgb(0, 0, 255);">function</span> iterate(args) {<br />            <span style="color: rgb(0, 0, 255);">for</span> (<span style="color: rgb(0, 0, 255);">var</span> i = args.start; i &lt; args.end; i++) {<br />                sum += i;<br />            };<br /><br />            <span style="color: rgb(0, 128, 0);">//If for some reason there was an error, create the error with WinJS.ErrorFromName</span><br />            <span style="color: rgb(0, 128, 0);">//and pass to errorDispatch</span><br />            <span style="color: rgb(0, 0, 255);">if</span> (<span style="color: rgb(0, 0, 255);">false</span> <span style="color: rgb(0, 128, 0);">/* replace with any necessary error check -- we don’t have any here */</span>) {<br />                errorDispatch(<span style="color: rgb(0, 0, 255);">new</span> WinJS.ErrorFromName(<span style="color: rgb(0, 96, 128);">&quot;calculateIntegerSum (scenario 7)&quot;</span>, <span style="color: rgb(0, 96, 128);">&quot;error occurred&quot;</span>));<br />            }<br /><br />            <span style="color: rgb(0, 0, 255);">if</span> (i &gt;= max) {<br />                <span style="color: rgb(0, 128, 0);">//Complete--dispatch results to completed handlers</span><br />                completeDispatch(sum); <br />            } <span style="color: rgb(0, 0, 255);">else</span> {<br />                <span style="color: rgb(0, 128, 0);">//Dispatch intermediate results to progress handlers</span><br />                progressDispatch(sum);<br /><br />                <span style="color: rgb(0, 128, 0);">//Interrupt the operation if canceled</span><br />                <span style="color: rgb(0, 0, 255);">if</span> (!_cancel) {<br />                    setImmediate(iterate, { start: args.end, end: Math.min(args.end + step, max) });<br />                }<br />            }<br />        }<br />            <br />        setImmediate(iterate, { start: 0, end: Math.min(step, max) });<br />    },<br />    <span style="color: rgb(0, 128, 0);">//Cancellation function for the WinJS.Promise constructor</span><br />    <span style="color: rgb(0, 0, 255);">function</span> () {<br />        _cancel = <span style="color: rgb(0, 0, 255);">true</span>;<br />    });<br />}<br /></pre>
  </div>
</blockquote>

<p>Insgesamt gesehen bietet das Erstellen von <b>WinJS.Promise</b>-Instanzen vielfältige Anwendungsmöglichkeiten. Wenn z. B. eine Bibliothek über eine andere asychrone Methode mit einem Webdienst kommuniziert, können Sie diese Vorgänge mit Zusagen umschließen. Sie können auch mehrere asynchrone Vorgänge (oder andere Zusagen!) aus verschiedenen Quellen in einer neuen Zusage kombinieren, für den Fall, dass die Steuerung aller beteiligten Beziehungen erforderlich ist. Selbstverständlich können Sie eigene Handler für andere asynchrone Vorgänge und deren Zusagen in den Code eines Initialisierers des <b>WinJS.Promise</b>-Objekts einfügen. Sie können diese zum Kapseln automatischer Wiederholungsmechanismen bei Netzwerktimeouts o. Ä. verwenden, als Hook in eine generische Fortschrittsanzeige-Benutzeroberfläche einfügen oder für versteckte Protokollierung oder Analysen einsetzen. Bei jeder dieser Anwendungen benötigt der restlichen Code keine Informationen zu den Details und kann einfach nur Zusagen von der Verbraucherseite verarbeiten.</p>

<p>Auf ähnliche Weise kann ein JavaScript-Worker ohne großen Aufwand von einer Zusage umschlossen werden, wodurch dessen Darstellung und Verhalten anderen asynchronen WinRT-Vorgängen entspricht. Bekanntermaßen stellen Worker ihre Ergebnisse durch einen <b>postMessage</b>-Aufruf bereit, der im Worker-Objekt in der App ein <b>message</b>-Ereignis auslöst. Der folgende Code verknüpft dieses Ereignis anschließend mit einer Zusage, die unabhängig von den Ergebnissen der jeweiligen Meldung erfüllt ist:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">// This is the function variable we're wiring up.</span><br /><span style="color: rgb(0, 0, 255);">var</span> workerCompleteDispatch = <span style="color: rgb(0, 0, 255);">null</span>;<br /><br /><span style="color: rgb(0, 0, 255);">var</span> promiseJS = <span style="color: rgb(0, 0, 255);">new</span> WinJS.Promise(<span style="color: rgb(0, 0, 255);">function</span> (completeDispatch, errorDispatch, progressDispatch) {<br />    workerCompleteDispatch = completeDispatch;<br />});<br /><br /><span style="color: rgb(0, 128, 0);">// Worker is created here and stored in the 'worker' variable</span><br /><br /><span style="color: rgb(0, 128, 0);">// Listen for worker events</span><br />worker.onmessage = <span style="color: rgb(0, 0, 255);">function</span> (e) {<br />    <span style="color: rgb(0, 0, 255);">if</span> (workerCompleteDispatch != <span style="color: rgb(0, 0, 255);">null</span>) {<br />        workerCompleteDispatch(e.data.results); <span style="color: rgb(0, 128, 0);">/* event args depends on the worker */</span><br />    }<br />}<br /><br />promiseJS.done(<span style="color: rgb(0, 0, 255);">function</span> (result) {<br />    <span style="color: rgb(0, 128, 0);">// Output for JS worker</span><br />});<br /></pre>
  </div>
</blockquote>

<p>Zum Erweitern dieses Codes zur Behandlung von Workerfehlern können Sie den Fehlerverteiler in einer anderen Variablen speichern, die Ereignisargumente des <b>message</b>-Ereignishandlers auf Fehlerinformationen überprüfen lassen und dann je nach Ergebnis den Fehlerverteiler anstelle des Abschlussverteilers aufrufen.</p>

<h2>Verknüpfen paralleler Zusagen</h2>

<p>Da Zusagen häufig zum Umschließen asynchroner Vorgänge verwendet werden, ist es durchaus möglich, dass mehrere Vorgänge parallel ausgeführt werden. In diesen Fällen muss ggf. ermittelt werden können, wann eine Zusage bzw. alle Zusagen in einer Gruppe erfüllt sind. Diesem Zweck dienen die statischen Funktionen <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br229660.aspx"><b>WinJS.Promise.any</b></a> und <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br211774.aspx"><b>WinJS.Promise.join</b></a>.</p>

<p>Beide Funktionen akzeptieren ein Wertearray oder ein Objekt mit Werteigenschaften. Bei diesen Werten kann es sich um Zusagen und beliebige andere, von <b>WinJS.Promise.as</b> umschlossene Werte handeln, sodass das ganze Array oder Objekt aus Zusagen besteht.</p>

<p>Merkmale von <b>any</b>:</p>

<ul>
  <li>Durch <b>any</b> wird eine einzelne Zusage erstellt, die bei der Erfüllung oder beim Auftreten eines Fehlers in einer der anderen Zusagen erfüllt wird (ein logisches OR). Im Grunde fügt <b>any</b><i> </i>all diesen Zusagen Completed-Handler hinzu. Sobald dann ein Completed-Handler aufgerufen wird, ruft dieser alle von der <b>any</b><i></i>-Zusage selbst empfangenen Completed-Handler auf.</li>

  <li>Nach Erfüllung der <b>any</b><i></i>-Zusage (d. h. bei Erfüllung der ersten Zusage auf der Liste) werden die anderen Vorgänge auf der Liste weiter ausgeführt und rufen jegliche Completed-, Fehler- oder Progress-Handler auf, die diesen Zusagen individuell zugeordnet sind.</li>

  <li>Wenn Sie die <b>any</b>-Zusage abbrechen, werden auch alle Zusagen auf der Liste abgebrochen.</li>
</ul>

<p>Merkmale von <b>join</b>:</p>

<ul>
  <li>Durch <b>join</b> wird eine einzelne Zusage erstellt, die bei der Erfüllung oder beim Auftreten eines Fehlers in <i>allen</i> anderen Zusagen erfüllt wird (ein logisches AND). Im Grunde fügt <b>join</b><i> </i>all diesen Zusagen Completed- sowie Fehlerhandler hinzu und wartet dann auf den Aufruf sämtlicher dieser Handler. Erst dann ruft <b>join</b> alle selbst empfangenen Completed-Handler auf.</li>

  <li>Die <b>join</b>-Zusage meldet auch den Fortschritt an alle angegebenen Progress-Handler. In diesem Fall handelt es sich beim Zwischenergebnis um ein Array der Ergebnisse aller bislang erfüllten Zusagen.</li>

  <li>Wenn Sie die <b>join</b>-Zusage abbrechen, werden auch alle noch ausstehenden Zusagen abgebrochen.</li>
</ul>

<p>Neben <b>any</b> und <b>join</b> sollen an dieser Stelle noch zwei weitere praktische, statische <b>WinJS.Promise</b>-Methoden erwähnt werden:</p>

<ul>
  <li><a href="http://msdn.microsoft.com/de-de/library/windows/apps/br211765.aspx"><b>is</b></a> ermittelt, ob es sich bei einem beliebigen Wert um eine Zusage handelt, und gibt einen booleschen Wert zurück. Im Grunde stellt die Methode sicher, dass es sich um ein Objekt mit einer als „then“ bezeichneten Funktion handelt. Tests in Bezug auf „done“ erfolgen nicht.</li>

  <li><a href="http://msdn.microsoft.com/de-de/library/windows/apps/br229727.aspx"><b>theneach</b></a><i> </i>wendet Completed-, Fehler- und Progress-Handler auf eine Gruppe von Zusagen an (mithilfe von <b>then</b>) und gibt die Ergebnisse als eine weitere Wertegruppe innerhalb einer Zusage zurück. Jeder der Handler kann <i>NULL</i> sein.</li>
</ul>

<h2>Parallele Zusagen mit sequenziellen Ergebnissen</h2>

<p>Durch <b>WinJS.Promise.join</b> und <b>WinJS.Promise.any</b> können parallele Zusagen verwendet werden, also parallele asynchrone Vorgänge. Die von <b>join</b> zurückgegebene Zusage wird wie bereits erwähnt erfüllt, wenn alle Zusagen in einem Array erfüllt sind. Diese Zusagen werden jedoch wahrscheinlich in zufälliger Reihenfolge abgeschlossen. Was wäre, wenn Sie über eine Reihe von auf diese Weise ausführbaren Vorgängen verfügen, deren Ergebnisse jedoch in wohldefinierter Reihenfolge verarbeitet werden sollen, und zwar der Reihenfolge der jeweiligen Zusagen in einem Array?</p>

<p>Hierfür muss jede nachfolgende Zusage mit der <b>join</b>-Methode aller vorherigen Zusagen verknüpft werden. Der Codeausschnitt am Anfang dieses Beitrags bewirkt genau dies. Hier ist der gleiche Code, jedoch für explizite Zusagen umgeschrieben. (Stellen Sie sich vor, <i>list</i><b> </b>sei ein Array beliebiger Werte, die als Argumente für einen hypothetischen, zusagengenerierenden asynchronen <b>doOperationAsync</b>-Aufruf dienen):</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">list.reduce(<span style="color: rgb(0, 0, 255);">function</span> callback (prev, item, i) {<br />    <span style="color: rgb(0, 0, 255);">var</span> opPromise = doOperationAsync(item);<br />    <span style="color: rgb(0, 0, 255);">var</span> join = WinJS.Promise.join({ prev: prev, result: opPromise});<br /><br />    <span style="color: rgb(0, 0, 255);">return</span> join.then(<span style="color: rgb(0, 0, 255);">function</span> completed (v) {<br />        console.log(i + <span style="color: rgb(0, 96, 128);">&quot;, item: &quot;</span> + item+ <span style="color: rgb(0, 96, 128);">&quot;, &quot;</span> + v.result);<br />    });<br />})<br /></pre>
  </div>
</blockquote>

<p>Um ein Verständnis dieses Codes zu entwickeln, sollten wir uns zunächst mit der Funktionsweise der <a href="http://msdn.microsoft.com/de-de/library/ie/ff679975%28v=vs.94%29.aspx"><b>reduce</b></a>-Methode des Arrays vertraut machen. <b>reduce</b> ruft für jedes Element im Array das hier als <b>callback</b> bezeichnete Funktionsargument auf, das vier Argumente empfängt (wovon im Code nur drei verwendet werden):</p>

<ul>
  <li><i>prev</i> – Der Wert, der vom <i>vorherigen</i> Aufruf von <b>callback</b> zurückgegeben wurde (<i>NULL</i> für das erste Element).</li>

  <li><i>item</i> – Der aktuelle Wert aus dem Array.</li>

  <li><i>i</i> – Der Index des Elements in der Liste.</li>

  <li><i>source</i> – Das ursprüngliche Array.</li>
</ul>

<p>Für das erste Element auf der Liste erhalten wir eine <b>opPromise<sub>1</sub></b> genannte Zusage. Da <b>prev</b> den Wert <i>NULL</i> aufweist, verknüpfen wir <b>[WinJS.Promise.as(null), opPromise<sub>1</sub>]</b>. Beachten Sie, das nicht <b>join</b> selbst zurückgegeben wird. Stattdessen fügen wir dieser Verknüpfung einen Completed-Handler (mit der Bezeichnung <b>completed</b>) hinzu und geben die Zusage von <b>then</b> zurück.</p>

<p>Denken Sie daran, dass die von <b>then</b> zurückgegebene Zusage bei Rückgabe des Completed-Handlers erfüllt wird. Deshalb gibt <b>callback</b> eine Zusage zurück, die erst erfüllt wird, wenn der <b>completed</b>-Handler die Ergebnisse von <b>opPromise<sub>1</sub></b> verarbeitet hat. Wenn Sie zudem an das Ergebnis einer Verknüpfung zurückdenken, wird diese durch ein Objekt mit den Ergebnissen der Zusagen auf der ursprünglichen Liste erfüllt. Dies bedeutet, dass der Erfüllungswert <i>v</i> sowohl eine <i>prev</i>-Eigenschaft als auch eine <i>result</i>-Eigenschaft aufweist, wobei letztere das Ergebnis von <b>opPromise<sub>1</sub></b> ist.</p>

<p>Beim nächsten <i>list</i>-Element wird von <b>callback</b> ein <i>prev</i>-Wert mit dem vorherigen <b>join.then</b>-Ergebnis empfangen. Anschließend erstellen wir eine neue Verknüpfung zwischen <b>opPromise<sub>1</sub>.then</b> und <b>opPromise<sub>2</sub></b>. Das Ergebnis: Diese Verknüpfung wird erst abgeschlossen, wenn sowohl <b>opPromise<sub>2</sub></b> erfüllt ist <i>und</i> der Completed-Handler für <b>opPromise<sub>1</sub></b> zurückgegeben wird. Voila! Der <b>completed<sub>2</sub></b>-Handler, den wir nun dieser <b>join</b>-Methode hinzufügen, wird erst nach Rückgabe von <b>completed<sub>1</sub></b> aufgerufen.</p>

<p>Die gleichen Abhängigkeiten bauen sich für jedes Listenelement weiter auf: Die von <b>join.then</b> für Element <i>n</i> zurückgegebene Zusage wird erst bei Rückgabe von <b>completed<i><sub>n</sub></i></b> erfüllt. Dies stellt sicher, dass die Completed-Handler in der gleichen Reihenfolge wie <i>list</i> aufgerufen werden.</p>

<h2>Zusammenfassung</h2>

<p>In diesem Beitrag haben wir erläutert, dass eine Zusage lediglich ein (wenn auch leistungsstarkes) Codekonstrukt oder eine Aufrufkonvention ist. Sie stellt die Beziehung zwischen einem Urheber dar, der zu einem beliebigen späteren Zeitpunkt Werte liefern muss, und einem Verbraucher, der über den Verfügbarkeitszeitpunkt dieser Werte informiert werden möchte. Hierbei sind Zusagen sehr gut zum Darstellen von Ergebnissen asynchroner Vorgänge geeignet und werden umfassend für in JavaScript geschriebene Windows Store-Apps verwendet. Die Spezifikation für Zusagen ermöglicht außerdem das sequenzielle Verketten asynchroner Vorgänge, in denen das Zwischenergebnis jedes Kettenglieds an das nächste übermittelt wird.</p>

<p>Die Windows-Bibliothek für JavaScript WinJS ermöglicht das stabile Implementieren von Zusagen, mit denen Sie beliebige Arten eigener Vorgänge umschließen können. Außerdem bietet sie Hilfsfunktionen für allgemeine Szenarien wie das Verknüpfen von Zusagen für parallele Vorgänge. Dank WinJS können auf diese Weise asynchrone Vorgänge sehr effizient und effektiv genutzt werden.</p>

<p>Kraig Brockschmidt 
  <br />Programmmanager, Windows Ecosystem Team 

  <br />Autor, <a href="http://blogs.msdn.com/b/microsoft_press/archive/2012/10/29/free-ebook-programming-windows-8-apps-with-html-css-and-javascript.aspx"><i>Programming Windows 8 Apps in HTML, CSS, and JavaScript</i></a></p>

<!-- Title: “Alles über Zusagen (für in JavaScript geschriebene Windows Store-Apps)” Tags: “JavaScript, Windows Store-Apps, Zusagen” --></div>]]></content:encoded>
    </item>
    <item>
      <title>Optimieren des Renderings für ListView-Elemente</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_de/optimieren-des-renderings-fr-listview-elemente</link>
      <pubDate>Tue, 25 Jun 2013 14:26:02 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_de/2013/06/25/optimieren-des-renderings-fr-listview-elemente/</guid>
      <description><![CDATA[Für viele Windows Store-Apps in JavaScript, die Collections verwenden, ist es entscheidend, dass...]]></description>
      <content:encoded><![CDATA[<div class="PostContent"> <p>Für viele <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br211385.aspx" target="_blank">Windows Store-Apps in JavaScript</a>, die Collections verwenden, ist es entscheidend, dass sie mit dem <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br211837.aspx" target="_blank">WinJS ListView-Steuerelement</a> gut zusammenarbeiten, um eine gute App-Leistung zu erreichen. Dies ist nicht verwunderlich: Wenn potenziell tausende von Elementen verwaltet und angezeigt werden müssen, fällt jede noch so kleine Optimierung für diese Vorgänge ins Gewicht. Am wichtigsten ist dabei, wie jedes dieser Elemente gerendert wird, d. h. wie und wann jedes Element im ListView-Steuerelement im DOM erstellt und in der App angezeigt wird. Insbesondere das <i>Wann</i> wird zum entscheidenden Faktor, wenn ein Benutzer schnell durch eine Liste schwenkt und erwartet, dass dies verzögerungsfrei geschieht.</p>  <p>Elementrendering wird in einer ListView entweder durch eine in HTML definierte deklarative Vorlage oder durch eine benutzerdefinierte JavaScript-<i>Renderingfunktion</i> ausgeführt, die für jedes Element in der Liste aufgerufen wird. Auch wenn die deklarative Vorlage am einfachsten ist, bietet sie nicht die Flexibilität für eine spezifische Steuerung des Prozesses. Mit einer Renderingfunktion können Sie andererseits das Rendering für jedes einzelne Element anpassen und eine Reihe von Optimierungen umsetzen, die unter <a href="http://code.msdn.microsoft.com/windowsapps/ListView-performance-39fb71f0" target="_blank">HTML ListView optimizing performance sample</a> dargestellt werden. Die Optimierungen sind Folgende:</p>  <ul>   <li>Ermöglichen einer asynchronen Bereitstellung der Elementdaten und eines gerenderten Elements, wie es von einfachen Renderingfunktionen unterstützt wird.</li>    <li>Trennen der Elementformerstellung für das allgemeine ListView-Layout von den internen Elementen. Dies wird durch einen Platzhalterrenderer unterstützt.</li>    <li>Wiederverwenden eines zuvor erstellten Elements (und dessen untergeordneten Elementen) durch Ersetzen der Daten mit einem Recycling-Platzhalterrenderer. Dadurch erübrigen sich die meisten Elementerstellungsschritte.</li>    <li>Verzögern von anspruchsvollen Anzeigevorgängen wie Laden von Bildern oder Animationen, bis das Element tatsächlich angezeigt wird und die ListView nicht mehr schnell geschwenkt wird. Dies wird mit einem mehrstufigen Renderer erreicht.</li>    <li>Zusammenfassen ähnlicher visueller Vorgänge durch einen mehrstufigen Batchverarbeitungsrenderer, um das erneute Rendern des DOM zu minimieren.</li> </ul>  <p>In diesem Beitrag werden all diese Schritte und deren Interaktion mit dem Elementrenderingprozess der ListView erläutert. Wie Sie sich vorstellen können, sind bei Optimierungen des <i>Wann</i> des Elementrenderings viele asynchrone Vorgänge involviert, d. h. viele Zusagen (Promises). Daher wird auch das Konzept der Zusagen verständlicher, das auf dem Beitrag <a href="http://blogs.msdn.com/b/windowsappdev/archive/2013/06/10/all-about-promises-for-windows-store-apps-written-in-javascript.aspx" target="_blank">All about promises</a> in diesem Blog aufbaut.</p>  <p>Im Allgemeinen gilt für alle Renderer, dass die Kernzeit (ohne zurückgestellte Prozesse) zum Rendern von Elementen auf ein Minimum reduziert sein sollte. Da die effektive Leistung der ListView stark davon abhängt, wie gut die Aktualisierungsintervalle mit den Bildschirmaktualisierungsintervallen abgestimmt sind, können bei einem Elementrenderer ein paar Millisekunden zu viel die Gesamtrenderingzeit der ListView über das nächste Aktualisierungsintervall verzögern, was zu verlorenen Frames und stotternder Anzeige führt. Klarer ausgedrückt, bei Elementrenderern ist es wirklich entscheidend, den JavaScript-Code zu optimieren.</p>  <h2>Einfache Renderer</h2>  <p>Beginnen wir mit einem kurzen Überblick, wie eine Elementrenderingfunktion, hier als <i>Renderer</i> bezeichnet, aussieht. Ein Renderer ist eine Funktion, die der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh700705.aspx" target="_blank">itemTemplate</a>-Eigenschaft der ListView anstelle eines Vorlagennamens zugewiesen wird. Diese Funktion wird bei Bedarf für Elemente aufgerufen, die die ListView in den DOM aufnehmen soll. (Eine grundlegende Dokumentation für Renderer ist auf der Seite <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh700705.aspx" target="_blank">itemTemplate</a> verfügbar, aber erst im Beispiel werden die Optimierungen ersichtlich.)</p>  <p>Vielleicht erwarten Sie, dass eine Elementrenderingfunktion einfach ein Element aus der Datenquelle der ListView erhält. Sie sollte dann die HTML-Elemente erstellen, die für ein bestimmtes Element erforderlich sind, und das Stammelement zurückgeben, das die ListView dem DOM hinzufügen kann. Dies geschieht tatsächlich, allerdings gibt es zwei zusätzliche Überlegungen. Erstens können die Elementdaten selbst asynchron geladen werden, daher ist es sinnvoll, die Elementerstellung an die Verfügbarkeit der Daten zu knüpfen. Zweitens kann der Prozess des Elementrenderings selbst andere asynchrone Vorgänge beinhalten, wie z. B. das Laden von Bildern von Remote-URIs oder das Lesen von Daten aus anderen Dateien, die in den Elementdaten angegeben sind. Die verschiedenen Stufen der hier gezeigten Optimierung ermöglichen genau diese asynchronen Prozesse zwischen der Abfrage der Elemente und der tatsächlichen Bereitstellung dieser Elemente.</p>  <p>Daher spielen Zusagen wieder eine Rolle. Die ListView übergibt dem Renderer die Elementdaten nämlich nicht einfach direkt, sie übergibt vielmehr eine Zusage für diese Daten. Und die Funktion gibt nur einer Zusage für das Stammelement des Elements zurück, nicht das Element selbst. Dadurch kann die ListView viele Elementrenderingzusagen zusammenfassen und (asynchron) warten, bis eine ganze Seite von Elementen gerendert wurde. Dies wird zur intelligenten Erstellung verschiedener Seiten auch durchgeführt: zuerst wird die Seite mit den angezeigten Elementen erstellt, dann die zwei nicht sichtbaren Seiten davor und dahinter, zu denen der Benutzer wahrscheinlich schwenken wird. Außerdem kann die ListView dank dieser zusammengefassten Zusagen das Rendern unfertiger Elemente einfach abbrechen, wenn der Benutzer wegschwenkt. Dadurch wird eine unnötige Elementerstellung vermieden.</p>  <p>So werden dieses Zusagen in der <b>simpleRenderer</b>-Funktion des Beispiels verwendet:</p>  <p> </p>  <blockquote>   <div id="codeSnippetWrapper">     <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> simpleRenderer(itemPromise) {<br />    <span style="color: rgb(0, 0, 255);">return</span> itemPromise.then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />        <span style="color: rgb(0, 0, 255);">var</span> element = document.createElement(<span style="color: rgb(0, 96, 128);">&quot;div&quot;</span>);<br />        element.className = <span style="color: rgb(0, 96, 128);">&quot;itemTempl&quot;</span>;<br />        element.innerHTML = <span style="color: rgb(0, 96, 128);">&quot;&lt;img src='&quot;</span> + item.data.thumbnail +<br />            <span style="color: rgb(0, 96, 128);">&quot;' alt='Databound image' /&gt;&lt;div class='content'&gt;&quot;</span> + item.data.title + <span style="color: rgb(0, 96, 128);">&quot;&lt;/div&gt;&quot;</span>;<br />        <span style="color: rgb(0, 0, 255);">return</span> element;<br />    });<br />}<br /></pre>
  </div>
</blockquote>

<p>In diesem Code wird zuerst ein Completed-Handler an <b>itemPromise</b> angehängt. Der Handler wird aufgerufen, wenn die Elementdaten verfügbar sind, und er erstellt daraufhin die tatsächlichen Elemente. Beachten Sie jedoch wieder, dass die Elemente nicht direkt zurückgegeben werden, es wird eine Zusage zurückgegeben, die für dieses Element erfüllt wird. Das heißt, der Rückgabewert von <b>itemPromise.then()</b> ist eine Zusage, die mit <i>element</i> erfüllt wird, wenn die ListView es benötigt.</p>

<p>Durch die Rückgabe einer Zusage können bei Bedarf andere asynchrone Prozesse abgearbeitet werden. In diesem Fall kann der Renderer diese vorläufigen Zusagen einfach aneinanderreihen und die Zusage vom letzten <b>then</b> in der Kette zurückgeben. Zum Beispiel:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> someRenderer(itemPromise) {<br />    <span style="color: rgb(0, 0, 255);">return</span> itemPromise.then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />        <span style="color: rgb(0, 0, 255);">return</span> doSomeWorkAsync(item.data);<br />    }).then(<span style="color: rgb(0, 0, 255);">function</span> (results) {<br />        <span style="color: rgb(0, 0, 255);">return</span> doMoreWorkAsync(results1);<br />    }).then(<span style="color: rgb(0, 0, 255);">function</span> (results2) {<br />        <span style="color: rgb(0, 0, 255);">var</span> element = document.createElement(<span style="color: rgb(0, 96, 128);">&quot;div&quot;</span>);<br />        <span style="color: rgb(0, 128, 0);">// use results2 to configure the element</span><br />        <span style="color: rgb(0, 0, 255);">return</span> element;<br />    });<br />}<br /></pre>
  </div>
</blockquote>

<p>Beachten Sie, dass am Ende der Kette <i>nicht</i> <b>done</b> verwendet wird, da die Zusage des letzten <b>then</b>-Aufrufs zurückgegeben wird. Die ListView behandelt alle eventuell auftretenden Fehler.</p>

<h2>Platzhalterrenderer</h2>

<p>In der nächsten Stufe der ListView-Optimierung wird ein <i>Platzhalterrenderer</i> verwendet, der die Elementerstellung in zwei Ebenen aufteilt. Dadurch kann die ListView nur die Elementteile abfragen, die zur Definition des allgemeinen Listenlayouts erforderlich sind, ohne gleichzeitig alle Elemente in jedem Element erstellen zu müssen. Im Ergebnis kann die ListView den Layoutdurchgang schnell ausführen und auf weitere Eingaben schnell reagieren. Die übrigen Bestandteile des Elements können dann später abgefragt werden.</p>

<p>Ein Platzhalterrenderer gibt anstelle einer Zusage ein Objekt mit zwei Eigenschaften zurück:</p>

<ul>
  <li><i>element</i> Das Element der höchsten Ebene in der Elementstruktur, mit dem die Größe und Form definiert werden kann und das nicht von den Elementdaten abhängig ist.</li>

  <li><i>renderComplete</i> Eine Zusage, die erfüllt wird, wenn die restlichen Elementinhalte erstellt werden. Es wird die Zusage der Kette zurückgegeben, die mit <b>itemPromise.then</b> beginnt, wie zuvor beschrieben.</li>
</ul>

<p>Die ListView kann ermitteln, ob der Renderer eine Zusage (einfacher Fall wie bisher) oder ein Objekt mit den Eigenschaften <i>element</i> und <i>renderComplete</i> (komplexere Fälle) zurückgibt. Der entsprechende Platzhalterrenderer (im Beispiel) für den vorherigen <b>simpleRenderer</b> sieht folgendermaßen aus:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> placeholderRenderer(itemPromise) {<br />    <span style="color: rgb(0, 128, 0);">// create a basic template for the item that doesn't depend on the data</span><br />    <span style="color: rgb(0, 0, 255);">var</span> element = document.createElement(<span style="color: rgb(0, 96, 128);">&quot;div&quot;</span>);<br />    element.className = <span style="color: rgb(0, 96, 128);">&quot;itemTempl&quot;</span>;<br />    element.innerHTML = <span style="color: rgb(0, 96, 128);">&quot;&lt;div class='content'&gt;...&lt;/div&gt;&quot;</span>;<br /><br />    <span style="color: rgb(0, 128, 0);">// return the element as the placeholder, and a callback to update it when data is available</span><br />    <span style="color: rgb(0, 0, 255);">return</span> {<br />        element: element,<br /><br />        <span style="color: rgb(0, 128, 0);">// specifies a promise that will be completed when rendering is complete</span><br />        <span style="color: rgb(0, 128, 0);">// itemPromise will complete when the data is available</span><br />        renderComplete: itemPromise.then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />            <span style="color: rgb(0, 128, 0);">// mutate the element to include the data</span><br />            element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;.content&quot;</span>).innerText = item.data.title;<br />            element.insertAdjacentHTML(<span style="color: rgb(0, 96, 128);">&quot;afterBegin&quot;</span>, <span style="color: rgb(0, 96, 128);">&quot;&lt;img src='&quot;</span> +<br />                item.data.thumbnail + <span style="color: rgb(0, 96, 128);">&quot;' alt='Databound image' /&gt;&quot;</span>);<br />        })<br />    };<br />}<br /></pre>
  </div>
</blockquote>

<p>Die <i>element.innerHTML</i>-Zuweisung könnte in <b>renderComplete</b> verschoben werden, da die <i>itemTempl</i>-Klasse in der Datei „css/scenario1.css“ des Beispiels die Breite und Höhe des Elements direkt angibt. Der Grund, warum sie in der <i>element</i>-Eigenschaft steht, ist, dass sie den Standardtext „…“ im Platzhalter enthält. Sie könnten genauso gut ein <i>img</i>-Element verwenden, das sich auf eine kleine Paketressource bezieht, die mit allen Elementen geteilt wird (und deshalb schnell gerendert wird).</p>

<h2>Recycling-Platzhalterrenderer</h2>

<p>Die nächste Optimierung, der <i>Recycling-Platzhalter</i>renderer, fügt Zusagen nichts Neues hinzu. Er macht den Renderer vielmehr auf einen zweiten Parameter mit dem Namen <i>recycled</i> aufmerksam, der das Stammelement eines zuvor gerenderten aber nicht mehr angezeigten Elements darstellt. Das bedeutet, dass für das recycelte Element bereits untergeordnete Elemente zur Verfügung stehen. Sie können dann einfach die Daten ersetzen und evtl. Änderungen an diesen Elementen vornehmen. Dadurch werden leistungsintensive Aufrufe zur Elementerstellung vermieden, die für neue Elemente erforderlich wären, und es wird für den Renderingprozess ziemlich viel Zeit gespart.</p>

<p>Die ListView kann eine recyceltes Element bereitstellen, wenn ihr <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br211835.aspx" target="_blank">loadingBehavior</a><b></b> auf „randomaccess“ festgelegt wird. Wenn <i>recycled</i> angegeben ist, können Sie die Daten einfach aus dem Element (und dessen untergeordneten Elementen) löschen, das Element als Platzhalter zurückgeben und dann Daten einfügen und ggf. weitere zusätzliche untergeordnete Elemente in <i>renderComplete</i> erstellen. Wenn ein Recycled-Element nicht vorhanden ist (z. B. bei der ersten Erstellung der ListView oder wenn das <b>loadingBehavior</b> „inkrementell“ ist), müssen Sie das Element neu erstellen. Hier ist der Code aus dem Beispiel für diese Variante:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> recyclingPlaceholderRenderer(itemPromise, recycled) {<br />    <span style="color: rgb(0, 0, 255);">var</span> element, img, label;<br />    <span style="color: rgb(0, 0, 255);">if</span> (!recycled) {<br />        <span style="color: rgb(0, 128, 0);">// create a basic template for the item that doesn't depend on the data</span><br />        element = document.createElement(<span style="color: rgb(0, 96, 128);">&quot;div&quot;</span>);<br />        element.className = <span style="color: rgb(0, 96, 128);">&quot;itemTempl&quot;</span>;<br />        element.innerHTML = <span style="color: rgb(0, 96, 128);">&quot;&lt;img alt='Databound image' style='visibility:hidden;'/&gt;&quot;</span> +<br />            <span style="color: rgb(0, 96, 128);">&quot;&lt;div class='content'&gt;...&lt;/div&gt;&quot;</span>;<br />    }<br />    <span style="color: rgb(0, 0, 255);">else</span> {<br />        <span style="color: rgb(0, 128, 0);">// clean up the recycled element so that we can reuse it </span><br />        element = recycled;<br />        label = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;.content&quot;</span>);<br />        label.innerHTML = <span style="color: rgb(0, 96, 128);">&quot;...&quot;</span>;<br />        img = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;img&quot;</span>);<br />        img.style.visibility = <span style="color: rgb(0, 96, 128);">&quot;hidden&quot;</span>;<br />    }<br />    <span style="color: rgb(0, 0, 255);">return</span> {<br />        element: element,<br />        renderComplete: itemPromise.then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />            <span style="color: rgb(0, 128, 0);">// mutate the element to include the data</span><br />            <span style="color: rgb(0, 0, 255);">if</span> (!label) {<br />                label = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;.content&quot;</span>);<br />                img = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;img&quot;</span>);<br />            }<br />            label.innerText = item.data.title;<br />            img.src = item.data.thumbnail;<br />            img.style.visibility = <span style="color: rgb(0, 96, 128);">&quot;visible&quot;</span>;<br />        })<br />    };<br />}<br /></pre>
  </div>
</blockquote>

<p>Überprüfen Sie <i>renderComplete</i> auf das Vorhandensein von Elementen, die Sie nicht für einen neuen Platzhalter erstellen, wie z. B. <i>label</i>, und erstellen Sie diese ggf. hier.</p>

<p>Wenn Sie recycelte Elemente allgemeiner leeren möchten, können Sie der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br211846.aspx" target="_blank">resetItem</a><b></b>-Eigenschaft der ListView eine Funktion bereitstellen. Diese Funktion enthält einen ähnlichen Code wie den oben gezeigten. Dasselbe gilt für die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh700726.aspx" target="_blank">resetGroupHeader</a><b></b>-Eigenschaft, da die Vorlagenfunktionen für Gruppenkopfzeilen genauso verwenden können wie für Elemente. Gruppenkopfzeilen haben wir bisher nicht thematisiert, da sie viel seltener sind und nicht die gleichen Leistungsanforderungen haben. Nichtsdestotrotz haben sie diese Funktion.</p>

<h2>Mehrstufige Renderer</h2>

<p>Die vorletzte Optimierung ist der <i>mehrstufige Renderer</i>. Er erweitert den Recycling-Platzhalterrenderer insoweit, dass Bilder und andere Medien so lange verzögert werden, bis der Rest des Elements vollständig im DOM repräsentiert ist. Er verzögert auch Effekte wie Animationen so lange, bis das Element tatsächlich auf dem Bildschirm angezeigt wird. Dies berücksichtigt, dass Benutzer oft ziemlich schnell in einer ListView hin- und herschwenken. Und daher ist es sinnvoll, die leistungsintensiven Prozesse asynchron zu verzögern, bis die ListView in eine ruhige Position kommt.</p>

<p>Die ListView bietet die erforderlichen Hooks als Mitglied des <b>item</b>-Ergebnisses aus <b>itemPromise</b>: eine Eigenschaft namens <b>ready</b> (eine Zusage) sowie die zwei Methoden <b>loadImage</b> und <b>isOnScreen</b>, die beide weitere Zusagen zurückgeben. Das heißt:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">renderComplete: itemPromise.then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />    <span style="color: rgb(0, 128, 0);">// item.ready, item.loadImage, and item.isOnScreen available</span><br />})<br /></pre>
  </div>
</blockquote>

<p>So werden sie verwendet</p>

<ul>
  <li><b>ready</b> gibt diese Zusage aus dem ersten Completed-Handler in Ihre Kette zurück. Diese Zusage wird erfüllt, wenn die vollständige Struktur des Elements gerendert wurde und angezeigt wird. Das bedeutet, dass Sie ein weiteres <b>then</b> mit einem Completed-Handler anhängen können, in dem Sie nach der Anzeige andere Prozesse, wie das Laden von Bildern, verarbeiten können.</li>

  <li><b>loadImage</b> lädt ein Bild von einem URI herunter und zeigt es im vorhandenen <i>img</i>-Element an, wobei eine Zusage zurückgegeben wird, die mit demselben Element erfüllt wird. Sie können einen Completed-Handler an diese Zusage anhängen, die selbst wiederum die Zusage von <b>isOnScreen</b> zurückgibt. Beachten Sie, dass <b>loadImage</b> ein <i>img</i>-Element erstellt, wenn keines vorhanden ist, und dieses dem Completed-Handler bereitstellt.</li>

  <li><b>isOnScreen</b> gibt eine Zusage zurück, deren Erfüllungswert ein boolescher Wert ist und angibt, ob das Element sichtbar ist. Bei aktuellen Implementierungen ist dieser Wert bekannt, sodass die Zusage synchron erfüllt wird. Durch Einschließen in eine Zusage kann er jedoch in einer längeren Kette verwendet werden.</li>
</ul>

<p>All dies wird in der <b>multistageRenderer</b>-Funktion des Beispiels veranschaulicht, in der der Abschluss des Ladens eines Bilds zum Starten einer Einblendanimation verwendet wird. Hier wird gezeigt, was von der <i>renderComplete</i>-Zusage zurückgegeben wird:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">renderComplete: itemPromise.then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />    <span style="color: rgb(0, 128, 0);">// mutate the element to update only the title</span><br />    <span style="color: rgb(0, 0, 255);">if</span> (!label) { label = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;.content&quot;</span>); }<br />    label.innerText = item.data.title;<br /><br />    <span style="color: rgb(0, 128, 0);">// use the item.ready promise to delay the more expensive work</span><br />    <span style="color: rgb(0, 0, 255);">return</span> item.ready;<br />    <span style="color: rgb(0, 128, 0);">// use the ability to chain promises, to enable work to be cancelled</span><br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />    <span style="color: rgb(0, 128, 0);">// use the image loader to queue the loading of the image</span><br />    <span style="color: rgb(0, 0, 255);">if</span> (!img) { img = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;img&quot;</span>); }<br />    <span style="color: rgb(0, 0, 255);">return</span> item.loadImage(item.data.thumbnail, img).then(<span style="color: rgb(0, 0, 255);">function</span> () {<br />        <span style="color: rgb(0, 128, 0);">// once loaded check if the item is visible</span><br />        <span style="color: rgb(0, 0, 255);">return</span> item.isOnScreen();<br />    });<br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (onscreen) {<br />    <span style="color: rgb(0, 0, 255);">if</span> (!onscreen) {<br />        <span style="color: rgb(0, 128, 0);">// if the item is not visible, don't animate its opacity</span><br />        img.style.opacity = 1;<br />    } <span style="color: rgb(0, 0, 255);">else</span> {<br />        <span style="color: rgb(0, 128, 0);">// if the item is visible, animate the opacity of the image</span><br />        WinJS.UI.Animation.fadeIn(img);<br />    }<br />})<br /></pre>
  </div>
</blockquote>

<p>Auch wenn sich hier viel abspielt, ist dies lediglich eine einfache Zusagekette. Der erste asynchrone Vorgang im Renderer aktualisiert einfache Teile der Elementstruktur, wie z. B. Text. Dann gibt er die Zusage in <b>item.ready</b> zurück. Wenn diese Zusage erfüllt ist, wird die asynchrone <b>loadImage</b>-Methode des Elements verwendet, um einen Bilddownload zu starten, und die <b>item.isOnScreen</b>-Zusage von diesem Completed-Handler wird zurückgegeben. Das heißt, dass das <i>onscreen</i>-Sichtbarkeitsflag an den letzten Completed-Handler in der Kette übergeben wird. Wenn diese <b>isOnScreen</b>-Zusage erfüllt ist (das Element wird angezeigt), können wichtige Vorgänge wie Animationen ausgeführt werden.</p>

<p>Das Wenn ist hier entscheidend, da es wiederum wahrscheinlich ist, dass der Benutzer in der ListView herumschwenkt, während all dies geschieht. Wenn all diese Zusagen aneinandergekettet sind, kann die ListView wie gesagt die asynchronen Vorgänge abbrechen, sobald dieses Elemente aus der Ansicht und/oder gepufferten Seiten weggeschwenkt werden. Es genügt der Hinweis, dass das ListView-Steuerelement <i>vielen</i> Leistungstests unterzogen wurde!</p>

<p>Sie sollten auch daran denken, dass das <b>then</b> in all diesen Ketten verwendet wird, da immer noch eine Zusage aus der Renderingfunktion in der <i>renderComplete</i>-Eigenschaft zurückgegeben wird. In diesen Renderern gibt es kein Ende der Kette, daher wird am Ende niemals ein <b>done</b> verwendet.</p>

<h2>Miniaturansicht-Batchverarbeitung</h2>

<p>Die letzte Optimierung ist wahrhaft das <i>Husarenstück</i> für das ListView-Steuerelement. In der Funktion namens <b>batchRenderer</b> befindet sich diese Struktur für <i>renderComplete</i> (der meiste Code wurde weggelassen):</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">renderComplete: itemPromise.then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />    <span style="color: rgb(0, 128, 0);">// mutate the element to update only the title</span><br />    <span style="color: rgb(0, 0, 255);">if</span> (!label) { label = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;.content&quot;</span>); }<br />    label.innerText = item.data.title;<br /><br />    <span style="color: rgb(0, 128, 0);">// use the item.ready promise to delay the more expensive work</span><br />    <span style="color: rgb(0, 0, 255);">return</span> item.ready;<br />    <span style="color: rgb(0, 128, 0);">// use the ability to chain promises, to enable work to be cancelled</span><br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />    <span style="color: rgb(0, 128, 0);">// use the image loader to queue the loading of the image</span><br />    <span style="color: rgb(0, 0, 255);">if</span> (!img) { img = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;img&quot;</span>); }<br />    <span style="color: rgb(0, 0, 255);">return</span> item.loadImage(item.data.thumbnail, img).then(<span style="color: rgb(0, 0, 255);">function</span> () {<br />        <span style="color: rgb(0, 128, 0);">// once loaded check if the item is visible</span><br />        <span style="color: rgb(0, 0, 255);">return</span> item.isOnScreen();<br />    });<br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (onscreen) {<br />    <span style="color: rgb(0, 0, 255);">if</span> (!onscreen) {<br />        <span style="color: rgb(0, 128, 0);">// if the item is not visible, don't animate its opacity</span><br />        img.style.opacity = 1;<br />    } <span style="color: rgb(0, 0, 255);">else</span> {<br />        <span style="color: rgb(0, 128, 0);">// if the item is visible, animate the opacity of the image</span><br />        WinJS.UI.Animation.fadeIn(img);<br />    }<br />})<br /></pre>
  </div>
</blockquote>

<p>Es ist fast dasselbe wie der <b>multistageRenderer</b>, nur dass dieser mysteriöse Aufruf der Funktion <b>thumbnailBatch</b> zwischen dem <b>item.loadImage</b>-Aufruf und der <b>item.isOnScreen</b>-Überprüfung eingefügt wurde. Das Einfügen von <b>thumbnailBatch</b> in der Kette gibt an, dass ihr Rückgabewert ein Completed-Handler sein muss, der wiederum eine andere Zusage zurückgibt.</p>

<p>Sind Sie verwirrt? Eine Erklärung folgt sogleich, zunächst aber müssen wir die Hintergründe dafür klären, was eigentlich erreicht werden soll.</p>

<p>Wenn nur eine ListView mit einem einzigen Element vorhanden wäre, wären die verschiedenen Ladeoptimierungen nicht bemerkbar. In ListViews befinden sich jedoch normalerweise viele Elemente, und die Renderingfunktion wird für jedes dieser Elemente aufgerufen. Im <b>multistageRenderer</b> des vorherigen Abschnitts startet das Rendern jedes Elements einen asynchronen <b>item.loadImage</b>-Vorgang, um die entsprechende Miniaturansicht von einem beliebigen URI herunterzuladen, und jeder Vorgang kann eine beliebige Zeit lang dauern. Für die gesamte Liste gibt es also eine Reihe von gleichzeitigen <b>loadImage</b>-Aufrufen, und das Rendern jedes Elements wartet auf die Vervollständigung der entsprechenden Miniaturansicht. So weit, so gut.</p>

<p>Eine wichtige Eigenschaft, die im <b>multistageRenderer</b> überhaupt nicht sichtbar ist, ist jedoch, dass sich das <i>img</i>-Element für die Miniaturansicht <i>bereits</i> im DOM befindet, und die <b>loadImage</b>-Funktion legt das <i>src</i>-Attribut des Bilds fest, sobald der Download abgeschlossen ist. Dies wiederum löst eine Aktualisierung im Renderingmodul aus, sobald wir von der übrigen Zusagekette zurückkehren, die danach im Wesentlichen synchron abläuft.</p>

<p>Es ist dann möglich, dass eine Reihe von Miniaturansichten in kurzer Zeit in den UI-Thread zurückkommen. Dies wird dann eine übermäßige Beanspruchung im Renderingmodul und somit eine schlechte visuelle Leistung verursachen. Um diese Überlastung zu vermeiden, sollten diese <i>img</i>-Elemente vollständig erstellt werden, <i>bevor</i> sie sich im DOM befinden, und dann sollten sie Batches hinzugefügt werden, damit sie in einem einzigen Renderingdurchlauf verarbeitet werden können.</p>

<p>Im Beispiel wird dies durch einen raffinierten Zusagecodeabschnitt, nämlich mit der Funktion <b>createBatch</b> erreicht. <b>createBatch</b> wird für die gesamte App nur einmal aufgerufen, und das Ergebnis, eine andere Funktion, wird in der Variable <b>thumbnailBatch</b> gespeichert:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> thumbnailBatch;<br />thumbnailBatch = createBatch();<br /></pre>
  </div>
</blockquote>

<p>Ein Aufruf dieser <b>thumbnailBatch</b>-Funktion wird in die Zusagekette des Renderers eingefügt. Der Zweck dieser Einfügung ist, wie es der Batchverarbeitungscode im Folgenden zeigen wird, einen Satz von geladenen <i>img</i>-Elementen zu gruppieren und diese Gruppen dann in geeigneten Intervallen zur weiteren Verarbeitung freizugeben. In der Zusagekette des Renderers muss ein Aufruf von <b>thumbnailBatch()</b> eine Completed-Handler-Funktion zurückgeben, die wiederum eine Zusage zurückgibt, und der Erfüllungswert dieser Zusage (im nächsten Schritt der Kette) muss ein <i>img</i>-Element sein, das dann dem DOM hinzugefügt werden kann. Durch das Hinzufügen der Bilder zum DOM <i>nach</i> der Batchverarbeitung wird die gesamte Gruppe im selben Renderingdurchlauf zusammengefasst.</p>

<p>Dies ist ein wichtiger Unterschied zwischen dem <b>batchRenderer</b> und dem <b>multistageRenderer</b> des vorherigen Abschnitts: Bei letzterem ist das <i>img</i>-Element der Miniaturansicht bereits im DOM vorhanden, und es wird als zweiter Parameter an <b>loadImage</b> übergeben. Wenn also <b>loadImage</b> das <i>src</i>-Attribut des Bilds festlegt, wird eine Renderingaktualisierung ausgelöst. Im <b>batchRenderer</b> wird jedoch dieses <i>img</i>-Element separat in <b>loadImage</b> (wo auch <i>src</i> festgelegt wird) erstellt, das <i>img</i> ist jedoch noch nicht im DOM. Es wird erst nach dem Abschluss des <b>thumbnailBatch</b>-Schritts dem DOM hinzugefügt und so zum Mitglied einer Gruppe eines einzigen Layoutdurchlaufs.</p>

<p>Wie funktioniert also die Batchverarbeitung? Im Folgenden ist die vollständige <b>createBatch</b>-Funktion dargestellt:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> createBatch(waitPeriod) {<br />    <span style="color: rgb(0, 0, 255);">var</span> batchTimeout = WinJS.Promise.<span style="color: rgb(0, 0, 255);">as</span>();<br />    <span style="color: rgb(0, 0, 255);">var</span> batchedItems = [];<br /><br />    <span style="color: rgb(0, 0, 255);">function</span> completeBatch() {<br />        <span style="color: rgb(0, 0, 255);">var</span> callbacks = batchedItems;<br />        batchedItems = [];<br />        <span style="color: rgb(0, 0, 255);">for</span> (<span style="color: rgb(0, 0, 255);">var</span> i = 0; i &lt; callbacks.length; i++) {<br />            callbacks[i]();<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">function</span> () {<br />        batchTimeout.cancel();<br />        batchTimeout = WinJS.Promise.timeout(waitPeriod || 64).then(completeBatch);<br /><br />        <span style="color: rgb(0, 0, 255);">var</span> delayedPromise = <span style="color: rgb(0, 0, 255);">new</span> WinJS.Promise(<span style="color: rgb(0, 0, 255);">function</span> (c) {<br />            batchedItems.push(c);<br />        });<br /><br />        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">function</span> (v) {<br />            <span style="color: rgb(0, 0, 255);">return</span> delayedPromise.then(<span style="color: rgb(0, 0, 255);">function</span> () {<br />                <span style="color: rgb(0, 0, 255);">return</span> v;<br />            });<br />        };<br />    };<br />}<br /></pre>
  </div>
</blockquote>

<p><b>createBatch</b> wird wie gesagt nur <i>einmal</i> aufgerufen, und dessen <b>thumbnailBatch</b>-Ergebnis wird für <i>jedes</i> gerenderte Element<i> </i>in der Liste aufgerufen. Der Completed-Handler, der von <b>thumbnailBatch</b> erzeugt wird, wird immer dann aufgerufen, wenn ein <b>loadImage</b>-Vorgang abgeschlossen wird.</p>

<p>Dieser Completed-Handler könnte genauso gut direkt in die Renderingfunktion eingefügt werden, es soll jedoch hier versucht werden, die Aktionen <i>über mehrere Elemente hinweg</i> und nicht nur für ein einzelnes Element zu koordinieren. Diese Koordination wird mithilfe der zwei Variablen erreicht, die zu Beginn von <b>createBatch</b> erstellt werden: <i>batchedTimeout</i> wird als leere Zusage initialisiert, und <i>batchedItems</i> wird als Array von Funktionen initialisiert, der zunächst leer ist. <b>createBatch</b> deklariert die Funktion <b>completeBatch</b>, die einfach <i>batchedItems</i> leert, indem sie jede Funktion im Array aufruft:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> createBatch(waitPeriod) {<br />    <span style="color: rgb(0, 0, 255);">var</span> batchTimeout = WinJS.Promise.<span style="color: rgb(0, 0, 255);">as</span>();<br />    <span style="color: rgb(0, 0, 255);">var</span> batchedItems = [];<br /><br />    <span style="color: rgb(0, 0, 255);">function</span> completeBatch() {<br />        <span style="color: rgb(0, 0, 255);">var</span> callbacks = batchedItems;<br />        batchedItems = [];<br />        <span style="color: rgb(0, 0, 255);">for</span> (<span style="color: rgb(0, 0, 255);">var</span> i = 0; i &lt; callbacks.length; i++) {<br />            callbacks[i]();<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">function</span> () {<br />        batchTimeout.cancel();<br />        batchTimeout = WinJS.Promise.timeout(waitPeriod || 64).then(completeBatch);<br /><br />        <span style="color: rgb(0, 0, 255);">var</span> delayedPromise = <span style="color: rgb(0, 0, 255);">new</span> WinJS.Promise(<span style="color: rgb(0, 0, 255);">function</span> (c) {<br />            batchedItems.push(c);<br />        });<br /><br />        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">function</span> (v) {<br />            <span style="color: rgb(0, 0, 255);">return</span> delayedPromise.then(<span style="color: rgb(0, 0, 255);">function</span> () {<br />                <span style="color: rgb(0, 0, 255);">return</span> v;<br />            });<br />        };<br />    };<br />}<br /></pre>
  </div>
</blockquote>

<p>Folgendes passiert nun in <b>thumbnailBatch</b> (die von <b>createBatch</b> zurückgegebene Funktion), die wieder für jedes zu renderndes Element aufgerufen wird. Zuerst werden alle vorhandenen <i>batchedTimeout</i> <i>abgebrochen</i> und gleich wieder neu erstellt:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">batchTimeout<span style="color: rgb(255, 0, 0);">.</span>cancel();<br />        batchTimeout = WinJS<span style="color: rgb(255, 0, 0);">.</span>Promise<span style="color: rgb(255, 0, 0);">.</span>timeout(waitPeriod || 64)<span style="color: rgb(255, 0, 0);">.</span>then(completeBatch);<br /></pre>
  </div>
</blockquote>

<p>In der zweiten Zeile steht das zukünftige Bereitstellungs-/Erfüllungsmuster, das im Beitrag „All About Promises“ &lt;TODO: link>beschrieben ist: <b>completeBatch</b> muss nach einer Verzögerung von <i>waitPeriod</i> Millisekunden (Standardwert 64 ms) aufgerufen werden. Das heißt, dass so lange wie <b>thumbnailBatch</b> innerhalb der <i>waitPeriod</i> eines vorhergehenden Aufrufs wieder aufgerufen wird, <b>batchTimeout</b> auf eine andere <i>waitPeriod</i> zurückgesetzt wird. Und da <b>thumbnailBatch</b> nur <i>nach</i> dem Abschluss eines <b>item.loadImage</b>-Aufrufs aufgerufen wird, bedeutet dies im Ergebnis, dass alle <b>loadImage</b>-Vorgänge, die innerhalb der <i>waitPeriod</i> des vorhergehenden Aufrufs abgeschlossen werden, in denselben Batchvorgang aufgenommen werden. Wenn eine Pause länger als <i>waitPeriod</i> eintritt, wird die Batchverarbeitung gestartet, d. h. die Bilder werden dem DOM hinzugefügt, und der nächste Batchvorgang beginnt.</p>

<p>Nach Verarbeitung dieses Timeoutcodes erstellt <b>thumbnailBatch</b> eine neue Zusage, die einfach die Abschlussverteilerfunktion in den <i>batchedItems</i>-Array übergibt:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> delayedPromise = <span style="color: rgb(0, 0, 255);">new</span> WinJS.Promise(<span style="color: rgb(0, 0, 255);">function</span> (c) {<br />         batchedItems.push(c);<br />     });<br /></pre>
  </div>
</blockquote>

<p>Sie erinnern sich an den Beitrag „All About Promises“&lt;TODO: link>, in dem erläutert wird, dass eine Zusage lediglich ein Codekonstrukt ist, und so ist es hier auch. Die neu erstellte Zusage zeigt keinerlei asynchrones Verhalten: Es wird lediglich die Abschlussverteilerfunktion <i>c</i> zu <i>batchedItems</i> hinzugefügt. Da aber der Verteiler nichts macht, bis <i>batchedTimeout</i> asynchron abgeschlossen ist, besteht de facto eine asynchrone Beziehung. Wenn das Timeout eintritt und der Batch (in <b>completeBatch</b>) geleert wird, werden alle anderen vorhandenen Completed-Handler für <b>delayedPromise.then</b> aufgerufen.</p>

<p>Die letzten Zeilen des Codes in <b>createBatch</b> stellen die Funktion dar, die von <b>thumbnailBatch</b> zurückgegeben wird. Diese Funktion ist genau der Completed-Handler, der in die gesamte Zusagekette des Renderers eingefügt wird:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">function</span> (v) {<br />           <span style="color: rgb(0, 0, 255);">return</span> delayedPromise.then(<span style="color: rgb(0, 0, 255);">function</span> () {<br />               <span style="color: rgb(0, 0, 255);">return</span> v;<br />           });<br />       };<br /></pre>
  </div>
</blockquote>

<p>Wenn dieser Codeabschnitt direkt in die Zusagekette eingefügt wird, sehen Sie die daraus resultierenden Beziehungen:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">return</span> item.loadImage(item.data.thumbnail);<br />          }).then(<span style="color: rgb(0, 0, 255);">function</span> (v) {<br />              <span style="color: rgb(0, 0, 255);">return</span> delayedPromise.then(<span style="color: rgb(0, 0, 255);">function</span> () {<br />                  <span style="color: rgb(0, 0, 255);">return</span> v;<br />              });<br />          ).then(<span style="color: rgb(0, 0, 255);">function</span> (newimg) {<br /></pre>
  </div>
</blockquote>

<p>Jetzt sehen Sie, dass das Argument <i>v</i> das Ergebnis von <b>item.loadImage</b> ist, das wiederum das erstellte <i>img</i>-Element ist. Wenn auf die Batchverarbeitung verzichtet wird, könnte einfach <b>return WinJS.Promise.as(v)</b> angegeben werden, und die gesamte Kette würde trotzdem funktionieren: <i>v</i> würde dann synchron übergeben und im nächsten Schritt als <i>newimg</i> erscheinen.</p>

<p>Wir übergeben jedoch eine Zusage von <b>delayedPromise.then</b>, die mit <i>v</i> so lange nicht erfüllt wird, bis das aktuelle <i>batchedTimeout</i> erfüllt ist. Wenn dann wieder eine Pause von <i>waitPeriod</i> zwischen <b>loadImage</b>-Vorgängen eintritt, werden diese <i>img</i>-Elemente dem nächsten Schritt in der Kette übergeben, in dem sie dem DOM hinzugefügt werden.</p>

<p>Das war's!</p>

<h2>Zusammenfassung</h2>

<p>Die fünf verschiedenen Renderingfunktionen in <a href="http://code.msdn.microsoft.com/windowsapps/ListView-performance-39fb71f0" target="_blank">HTML ListView optimizing performance sample</a> haben alle eines gemeinsam: Sie zeigen, wie die asynchrone Beziehung zwischen der ListView und dem Renderer, die durch Zusagen ausgedrückt wird, dem Renderer eine immense Flexibilität dafür verleiht, wie und wann Elemente für Listenelemente erstellt werden. Beim Schreiben Ihrer eigenen Apps hängt die Strategie für ListView-Optimierungen stark davon ab, wie groß die Datenquelle, wie komplex die Elemente selbst und wie groß die Menge der asynchron abgerufenen Daten für diese Elemente ist (z. B. Herunterladen von remoten Bildern). Natürlich werden Sie Elementrenderer so einfach wie möglich konstruieren, um Ihre Leistungsziele zu erreichen. Aber jetzt haben Sie alle erforderlichen Tools an der Hand, um der ListView und Ihrer App zur Höchstleistung zu verhelfen.</p>

<p>Kraig Brockschmidt 
  <br />Programmmanager, Windows Ecosystem Team 

  <br />Autor, <a href="http://blogs.msdn.com/b/microsoft_press/archive/2012/10/29/free-ebook-programming-windows-8-apps-with-html-css-and-javascript.aspx"><i>Programming Windows 8 Apps in HTML, CSS, and JavaScript</i></a></p>
<!-- Title: “Optimieren des Renderings für ListView-Elemente” Tags: “Windows Store-Apps, Rendern, Batchverarbeitung, Batch, Rendering, ListView” --></div>]]></content:encoded>
    </item>
    <item>
      <title>Das Game On Virtual Event</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_de/das-game-on-virtual-event</link>
      <pubDate>Wed, 12 Jun 2013 11:28:58 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_de/2013/06/12/das-game-on-virtual-event/</guid>
      <description><![CDATA[Spiele sind besonders wichtige Apps im Windows Store. Wir unterstützen Sie mit dem Virtual Game...]]></description>
      <content:encoded><![CDATA[<div class="PostContent"> <p>Spiele sind besonders wichtige Apps im Windows Store. Wir unterstützen Sie mit dem Virtual Game Building Event bei der Entwicklung von Windows Store-Spielen. Dieses Event ist kostenlos und steht sowohl neuen als auch erfahrenen Spieleentwicklern offen. </p>  <p>Wir zeigen Ihnen anhand von <a href="https://aka.ms/yoyogamesgamemaker" target="_blank">GameMaker: Studio</a> von YoYo Games wie Sie hochwertige Spiele schneller entwickeln und veröffentlichen. GameMaker: Studio verfügt über zahlreiche integrierte Entwicklungsfunktionen und Drag &amp; Drop-Tools, die den Einstieg erleichtern, wenn Sie über noch keine Idee für ein Spiel oder Entwicklungserfahrung verfügen. Und erfahrene Spieleentwickler können mit den erweiterten Tools einzigartige Spiele erstellen. </p>  <p><a href="https://aka.ms/gameonevent"><img title="clip_image002" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/8666.clip_image002_0385EAB3.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/8666.clip_5F00_image002_5F00_0385EAB3.jpg" width="500" height="154" /></a></p>  <p>Die Onlineveranstaltung beginnt am Samstag, den 15. Juni um 10:00 Uhr PDT mit einer Einführung und einem Live-Chat. Sie lernen verschiedene Spieltypen kennen, erfahren, wie Grafiken, Level und Sounds in einfache Spiele eingefügt werden, und machen sich mit Möglichkeiten zum individuellen Anpassen des Spiels vertraut. Im Laufe der Woche erhalten Sie in den GameMaker-Foren weitere persönliche Unterstützung.</p>  <p>Ob Ersteinsteiger, Anfänger oder erfahrener Profi: Dieses Event ist der perfekte Einstieg in die Bereiche Erstellen, Hochladen und Veröffentlichen von Windows Store-Spielen. Unter <a href="http://msdnevents.com/gameon/" target="_blank">http://msdnevents.com/gameon/</a> können Sie sich registrieren und erhalten weitere Informationen sowie kostenlose Tools und Ressourcen. </p>  <p>– Robert Rodriguez-Lawson, Senior Content Publishing Manager, Windows Developer Content</p> <!-- Title: “Das Game On Virtual Event” Tags: “Windows Store-Spiele, Spiele, Game On, Events” --></div>]]></content:encoded>
    </item>
    <item>
      <title>Schließfach für Anmeldeinformationen: Die Lösung bei der Verwaltung von Benutzernamen und Kennwörtern in Windows Store-Apps</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_de/schliefach-fr-anmeldeinformationen-die-lsung-bei-der-verwaltung-von-benutzernamen-und-kennwrtern-in-windows-store-apps</link>
      <pubDate>Tue, 04 Jun 2013 19:41:24 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_de/2013/06/04/schliefach-fr-anmeldeinformationen-die-lsung-bei-der-verwaltung-von-benutzernamen-und-kennwrtern-in-windows-store-apps/</guid>
      <description><![CDATA[Wenn Sie bisher noch nichts vom Schließfach für Anmeldeinformationen, das für Windows Store-Apps...]]></description>
      <content:encoded><![CDATA[<div class="PostContent"> <p>Wenn Sie bisher noch nichts vom <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh465069.aspx" target="_blank">Schließfach für Anmeldeinformationen</a>, das für Windows Store-Apps verfügbar ist, mitbekommen haben, dann wird es jetzt langsam Zeit. Warum? Das Schließfach vereinfacht nicht nur die Aufgabe des <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh465060.aspx" target="_blank">Speicherns</a> und <a href="http://msdn.microsoft.com/de-de/library/windows/apps/jj839731.aspx" target="_blank">Abrufens der Anmeldeinformationen</a>, sondern es bietet dabei zusätzlich Sicherheit, und die Anmeldeinformationen sind per Microsoft-Konto überall kostenlos verfügbar.</p>  <p>Angenommen, Sie haben eine App, die sich mit einem Dienst zum Zugriff auf geschützte Ressourcen verbindet, wie z. B. Mediendateien, soziale Netzwerke usw., und Ihr Dienst benötigt für jeden Benutzer Anmeldeinformationen. Sie haben also eine Benutzeroberfläche in Ihre App integriert, mit der Benutzername und Kennwort eines Benutzers abgerufen werden. Diese Informationen werden dann zur Anmeldung des Benutzers beim Dienst verwendet. Alles funktioniert wie geschmiert.</p>  <p>Sie möchten jetzt jedoch Ihren Funktionsumfang erweitern und es den Benutzern möglich machen, ihre Anmeldeinformationen sicher zu speichern, sodass diese sich nicht bei jedem Öffnen Ihrer App wieder anmelden müssen. Hier kommt das Schließfach für Anmeldeinformationen ins Spiel. Mit nur wenigen einfachen Aufrufen der zugehörigen API lassen sich Benutzername und Kennwort der Benutzer speichern und problemlos wieder abrufen, sodass der Benutzer beim nächsten Öffnen Ihrer App wieder angemeldet wird.</p>  <h2>Sicheres Speichern</h2>  <p>Der größte Vorteil des Schließfachs für Anmeldeinformationen für Ihre App liegt darin, dass die Anmeldeinformationen an einem sichern Ort gespeichert und bei der Speicherung auf einem Datenträger verschlüsselt werden. Sie könnten die Benutzerinformationen natürlich in einer Datei im lokalen Speicher Ihrer App speichern, das Speichern der Anmeldeinformationen in reiner Textform stellt jedoch ein erhebliches Sicherheitsrisiko dar. Wenn das System eines Benutzers auf irgendeine Art und Weise beeinträchtigt wurde, können Benutzername und Kennwort problemlos ausgelesen und manipuliert werden. Wenn Benutzername und Kennwort jedoch im Schließfach für Anmeldeinformationen gespeichert sind, erhält ein böswilliger Angreifer im Höchstfall nur eine verschlüsselte Datei.</p>  <p>Jeder Windows-PC-Benutzer hat sein eigenes Schließfach für Anmeldeinformationen und der Zugriff auf einen Satz von Anmeldedaten ist auf die App beschränkt, die den Anmeldedatensatz gespeichert hat. Das heißt, dass Sie nur Anmeldedaten abrufen können, die für Ihre App gespeichert wurden. Dies bedeutet andererseits auch, dass andere Apps nicht auf die Anmeldedaten zugreifen können, die für Ihre App im Schließfach gespeichert wurden.</p>  <h2>Roaming der Anmeldeinformationen</h2>  <p>Ein weiterer Vorteil beim Speichern von Benutzername und Kennwort mithilfe des Schließfachs für Anmeldeinformationen besteht für die Benutzer darin, dass die Anmeldedaten über das Microsoft-Konto auf jeden gewünschten sicheren Computer übertragen werden, den die Benutzer mit dem entsprechenden Microsoft-Konto verwenden. Dies macht Ihre App, neben der erhöhten Sicherheit, noch benutzerfreundlicher, da die Benutzer auf jedem vertrauenswürdigen Computer, auf dem Ihre App installiert wurde, mittels Verknüpfung des Microsoft-Kontos automatisch angemeldet werden können, ohne erneut zur Eingabe der Anmeldeinformationen aufgefordert zu werden.</p>  <p>Bei Domänenkonten sieht das jedoch ein wenig anders aus. Wenn mittels Microsoft-Konto gespeicherte Anmeldedaten vorhanden sind und dieses Konto mit einem Domänenkonto verknüpft wird (wie beispielsweise einem Konto am Arbeitsplatz), werden die Anmeldedaten auf dieses Domänenkonto übertragen. Neu Anmeldedaten, die während einer Domänenkontositzung hinzugefügt wurden, werden jedoch nicht übertragen. Dadurch wird sichergestellt, dass private Anmeldedaten für die Domäne nicht außerhalb der Domäne veröffentlicht werden.</p>  <h2>Speichern von Benutzeranmeldeinformationen</h2>  <p>Das Speichern der Benutzeranmeldeinformationen im Schließfach für Anmeldeinformationen ist ein einfaches Verfahren in zwei Schritten. Zunächst wird ein Verweis auf das Schließfach für Anmeldeinformationen mithilfe des <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.security.credentials.passwordvault.aspx" target="_blank">PasswordVault</a>-Objekts aus dem <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.security.credentials.aspx" target="_blank">Windows.Security.Credentials</a>-Namespace abgerufen. Anschließend erstellen Sie ein <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.security.credentials.passwordcredential.aspx" target="_blank">PasswordCredential</a>-Objekt, das einen Bezeichner für Ihre App, den Benutzernamen und das Kennwort enthält. Dieses Objekt wird an die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh701231.aspx" target="_blank">PasswordVault.Add()</a>-Methode übergeben, um den Anmeldedatensatz an das Schließfach zu übergeben.</p>  <p><strong>C#</strong></p>  <blockquote>   <div id="codeSnippetWrapper">     <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">var vault = <span style="color: rgb(0, 0, 255);">new</span> Windows.Security.Credentials.PasswordVault();<br />vault.Add(<span style="color: rgb(0, 0, 255);">new</span> Windows.Security.Credentials.PasswordCredential(<br />    <span style="color: rgb(0, 96, 128);">&quot;My App&quot;</span>, username, password));<br /></pre>
  </div>
</blockquote>

<p><strong>JavaScript</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> vault = <span style="color: rgb(0, 0, 255);">new</span> Windows.Security.Credentials.PasswordVault();<br />vault.add(<span style="color: rgb(0, 0, 255);">new</span> Windows.Security.Credentials.PasswordCredential(<br />    <span style="color: rgb(0, 96, 128);">&quot;My App&quot;</span>, username, password));<br /></pre>
  </div>
</blockquote>

<h2>Abrufen von Benutzeranmeldeinformationen</h2>

<p>Es gibt verschiedene Wege, Benutzerinformationen aus dem Schließfach für Anmeldeinformationen abzurufen, nachdem Sie einen Verweis auf das <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.security.credentials.passwordvault.aspx" target="_blank">PasswordVault</a>-Objekt erstellt haben.</p>

<ul>
  <li>Sie können alle Informationen, die der Benutzer im Schließfach für Ihre App angegeben hat, mit der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.security.credentials.passwordvault.retrieveall.aspx" target="_blank">PasswordVault.RetrieveAll()</a>-Methode abrufen.</li>

  <li>Wenn Sie den Benutzernamen der gespeicherten Anmeldeinformationen kennen, können Sie alle Anmeldedaten für diesen Benutzernamen mit der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.security.credentials.passwordvault.findallbyusername.aspx" target="_blank">PasswordVault.FindAllByUserName()</a>-Methode abrufen.</li>

  <li>Wenn Sie den Ressourcennamen für die gespeicherten Anmeldeinformationen kennen, können Sie alle Anmeldeinformationen für diesen Ressourcennamen mit der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.security.credentials.passwordvault.findallbyresource.aspx" target="_blank">PasswordVault.FindAllByResource()</a>-Methode abrufen.</li>

  <li>Als letzte Möglichkeit können Sie bei bekanntem Benutzer- sowie Ressourcennamen eines Anmeldedatensatzes ausschließlich die Anmeldeinformationen mit der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.security.credentials.passwordvault.retrieve.aspx" target="_blank">PasswordVault.Retrieve()</a>-Methode abrufen.</li>
</ul>

<p>Sehen wir uns nun ein Beispiel an, bei dem der Ressourcenname global in einer App gespeichert wurde und bei dem der Benutzer automatisch angemeldet wird, wenn ein Anmeldedatensatz für diesen gefunden wird. Falls mehrere Anmeldedatensätze für einen Benutzer gefunden werden, wird eine Aufforderung zur Auswahl der Standardanmeldeinformationen für dessen Anmeldung angezeigt.</p>

<p><strong>C#</strong></p>

<blockquote>
  <div>
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">string</span> resourceName = <span style="color: rgb(0, 96, 128);">&quot;My App&quot;</span>;<br /><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">string</span> defaultUserName;<br /><br /><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> Login()<br />{<br />    var loginCredential = GetCredentialFromLocker();<br /><br />    <span style="color: rgb(0, 0, 255);">if</span> (loginCredential != <span style="color: rgb(0, 0, 255);">null</span>)<br />    {<br />        <span style="color: rgb(0, 128, 0);">// There is a credential stored in the locker.</span><br />        <span style="color: rgb(0, 128, 0);">// Populate the Password property of the credential</span><br />        <span style="color: rgb(0, 128, 0);">// for automatic login.</span><br />        loginCredential.RetrievePassword();<br />    }<br />    <span style="color: rgb(0, 0, 255);">else</span><br />    {<br />        <span style="color: rgb(0, 128, 0);">// There is no credential stored in the locker.</span><br />        <span style="color: rgb(0, 128, 0);">// Display UI to get user credentials.</span><br />        loginCredential = GetLoginCredentialUI();<br />    }<br /><br />    <span style="color: rgb(0, 128, 0);">// Log the user in.</span><br />    ServerLogin(loginCredential.UserName, loginCredential.Password);<br />}<br /><br /><br /><span style="color: rgb(0, 0, 255);">private</span> Windows.Security.Credentials.PasswordCredential GetCredentialFromLocker()<br />{<br />    Windows.Security.Credentials.PasswordCredential credential = <span style="color: rgb(0, 0, 255);">null</span>;<br /><br />    var vault = <span style="color: rgb(0, 0, 255);">new</span> Windows.Security.Credentials.PasswordVault();<br />    var credentialList = vault.FindAllByResource(resourceName);<br />    <span style="color: rgb(0, 0, 255);">if</span> (credentialList.Count &gt; 0)<br />    {<br />        <span style="color: rgb(0, 0, 255);">if</span> (credentialList.Count == 1)<br />        {<br />            credential = credentialList[0];<br />        }<br />        <span style="color: rgb(0, 0, 255);">else</span><br />        {<br />            <span style="color: rgb(0, 128, 0);">// When there are multiple usernames,</span><br />            <span style="color: rgb(0, 128, 0);">// retrieve the default username. If one doesn’t</span><br />            <span style="color: rgb(0, 128, 0);">// exist, then display UI to have the user select</span><br />            <span style="color: rgb(0, 128, 0);">// a default username.</span><br /><br />            defaultUserName = GetDefaultUserNameUI();<br /><br />            credential = vault.Retrieve(resourceName, defaultUserName);<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">return</span> credential;<br />}<br /></pre>
  </div>
</blockquote>

<div>
  <br /><strong>JavaScript</strong></div>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> resourceName = <span style="color: rgb(0, 96, 128);">&quot;My App&quot;</span>;<br /><span style="color: rgb(0, 0, 255);">var</span> defaultUserName;<br /><br /><span style="color: rgb(0, 0, 255);">function</span> login() {<br />    <span style="color: rgb(0, 0, 255);">var</span> loginCredential = getCredentialFromLocker();<br /><br />    <span style="color: rgb(0, 0, 255);">if</span> (loginCredential != <span style="color: rgb(0, 0, 255);">null</span>) {<br />        <span style="color: rgb(0, 128, 0);">// There is a credential stored in the locker.</span><br />        <span style="color: rgb(0, 128, 0);">// Populate the Password property of the credential</span><br />        <span style="color: rgb(0, 128, 0);">// for automatic login.</span><br />        loginCredential.retrievePassword();<br />    } <span style="color: rgb(0, 0, 255);">else</span> {<br />        <span style="color: rgb(0, 128, 0);">// There is no credential stored in the locker.</span><br />        <span style="color: rgb(0, 128, 0);">// Display UI to get user credentials.</span><br />        loginCredential = getLoginCredentialUI();<br />    }<br /><br />    <span style="color: rgb(0, 128, 0);">// Log the user in.</span><br />    serverLogin(loginCredential.userName, loginCredential.password);<br />}<br /><br /><br /><span style="color: rgb(0, 0, 255);">function</span> GetCredentialFromLocker() {<br />    <span style="color: rgb(0, 0, 255);">var</span> credential = <span style="color: rgb(0, 0, 255);">null</span>;<br /><br />    <span style="color: rgb(0, 0, 255);">var</span> vault = <span style="color: rgb(0, 0, 255);">new</span> Windows.Security.Credentials.PasswordVault();<br />    <span style="color: rgb(0, 0, 255);">var</span> credentialList = vault.findAllByResource(resourceName);<br />    <span style="color: rgb(0, 0, 255);">if</span> (credentialList.length &gt; 0) {<br />        <span style="color: rgb(0, 0, 255);">if</span> (credentialList.length == 1) {<br />            credential = credentialList[0];<br />        } <span style="color: rgb(0, 0, 255);">else</span> {<br />            <span style="color: rgb(0, 128, 0);">// When there are multiple usernames,</span><br />            <span style="color: rgb(0, 128, 0);">// retrieve the default username. If one doesn’t</span><br />            <span style="color: rgb(0, 128, 0);">// exist, display UI to have the user select</span><br />            <span style="color: rgb(0, 128, 0);">// a default username.</span><br /><br />            defaultUserName = getDefaultUserNameUI();<br />            credential = vault.retrieve(resourceName, defaultUserName);<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">return</span> credential;<br />}<br /></pre>
  </div>
</blockquote>

<h2>Löschen von Benutzeranmeldeinformationen</h2>

<p>Das Löschen der Benutzeranmeldeinformationen im Schließfach für Anmeldeinformationen ist auch ein einfaches Verfahren, das zwei Schritte umfasst. Zunächst wird wieder ein Verweis auf das Schließfach für Anmeldeinformationen mithilfe des <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.security.credentials.passwordvault.aspx" target="_blank">PasswordVault</a>-Objekts aus dem <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.security.credentials.aspx" target="_blank">Windows.Security.Credentials</a>-Namespace abgerufen. Anschließend werden die zu löschenden Anmeldeinformationen an die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh701242.aspx" target="_blank">PasswordVault.Remove()</a>-Methode übergeben.</p>

<p><strong>C#</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">var vault = <span style="color: rgb(0, 0, 255);">new</span> Windows.Security.Credentials.PasswordVault();<br />vault.Remove(<span style="color: rgb(0, 0, 255);">new</span> Windows.Security.Credentials.PasswordCredential(<br />    <span style="color: rgb(0, 96, 128);">&quot;My App&quot;</span>, username, password));<br /></pre>
  </div>
</blockquote>

<p><strong>JavaScript</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> vault = <span style="color: rgb(0, 0, 255);">new</span> Windows.Security.Credentials.PasswordVault();<br />vault.remove(<span style="color: rgb(0, 0, 255);">new</span> Windows.Security.Credentials.PasswordCredential(<br />    <span style="color: rgb(0, 96, 128);">&quot;My App&quot;</span>, username, password));<br /></pre>
  </div>
</blockquote>

<h2>Einfach und sicher</h2>

<p>Wie Sie sehen, handelt es sich beim Schließfach für Anmeldeinformationen um ein einfach zu verwendendes Feature, mit dem die Authentifizierung der Benutzer und das Speichern der Anmeldeinformationen auf äußerst sichere Art und Weise für die zukünftige Verwendung erleichtert wird.</p>

<p>Weitere Informationen zur Windows 8-App-Authentifizierung finden Sie u. a. im Artikel zum <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh465281.aspx" target="_blank">Webauthentifizierungsbroker</a>, den Sie zum Abrufen eines Authentifizierungstokens von einer Website (z. B.: OAuth) verwenden können, und unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh770853.aspx" target="_blank">Personalisieren von Apps mit Live Connect (Windows Store-Apps mit JavaScript und HTML)</a>.</p>

<p>Weitere Informationen finden Sie unter:</p>

<ul>
  <li><a href="http://msdn.microsoft.com/de-de/library/windows/apps/br211367.aspx" target="_blank">Verwalten von Benutzerinformationen (JavaScript)</a></li>

  <li><a href="http://msdn.microsoft.com/de-de/library/windows/apps/xaml/BR229572(v=win.10).aspx" target="_blank">Verwalten von Benutzerinformationen (Windows Store-Apps mit C#/VB/C++ und XAML)</a></li>

  <li><a href="http://code.msdn.microsoft.com/windowsapps/PasswordVault-f01be74a" target="_blank">Beispiel zum Schließfach für Anmeldeinformationen</a></li>

  <li><a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.security.credentials.aspx" target="_blank">Windows.Security.Credentials</a></li>
</ul>

<p><i></i></p>

<p>– Doug Rothaus, Senior Content Developer, Windows Developer Content</p>

<p>Besonderer Dank geht an Yashar Bahman für seine Hilfe und Beteiligung an diesem Blogbeitrag.</p>
<!-- Title: “Schließfach für Anmeldeinformationen: Die Lösung bei der Verwaltung von Benutzernamen und Kennwörtern in Windows Store-Apps” Tags: “Abrufen von Anmeldeinformationen, Speichern von Anmeldeinformationen, sicheres Speichern, Schließfach für Anmeldeinformationen” --></div>]]></content:encoded>
    </item>
    <item>
      <title>Erstellen von standortbezogenen Apps mit Geolocation und Bing Maps</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_de/erstellen-von-standortbezogenen-apps-mit-geolocation-und-bing-maps</link>
      <pubDate>Tue, 28 May 2013 11:02:26 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_de/2013/05/28/erstellen-von-standortbezogenen-apps-mit-geolocation-und-bing-maps/</guid>
      <description><![CDATA[Sie können App-Benutzern ganz einfach Informationen über das Wetter, Sonderangebote,...]]></description>
      <content:encoded><![CDATA[<div class="PostContent"> <p>Sie können App-Benutzern ganz einfach Informationen über das Wetter, Sonderangebote, Sportveranstaltungen oder Konzerte in der Umgebung zukommen lassen, indem Sie den jeweiligen Aufenthaltsort mit der Geschäftslogik Ihrer App verknüpfen. Mit den <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br229921.aspx" target="_blank">Geolocation</a>-Klassen von Windows 8 können Sie zusammen mit dem Bing Maps-SDK großartige <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh465148.aspx" target="_blank">standortabhängige Windows Store-Apps</a> erstellen.</p>  <p>Lassen Sie uns näher betrachten, wie Ihre App den <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br225603.aspx" target="_blank">Positionsdienst</a> einsetzen kann, um dem Benutzer standortabhängige Informationen auf Basis einer IP-Adresse, eines WiFi-Netzwerks oder GPS-Daten anzuzeigen. Wenn Sie die Position abgerufen haben, können Sie Benutzern über das Bing Maps-SDK anzeigen, wo sie sich gerade aufhalten. </p>  <h2>Abrufen der Position</h2>  <p>Die Position wird mit dem <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.devices.geolocation.aspx">Windows.Devices.Geolocation</a>-Namespace abgerufen. Zwei wesentliche Faktoren entscheiden, ob Sie GPS, ein WiFi-Netzwerk oder eine IP-Adresse zum Abrufen der Benutzerposition verwenden:</p>  <ol>   <li>Die erforderliche Genauigkeit. Hier handelt es sich um den Grad an Genauigkeit, der die Anforderungen Ihrer App erfüllt. </li>    <li>Die Verfügbarkeit von Positionsdaten. Nicht alle Geräte verfügen über ein integriertes GPS. Ein Netzwerk oder eine WiFi-Verbindung ist beim Abrufen der Position möglicherweise nicht verfügbar.</li> </ol>  <h3><a>Gewünschte Genauigkeit</a></h3>  <p>Beim Abrufen einer Position sollte Ihre App die gewünschte Genauigkeit in der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.devices.geolocation.geolocator.desiredaccuracy.aspx" target="_blank">desiredAccuracy</a>-Eigenschaft angeben, damit die Positionsdaten im entsprechenden Bereich so schnell wie möglich zurückgegeben werden können. Jeder Positionstyp verfügt über eine unterschiedliche Genauigkeit:</p>  <ul>   <li><a href="http://de.wikipedia.org/wiki/GPS" target="_blank">GPS</a> – GPS bietet die größte Genauigkeit (bis ungefähr zehn Meter). Wenn der GPS-Sensor jedoch zunächst „aufwachen“, Satellitendaten abrufen und anschließend triangulieren muss, kann das Zurückgeben der Positionsinformationen bis zu zwei Minuten dauern. Ist die GPS-Satellitenverbindungen jedoch bereits vorhanden, kann die nächste Position wesentlich schneller abgerufen werden. Doch die ständige Verwendung des GPS erhöht den Stromverbrauch. Die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.devices.geolocation.geolocator.desiredaccuracy.aspx" target="_blank">Geolocator.DesiredAccuracy</a>-Eigenschaft muss auf „High“ festgelegt werden, damit das GPS Daten abrufen kann.</li>    <li><a href="http://de.wikipedia.org/wiki/Wi-Fi" target="_blank">WiFi</a> – Über eine WiFi-Verbindung lässt sich eine Genauigkeit im Bereich von 300 bis 500 Metern erzielen. Ist eine Verbindung vorhanden, können die Positionsdaten schneller zurückgegeben werden, als über ein GPS, das zuerst eine Satellitenverbindung herstellen muss. Legen Sie die „DesiredAccuracy“-Eigenschaft auf „Default“ fest, um die Position über WiFi abzufragen.</li>    <li><a href="http://de.wikipedia.org/wiki/IP-Adresse" target="_blank">IP</a> – Die Auflösung auf IP-Basis hat eine Genauigkeit von ungefähr einem Kilometer. Bei bestehender Netzwerkverbindung können die Positionsdaten schneller zurückgegeben werden, als über ein GPS, das zuerst eine Satellitenverbindung herstellen muss. Legen Sie die „DesiredAccuracy“-Eigenschaft ebenfalls auf „Default“ fest, um die Position über die IP-Adresse abzufragen. Der Positionsdienst gibt die maximal verfügbare Genauigkeit zurück und gibt diese in der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.devices.geolocation.geocoordinate.accuracy.aspx" target="_blank">Geocoordinate.Accuracy</a>-Eigenschaft an.</li> </ul>  <p>Bedenken Sie die gewünschte Genauigkeit sorgfältig. Sie kann die Leistung Ihrer App und den Stromverbrauch des Geräts wesentlich beeinflussen. Wenn Ihre App beispielsweise eine Wettervorhersage bietet, benötigen Sie sicher nicht die Genauigkeit von GPS-Daten. Stellen Sie gleichzeitig sicher, die Genauigkeit Ihrer Daten zu veranschaulichen, indem Sie einen Fehlerbereich auf Basis der Genauigkeit der gelieferten Daten anzeigen. Hier der C#-Code zum Festlegen der gewünschten Genauigkeit:</p>  <p><strong>C#</strong></p>  <blockquote>   <div id="codeSnippetWrapper">     <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">Geolocator geolocator = <span style="color: rgb(0, 0, 255);">new</span> Geolocator();<br />geolocator.DesiredAccuracy = Windows.Devices.Geolocation.PositionAccuracy.High;<br /></pre>
  </div>
</blockquote>

<br />Unabhängig von der von Ihnen gewünschten Genauigkeit lautet der Aufruf der Positionsdaten: 

<p><strong>C#</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">Geoposition pos = await geolocator.GetGeopositionAsync().AsTask(token);</pre>
  </div>
</blockquote>

<p>Hier der JavaScript-Code, der eine Instanz der „Geolocator“-Klasse erstellt, die gewünschte Genauigkeit festlegt und anschließend die derzeitige Position abruft. Beachten Sie, dass die unten verwendete „promise“-Variable ein <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br211867.aspx" target="_blank">WinJS.Promise</a>-Objekt ist. Sie müssen die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh701079.aspx" target="_blank">done</a>-Methode für den Zugriff auf die Daten von <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br225537.aspx" target="_blank">getGeopositionAsync</a> verwenden.</p>

<p><strong>JavaScript</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> geolocator = Windows.Devices.Geolocation.Geolocator();<br />geolocator.desiredAccuracy =<br />Windows.Devices.Geolocation.PositionAccuracy.high;<br /><br /><span style="color: rgb(0, 128, 0);">// Get the geoposition, capturing the request in a 'promise' object.</span><br /><span style="color: rgb(0, 0, 255);">var</span> promise = geolocator.getGeopositionAsync();<br /></pre>
  </div>
</blockquote>

<br />Bedenken Sie, dass auch wenn Sie die gewünschte Genauigkeit auf „High“ festlegen, Sie nicht sicher davon ausgehen können, dass das Gerät des Benutzers eine hohe Genauigkeit zurückgeben kann. Ein PC verfügt möglicherweise nicht über GPS, dieses ist ausgeschaltet oder der PC ist nicht mit einem WiFi-Netzwerk verbunden. Bereiten Sie immer einen angemessenen Umgang mit weniger genauen Daten vor. Die Vorgehensweise ist abhängig von den Funktionen Ihrer App. Können Sie mit einer geringeren Genauigkeit fortfahren? Können Sie eine Genauigkeit auf GPS-Niveau als erforderlich festlegen? Weitere Informationen finden Sie in den <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh465148.aspx" target="_blank">Richtlinien für standortabhängige Anwendungen</a>. 

<h3>Bing Maps</h3>

<p>Die <a href="http://apps.microsoft.com/windows/de-de/app/maps/97a2179c-38be-45a3-933e-0d2dbf14a142" target="_blank">Karten-App</a> ist ein gutes Beispiel für eine App, die sich an die Genauigkeit der verfügbaren Positionsdaten anpasst. Auf einem Desktop-PC, der üblicherweise nicht über GPS oder WiFi verfügt, wird der Standort auf Basis der IP-Adresse ermittelt und <a>auf Regionsebene gezoomt</a>. Auf einem Laptop, der üblicherweise über eine WiFi-Karte verfügt, wird diese zur genaueren Bestimmung der Position verwendet und die Anzeige der aktuellen Position vergrößert dargestellt. Wenn der Benutzer die Darstellung weiter vergrößert, zeigt das Symbol für den aktuellen Standort einen Fehlerbereich an. Auf einem GPS-Gerät kann Bing Maps die Position mit der höchsten Genauigkeit ermitteln und eine recht genaue Position darstellen.</p>

<h3>Bing Weather</h3>

<p>Wie bereits erwähnt, benötigt eine App wie beispielsweise die <a href="http://apps.microsoft.com/webpdp/app/421ba874-f903-4965-9b82-d60f3ba3cae0" target="_blank">Wetter-App</a> lediglich Positionsdaten für die Umgebung. Daher kann sie festlegen, dass sie nur Daten mit geringer Genauigkeit benötigt, um sehr schnell einen Positionswert zu erhalten. Auf diese Weise reagiert die App schneller auf Benutzereingaben. Andere Apps, die nur eine geringe Genauigkeit benötigen, sind beispielsweise Informationen zu Radiosendern, Sonderangeboten oder lokale Nachrichten-Feeds.</p>

<h2>Anzeigen von Positionsdaten mit dem Bing Maps-SDK</h2>

<p>Wenn Sie die Positionsdaten über den Aufruf von <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.devices.geolocation.geolocator.getgeopositionasync.aspx" target="_blank">GetGeopositionAsync</a> erhalten haben, möchten Sie diese auf einer Karte darstellen.</p>

<ul>
  <li>Konvertieren Sie mit dem folgenden Code zunächst die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.devices.geolocation.geoposition.aspx" target="_blank">Geoposition</a> in eine <a href="http://msdn.microsoft.com/de-de/library/hh846500.aspx" target="_blank">Location</a>, die mit Bing Maps verwendet werden kann:</li>
</ul>

<p> </p>

<p><strong>C#</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">Location location = <span style="color: rgb(0, 0, 255);">new</span> Location(pos.Coordinate.Latitude, pos.Coordinate.Longitude);</pre>
  </div>
</blockquote>

<p><strong>JavaScript:</strong></p>

<blockquote>
  <div>
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">promise.done(<br />  <span style="color: rgb(0, 0, 255);">function</span> (pos) {<br />    <span style="color: rgb(0, 128, 0);">// Get the coordinates of the current location.</span><br />    <span style="color: rgb(0, 0, 255);">var</span> coord = pos.coordinate,<br />    location = <span style="color: rgb(0, 0, 255);">new</span> Microsoft.Maps.Location(coord.latitude, coord.longitude);<br /> <br />  },<br />  <span style="color: rgb(0, 0, 255);">function</span> (err) {<br />    <span style="color: rgb(0, 128, 0);">// Handle the error.</span><br />  });<br /></pre>
  </div>
</blockquote>

<p> </p>

<ul>
  <li>Stellen Sie im nächsten Schritt die Position mit Bing Maps dar. Das Bing Maps-SDK erhalten Sie <a href="http://visualstudiogallery.msdn.microsoft.com/bb764f67-6b2c-4e14-b2d3-17477ae1eaca">hier</a>. Sie benötigen darüber hinaus einen Bing Maps Key, den Sie nach einer Registrierung auf dem Bing Maps-Portal und dem Durchführen der Schritte in der Anleitung <a href="http://msdn.microsoft.com/en-us/library/ff428642.aspx">Getting a Bing Maps Key</a> erhalten. Achten Sie beim Registrieren darauf, dass Sie die Nutzungseinschränkungen für jeden Schlüsseltyp zur Kenntnis nehmen und den für Ihre App geeigneten Typ auswählen. 

    <br />Fügen Sie Ihrem Designer ein Bing Maps-Steuerelement hinzu und geben Sie Ihren Key in die Anmeldeinformationen ein.</li>
</ul>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">Page</span><br />    <span style="color: rgb(255, 0, 0);">xmlns</span><span style="color: rgb(0, 0, 255);">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span><br />    <span style="color: rgb(255, 0, 0);">xmlns:x</span><span style="color: rgb(0, 0, 255);">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span><br />    <span style="color: rgb(255, 0, 0);">xmlns:local</span><span style="color: rgb(0, 0, 255);">=&quot;using:SimpleMapping&quot;</span><br />    <span style="color: rgb(255, 0, 0);">xmlns:d</span><span style="color: rgb(0, 0, 255);">=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;</span><br />    <span style="color: rgb(255, 0, 0);">xmlns:mc</span><span style="color: rgb(0, 0, 255);">=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;</span><br />    <span style="color: rgb(255, 0, 0);">xmlns:Maps</span><span style="color: rgb(0, 0, 255);">=&quot;using:Bing.Maps&quot;</span><br />    <span style="color: rgb(255, 0, 0);">x:Class</span><span style="color: rgb(0, 0, 255);">=&quot;SimpleMapping.MainPage&quot;</span><br />    <span style="color: rgb(255, 0, 0);">mc:Ignorable</span><span style="color: rgb(0, 0, 255);">=&quot;d&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br /><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">Grid</span> <span style="color: rgb(255, 0, 0);">Background</span><span style="color: rgb(0, 0, 255);">=&quot;{StaticResource ApplicationPageBackgroundThemeBrush}&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">Maps:Map</span> <span style="color: rgb(255, 0, 0);">x:Name</span><span style="color: rgb(0, 0, 255);">=&quot;Map&quot;</span> <span style="color: rgb(255, 0, 0);">Margin</span><span style="color: rgb(0, 0, 255);">=&quot;0,120,0,0&quot;</span> <span style="color: rgb(255, 0, 0);">Credentials</span><span style="color: rgb(0, 0, 255);">=&quot;Insert Your Bing Maps Key Here&quot;</span><span style="color: rgb(0, 0, 255);">/&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">Grid</span><span style="color: rgb(0, 0, 255);">&gt;</span><br /><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">Page</span><span style="color: rgb(0, 0, 255);">&gt;</span></pre>
  </div>
</blockquote>

<ul>
  <li>Jetzt können Sie den folgenden Code auf der Seite verwenden, auf der die Karte dargestellt wird. Dieser legt des Vergrößerungsfaktor der Karte fest und zeigt die Position an. Mehr über Zoomstufen erfahren Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/jj850315.aspx" target="_blank">So wird's gemacht: Anzeigen Ihrer Position auf einer Bing-Karte</a>:</li>
</ul>

<p><strong>C#</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">double</span> zoomLevel = 13.0f;<br /><br />Map.SetView(location, zoomLevel);<br /></pre>
  </div>
</blockquote>

<br />Das Hinzufügen eines Bing Maps-Steuerelements in Ihre App mit JavaScript und HTML erfordert etwas mehr Arbeit. Fügen Sie das folgende &lt;script&gt;-Tag in das HTML der App ein: 

<div> </div>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">script</span> <span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;text/javascript&quot;</span> <br />   <span style="color: rgb(255, 0, 0);">src</span><span style="color: rgb(0, 0, 255);">=&quot;ms-appx:///Bing.Maps.JavaScript//js/veapicore.js&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />/script<span style="color: rgb(0, 0, 255);">&gt;</span><br /></pre>
  </div>
</blockquote>

<p>Erstellen Sie anschließend ein &lt;div&gt;-Tag für die Karte und legen Sie das Attribut „id“ so fest, dass Sie darauf zugreifen können.</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">div</span> <span style="color: rgb(255, 0, 0);">id</span>=’<span style="color: rgb(255, 0, 0);">map-div</span>’<span style="color: rgb(0, 0, 255);">&gt;&lt;/</span><span style="color: rgb(128, 0, 0);">div</span><span style="color: rgb(0, 0, 255);">&gt;</span></pre>
  </div>
</blockquote>

<p>Abschließend müssen Sie das Kartensteuerelement in der HTML-Seite initialisieren. Ein entsprechender Code in JavaScript:</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">// Load the Microsoft.Maps.Map module and then call getMap when the </span><br /><span style="color: rgb(0, 128, 0);">// module has loaded.</span><br /><span style="color: rgb(0, 0, 255);">function</span> initMap() {<br />  Microsoft.Maps.loadModule(<span style="color: rgb(0, 96, 128);">'Microsoft.Maps.Map'</span>, <br />    { <br />      callback: getMap, <br />      culture: <span style="color: rgb(0, 96, 128);">&quot;en&quot;</span>, <br />      homeRegion: <span style="color: rgb(0, 96, 128);">&quot;US&quot;</span> <br />  });<br />}<br /><br /><span style="color: rgb(0, 128, 0);">// Get the div to contain the map from the interface of the app.</span><br /><span style="color: rgb(0, 0, 255);">function</span> getMap() {<br /><br />  <span style="color: rgb(0, 128, 0);">// Create a new instance of the Map class, passing in the app ID.</span><br />  <span style="color: rgb(0, 0, 255);">var</span> map = <span style="color: rgb(0, 0, 255);">new</span> Microsoft.Maps.Map(<br />    document.getElementById(mapDivId), <br />    { credentials: “Insert your credentials here” });<br /><br />  <span style="color: rgb(0, 128, 0);">// Set the initial zoom level and type of map.</span><br />  map.setView({<br />    mapTypeId: Microsoft.Maps.MapTypeId.road,<br />    zoom: 3<br />  });<br />}<br /></pre>
  </div>
</blockquote>

<ul>
  <li>Und: Jede App, die den Positionsdienst verwendet, muss die Berechtigungseinstellungen des Benutzers respektieren, die sich jederzeit ändern können. Die Wetter-App verwendet die aktuelle Position zum Abrufen entsprechender Wetterdaten. Der Benutzer kann jedoch jederzeit die Einstellungen aufrufen und die Berechtigung deaktivieren. Ihre App muss jederzeit in der Lage sein, auf eine Deaktivierung der Positionsberechtigung zu reagieren. In diesem Fall wird von der Wetter-App eine Meldung wie „Ihre Position wurde nicht gefunden. Ändern Sie die Berechtigungen, um Wetter die Verwendung Ihrer Position zuzulassen.“ angezeigt. Weitere Informationen und Beispiele zum Umgang mit Positionsberechtigungen finden Sie in den <a href="http://msdn.microsoft.com/de-de/library/windows/apps/Hh465148(v=win.10).aspx" target="_blank">Richtlinien für standortabhängige Anwendungen</a>. 

    <br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0882.bing-weather_2FEEBCEF.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0882.bing_2D00_weather_5F00_2FEEBCEF.jpg"><img title="Bing Weather-App" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Die Bing Weather-App verwendet ddie Position zum Abrufen entsprechender Wetterinformationen" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/7356.bing-weather_thumb_084840C5.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/7356.bing_2D00_weather_5F00_thumb_5F00_084840C5.jpg" width="600" height="450" /></a></li>
</ul>

<p> </p>

<p>Ausführliche Informationen zum Verwenden von Geolocation und dem Bing Maps-SDK finden Sie in <a></a><a>unserem neuen </a><a href="http://msdn.microsoft.com/de-de/library/windows/apps/jj850315.aspx" target="_blank"> Video, im „Gewusst wie“-Thema</a> und dem <a href="http://code.msdn.microsoft.com/windowsapps/Simple-geolocation-with-7b385c3c" target="_blank">Codebeispiel</a>, das Sie mit den Schritten zum asynchronen Abrufen von Positionsdaten vertraut macht, um anschließend das Bing Maps-SDK zur Anzeige des Aufenthaltsortes zu verwenden. Das Video, das „Gewusst wie“-Thema und das Beispiel zeigen Ihnen, wie die Positionsfunktion aktiviert wird, wie die Daten asynchron abgerufen werden, wie die Karte für die ermittelte Position eingerichtet wird und wie das Symbol für die Position auf Basis der Genauigkeit der Daten festgelegt wird. Weitere Informationen finden Sie auch unter <a href="http://msdn.microsoft.com/de-de/library/hh846481.aspx" target="_blank">Bing Maps für Windows Store-Apps</a>.</p>

<h2>Zusammenfassung</h2>

<p>Positionsdaten ermöglichen leistungsstarke und zeitsparende App-Funktionen. Sie können dem Benutzer relevante Informationen zum aktuellen Aufenthaltsort bieten. Ob eine Liste der örtlichen Radiosender, Angebote, Verkehrsdaten oder ein Wetterbericht – Benutzer profitieren von der Möglichkeit einer individuellen Bereitstellung dieser Informationen. Da diese ohne Benutzereingriff automatisch erfolgen kann, sparen Benutzer Zeit und erkennen die Vorteile Ihrer App.</p>

<p>– Ross Heise, Senior Content Developer, Windows Developer Content</p>
<p>   Einen besonderen Dank an Jon Kay und Eric Schmidt für Ihre Hilfe und Beteiligung an diesem Blogbeitrag.</p>
<!-- Title: “Erstellen von standortbezogenen Apps mit Geolocation und Bing Maps” Tags: “Bing Maps, Geolocation, Windows, Geräte, Geolocation, Positionsdienste” --></div>]]></content:encoded>
    </item>
    <item>
      <title>Das neue Windows Dev Center</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_de/das-neue-windows-dev-center</link>
      <pubDate>Thu, 16 May 2013 09:50:00 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_de/2013/05/16/das-neue-windows-dev-center/</guid>
      <description><![CDATA[Seit dem Start des Windows Dev Centers im Oktober 2011 haben wir in enger Kooperation mit...]]></description>
      <content:encoded><![CDATA[<div class="PostContent">
<p>Seit dem Start des <a href="http://msdn.microsoft.com/de-de/windows/default.aspx" target="_blank">Windows Dev Centers</a> im Oktober 2011 haben wir in enger Kooperation mit Entwicklern und Designern auf der ganzen Welt analysiert, wie wir App-Entwicklern optimale Anleitungen, Inspiration und Beispiele zur Verf&uuml;gung stellen k&ouml;nnen. Mithilfe unz&auml;hliger Besucher und dank Ihres Feedbacks wurde ausgewertet, welche Komponenten gut funktionieren und welche Inhalte verbessert werden k&ouml;nnen.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0172.windows_dev_center_1EC86298.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0172.windows_5F00_dev_5F00_center_5F00_1EC86298.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="Windows Developer Center" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0184.windows_dev_center_thumb_1DEFFCAE.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0184.windows_5F00_dev_5F00_center_5F00_thumb_5F00_1DEFFCAE.png" alt="Windows Developer Center" width="600" height="338" border="0" /></a></p>
<h2>Neues</h2>
<p>Das Windows-Team setzt alle Hebel in Bewegung, um ein lebendiges und umfassendes App-&Ouml;kosystem zur Verf&uuml;gung zu stellen. Dies wird durch drei Merkmale deutlich: hervorragende Apps, einzigartige wirtschaftliche Bedingungen und optimale Reichweite. Im neuen Dev Center k&ouml;nnen App-Entwickler, Designer und Unternehmen auf die Ressourcen zugreifen, die sie f&uuml;r das Erstellen hervorragender Apps und das Verwirklichen von Gesch&auml;ftsideen mit Windows ben&ouml;tigen.</p>
<p>Folgende Bereiche des Dev Centers wurden zum Erreichen dieser Ziele weiterentwickelt:</p>
<ol>
<li>Das Navigationsmodell wurde ge&auml;ndert, sodass Sie wichtige Inhalte in jeder Phase der App-Entwicklung problemlos finden.</li>
<li>Durch das Sitedesign werden die wichtigsten Aufgaben und Szenarios sowie neue Inhalte hervorgehoben.</li>
</ol>
<p>Neben den Inhalten, Beispielen und Downloads, die f&uuml;r Entwickler erforderlich sind, wurde f&uuml;r Designer und Unternehmen der Zugriff auf Ressourcen vereinfacht.</p>
<p>Je nach Ihrem Entwicklungsvorhaben steht Ihnen einer von vier Bereichen zur Verf&uuml;gung: <a href="http://msdn.microsoft.com/de-de/windows/apps/br229512" target="_blank">Windows Store-Apps</a>, <a href="http://msdn.microsoft.com/de-de/ie/" target="_blank">Internet Explorer</a>, <a href="http://msdn.microsoft.com/de-de/windows/desktop" target="_blank">Windows-Desktop</a> und <a href="http://msdn.microsoft.com/de-de/windows/hardware" target="_blank">Hardware</a>. In jedem Bereich werden die oben genannten Punkte auf neue Weise unterst&uuml;tzt. In diesem Beitrag werden die spezifischen &Auml;nderungen f&uuml;r Windows Store-Apps ausf&uuml;hrlicher behandelt.</p>
<h2>Die richtigen Inhalte f&uuml;r Ihre Rolle</h2>
<p>Eine Website mit vielen Informationen ist nicht hilfreich, wenn gesuchte Inhalte nicht gefunden werden k&ouml;nnen. Die unz&auml;hligen Themen im Dev Center verdeutlichen, dass die Organisation und Strukturierung der Inhalte &auml;u&szlig;erst wichtig sind. Hinsichtlich der Entwicklung von Windows Store-Apps wurde daher der Schwerpunkt verst&auml;rkt auf Rolle und Szenario gelegt, sodass z.&nbsp;B. die Ressourcen f&uuml;r die ersten Schritte zentralisiert bereitgestellt werden und der Support f&uuml;r Designer und Unternehmen verbessert wurde. Dies sind die wichtigsten Neuerungen:</p>
<h3>Entwickler</h3>
<p>Wir haben die Inhalte, die zum Erstellen hervorragender Windows Store-Apps erforderlich sind, optimiert. Auf der <a href="http://msdn.microsoft.com/de-de/windows/apps" target="_blank">Startseite f&uuml;r Windows Store-Apps</a> werden folgende Komponenten angezeigt:</p>
<ul>
<li>Der Bereich &bdquo;Wichtige Aufgaben und Inhalte&ldquo; wurde so prominent platziert, dass Sie problemlos zu den ben&ouml;tigten Inhalten navigieren k&ouml;nnen. Veranstaltungen in Ihrer Region und neue Ressourcen werden ebenfalls hervorgehoben.</li>
<li>Au&szlig;erdem finden Sie hier Downloads, mit denen Sie Code erstellen, auf Ressourcen f&uuml;r die ersten Schritte und auf ausf&uuml;hrliche Anleitungen zum Platzieren Ihrer App im Windows Store zugreifen k&ouml;nnen.</li>
<li>Wichtige Codebeispiele werden hervorgehoben. Praktische Leitf&auml;den f&uuml;r die Entwicklung wurden noch benutzerfreundlicher gestaltet.</li>
<li>Auf der Website finden Sie &bdquo;<a href="http://msdn.microsoft.com/de-de/library/windows/apps/br211360.aspx" target="_blank">One Dev Minute</a>&ldquo;-Videos, die einen &Uuml;berblick &uuml;ber das Hinzuf&uuml;gen von Features in Apps bieten.</li>
</ul>
<h3>Designer</h3>
<p>Der Bereich <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh779072.aspx" target="_blank">Design</a> wurde umfassender und gleichzeitig benutzerfreundlicher gestaltet. Sie k&ouml;nnen jetzt einfacher auf hilfreiche Downloads und wiederverwendbare Designressourcen zugreifen. Designinspiration und Fallstudien statten Sie mit dem R&uuml;stzeug aus, mit dem Sie einzigartige Features f&uuml;r Windows erstellen k&ouml;nnen. Ihnen stehen somit s&auml;mtliche Ressourcen, die Sie zum Erstellen einer ansprechenden, markanten App ben&ouml;tigen, auf einer Touchscreen-optimierten, benutzerfreundlichen Website zur Verf&uuml;gung.</p>
<h3>Unternehmen</h3>
<p>Der Windows Store bietet &auml;u&szlig;erst attraktive Gesch&auml;ftschancen. Das Wirtschaftsmodell ist dem der Konkurrenzplattformen &uuml;berlegen, und dank der Flexibilit&auml;t k&ouml;nnen Sie Ihre eigenen Gesch&auml;ftsmodelle umsetzen. Im neuen <a href="http://go.microsoft.com/fwlink/?LinkID=285998" target="_blank">Marktbereich</a> der Website finden Sie hilfreiche Tipps f&uuml;r die Vermarktung Ihrer Apps, zur Evaluierung von Telemetriedaten und zum Bestehen der App-Zertifizierung. Wir konnten die Zertifizierung optimieren. Die entsprechenden Inhalte wurden verbessert, um den Vorgang f&uuml;r Sie weiter zu vereinfachen.</p>
<p>Selbstverst&auml;ndlich nehmen viele von Ihnen verschiedene Rollen ein. Wir sind sicher, dass die neu gestaltete Website auch diesem Aspekt gerecht wird. Die neue Siteorganisation hilft &bdquo;Freizeitentwicklern&ldquo;, Kreativagenturen und gro&szlig;en Softwareunternehmen beim Verwirklichen kreativer und gesch&auml;ftlicher Visionen mit Windows.</p>
<h2>Weitere Entwicklungen stehen an &ndash; wir sind gespannt auf Ihre Ideen</h2>
<p>Die <a href="http://www.buildwindows.com">BUILD 2013</a> findet in weniger als einem Monat statt, und es gibt viele Themen. Wir arbeiten mit Hochdruck an der Erstellung neuer Inhalte, sodass auf der diesj&auml;hrigen Veranstaltung ein breites Themenspektrum behandelt werden kann. Sie k&ouml;nnen sich nicht nur &uuml;ber diesen Blog, sondern auch mit folgenden Ressourcen auf dem Laufenden halten: <a href="https://twitter.com/#!/windevs" target="_blank">@windevs</a> auf Twitter und das Abonnement des <a href="http://www.windowsstore.com/newsletter-signup" target="_blank">Windows Store-Newsletters</a>.</p>
<p>Mit jeder Ver&ouml;ffentlichung neuer Inhalte, die Sie beim Entwerfen, Entwickeln und Vermarkten von Windows Store-Apps unterst&uuml;tzen, m&ouml;chten wir das Dev Center noch benutzerfreundlicher gestalten. Damit Sie uns noch einfacher Feedback geben k&ouml;nnen, stehen am Ende jeder Seite zwei neue Feedbackoptionen zur Verf&uuml;gung. Ihr Feedback ist uns wichtig, und wir nehmen uns Ihre Einw&auml;nde zu Herzen.</p>
<p>&nbsp;</p>
<p>Keith Boyd, Content Publishing Manager, Windows Developer Content</p>
<!-- Title: “Das neue Windows Dev Center” Tags: “dev center, Entwicklerinfo, App-Erstellung, Windows Store-Apps, Erstellen, Windows Dev Center” --></div>]]></content:encoded>
    </item>
    <item>
      <title>Freigabe für Ziel-Apps</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_de/freigabe-fr-ziel-apps</link>
      <pubDate>Wed, 15 May 2013 09:09:43 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_de/2013/05/15/freigabe-fr-ziel-apps/</guid>
      <description><![CDATA[In Teilen aus Ihrer App haben wir die Idee vorgestellt, Inhalte aus der Beispiel-App Food with...]]></description>
      <content:encoded><![CDATA[<div class="PostContent"> <p>In <a href="http://blogs.msdn.com/b/windowsappdev_de/archive/2012/12/21/teilen-aus-ihrer-app.aspx" target="_blank">Teilen aus Ihrer App</a> haben wir die Idee vorgestellt, Inhalte aus der Beispiel-App <a href="http://blogs.msdn.com/b/windowsappdev_de/archive/2012/07/19/erstellen-von-apps-im-metro-stil-die-sich-aus-der-masse-hervorheben.aspx" target="_blank">Food with Friends</a> mit mehreren Ziel-Apps zu teilen, um funktionell umfangreiche End-to-End-Szenarien zu ermöglichen. Apps unter Windows 8 bieten interessante Inhalte, die Ihre Kunden wahrscheinlich mit Freunden und anderen Apps <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh465251.aspx" target="_blank">teilen</a> möchten. Eine überzeugende und gut gestaltete Zielfreigabe rückt Ihre App in den Mittelpunkt der sozialen und vernetzen Aktivitäten Ihrer Kunden.</p>  <p>In diesem Beitrag beleuchten wir, wie Sie den Zielfreigabe-Vertrag in Ihren Apps verwenden, besonders für Apps wie Food with Friends. Mit diesem Vertrag kann Ihre App <i>Inhalte von anderen Apps empfangen</i> und so qualitativ hochwertigere eigene Inhalte bereitstellen. Wir möchten Ihnen dabei helfen, Ihre App zur besten in ihrer Kategorie zu machen.</p>  <p>Eine Ziel-App wird mithilfe des <a href="http://blogs.msdn.com/b/windowsappdev_de/archive/2012/03/30/aktivierung-von-windows-160-8-vertr-228-gen-in-apps.aspx" target="_blank">Zielfreigabe-Vertrags</a><u></u> erstellt und ermöglicht schnelles und einfaches Teilen. Nicht jede App unter Windows ist als Freigabeziel geeignet. Wenn Ihre App jedoch empfangene Inhalte veröffentlichen, ändern, speichern oder auf andere Art verarbeiten kann, bietet das Erstellen eines Freigabeziels Vorteile. </p>  <ul>   <li>Ihr App wird stets in der Liste der Ziel-Apps angezeigt. Sie ist unmittelbar relevant und mit anderen Apps verknüpft, die die benötigten Daten teilen können. </li>    <li>Der Freigabe-Vertrag bildet eine Brücke zwischen Ihrer App und einer beliebigen Quell-App, ohne dass die Apps wechselseitig integriert werden müssen. </li>    <li>Da der Charm „Teilen“ im Betriebssystem stets vorhanden und verfügbar ist, erhält Ihre Ziel-App eine Präsenz im Betriebssystem, die über die Grenzen der App hinausreicht. So können Sie mit Ihrer App auch mehr potenzielle Kunden erreichen.</li> </ul>  <h2>Empfangen geteilter Inhalte</h2>  <p>Betrachten wir einige Beispiele für das Bereitstellen praktischer Funktionen mit einer Freigabeziel-App.</p>  <p>Wahrscheinlich sind Sie bereits mit den Apps Mail und Kontakte von Windows 8 vertraut. Mail stellt ein einfaches und persönliches Freigabeziel für den Empfang und das Teilen von Inhalten mit Freunden dar. Mit der Kontakte-App können Sie Inhalte in Ihren sozialen Netzwerken mit einer größeren Zielgruppe teilen. Zusätzlich zum Teilen in sozialen Netzwerken können Sie mit der Freigabe zuwischen Apps einen Schritt weitergehen. Produktivitäts-Apps wie SkyDrive können Dateien aus der gesamten Windows-Umgebung empfangen und in der Cloud speichern. Apps für Notizen können Text und ggf. auch Daten in zahlreichen anderen Formaten empfangen und diese für die spätere Verwendung archivieren. Wie Sie sehen ist jede Menge Raum für Kreativität vorhanden. </p>  <p>In den folgenden zwei Abbildungen sehen Sie den Freigabepfad beim Teilen eines Fotos von der Fotos-App mit PuzzleTouch, einer Spiele-App, die aus Fotos Bildpuzzles erstellt. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/8637.puzzletouch1_6E4332DA.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/8637.puzzletouch1_5F00_6E4332DA.png"><img title="Quell-App auf der linken Seite, rechts eine gefilterte Liste mit Ziel-Apps, die Fotos empfangen können. " style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Quell-App auf der linken Seite, rechts eine gefilterte Liste mit Ziel-Apps, die Fotos empfangen können. " src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/1307.puzzletouch1_thumb_2681A9F3.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/1307.puzzletouch1_5F00_thumb_5F00_2681A9F3.png" width="700" height="394" /></a></p>  <p align="center"><i>Abbildung 1: Quell-App auf der linken Seite, rechts eine gefilterte Liste mit Ziel-Apps, die Fotos empfangen können.      <br />PuzzleTouch ist eines der Freigabeziele, die ein Bild von der Fotos-App empfangen können. </i></p>  <p align="left"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/6661.puzzletouch2_463083BB.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/6661.puzzletouch2_5F00_463083BB.png"><img title="Ziel-App-Vorschau auf der rechten Seite, in der der Benutzer auswählen kann, welche Art Puzzle er erstellen möchte" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Ziel-App-Vorschau auf der rechten Seite, in der der Benutzer auswählen kann, welche Art Puzzle er erstellen möchte" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/2474.puzzletouch2_thumb_65DF5D83.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/2474.puzzletouch2_5F00_thumb_5F00_65DF5D83.png" width="700" height="394" /></a></p>  <p align="center"><i>Abbildung 2: Ziel-App-Vorschau auf der rechten Seite, in der der Benutzer auswählen kann, welche Art Puzzle      <br />er erstellen möchte. Der Puzzle ist fertig, wenn der Benutzer zur App zurückwechselt. </i></p>  <h2>Was ist eine Freigabeziel-App?</h2>  <p>Ein End-to-End-Freigabeszenario unter Windows besteht aus zwei Komponenten. Sie haben eine Quell-App, die ihre Inhalte unter Windows in verschiedenen Formaten zur Verfügung stellt. Zudem gibt es eine Freigabeziel-App, die sich für bestimmte Formate registriert und als Ziel für die geteilten Inhalte fungiert. Die Quell-App und die Freigabeziel-App kommunizieren mithilfe des Freigabe-Vertrags miteinander.</p>  <p>Bedenken Sie bei der Freigabe für Ihre App, dass die Freigabeziel-App im gehosteten Fenster „Teilen“ angezeigt wird. Gestalten Sie diese Oberfläche so, dass Benutzer rasch eine Vorschau der Inhalte erhalten und das Teilen in dieser Ansicht bestätigen können. Dieses Beispiel zeigt die Freigabeziel-App-Ansicht für Mail, in der ein Benutzer einen Link aus dem Browser rasch mit einem seiner Mail-Kontakte teilen kann. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/8561.Share-Target-Image_3ED44139.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/8561.Share_2D00_Target_2D00_Image_5F00_3ED44139.png"><img title="Abbildung zum Freigabeziel" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Abbildung zum Freigabeziel" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/6011.Share-Target-Image_thumb_4FD86F1C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/6011.Share_2D00_Target_2D00_Image_5F00_thumb_5F00_4FD86F1C.png" width="700" height="435" /></a></p>  <p align="center"><i>Abbildung 3: Teilen eines Links aus der Fotos-App mithilfe der Ziel-App Mail</i></p>  <h2>Szenarien für Food with Friends</h2>  <p>Betrachten wir nun, wie <a href="http://blogs.msdn.com/b/windowsappdev_de/archive/2012/07/19/erstellen-von-apps-im-metro-stil-die-sich-aus-der-masse-hervorheben.aspx" target="_blank">Food with Friends</a> als Freigabeziel-App praktische Funktionen umsetzt. Wenn Sie mit der App vertraut sind, kennen Sie auch die beiden Hauptfunktionen von Food with Friends: <i>Planen</i> und <i>Hinzufügen eines Restaurants zur Wunschliste</i>. Selbstverständlich gibt es auch noch andere Funktionen, beispielsweise das Verfassen einer Kritik, Anzeigen der Wunschlisten von Freunden usw. Diese Funktionen finden allerdings ausschließlich innerhalb der Haupt-App statt. Werfen wir einen Blick darauf, ob die beiden Hauptfunktionen mit Food with Friends als Ziel-App effizient umgesetzt werden können.</p>  <h3>Erstellen eines Plans für den heutigen Abend</h3>  <p>Obwohl dies eine der Kernfunktionen in der Haupt-App darstellt, handelt es sich nicht ein optimales Szenario für ein Freigabeziel. Der Grund ist folgender: Die Zielfreigabe soll schnell und einfach erfolgen. Das Erstellen eines Plans ist eine viel anspruchsvollere Aufgabe – ein Benutzer möchten wissen, welche anderen Restaurants ihre Freunde ausprobieren wollen, möchten einige Restaurants auf deren Wunschlisten vergleichen, Kritiken lesen usw. Da die Planung Details erfordert, die am besten in der Haupt-App präsentiert werden, ist die Zusammenfassung dieser Funktion in der Freigabeziel-App nicht sinnvoll. </p>  <p><b></b></p>  <h3>Hinzufügen zur Wunschliste</h3>  <p>Dies ist ein gutes Szenario, da es sich um eine kurze und direkte Aufgabe im Freigabeziel handelt. Einige Beispiele zu dieser App-Funktion:<b></b></p>  <ul>   <li>Benutzer entdecken Restaurants in anderen Apps, zum Beispiel in Apps für die Reiseplanung, Apps mit Empfehlungen zur Umgebung, Restaurant-Blogs usw. Food with Friends ist ein hervorragendes Ziel zum Sammeln von Restaurants auf der Wunschliste. </li>    <li>Die Ziel-App-Ansicht einer App dient dazu, dass ein Benutzer rasch eine Aktion durchführen kann, während er eigentlich eine andere App verwendet. Daher ist das Hinzufügen eines Restaurants zur Wunschliste eine ideale Funktion für das Freigabeziel. </li>    <li>Selbstverständlich könnte der Benutzer auch die App wechseln, die Suche nach dem Restaurant wiederholen und dieses anschließend zur Wunschliste hinzufügen – jedoch ist es wesentlich einfacher, kurz auf „Teilen“ zu tippen.</li> </ul>  <p>Die Wunschliste von Food with Friends ist eine Funktion in einer Freigabeziel-App, wie wir sie uns wünschen. Hier das End-to-End-Szenario, das wir uns vorstellen:</p>  <p>In einer App entdecke ich eine eine interessante Empfehlung zu einem Imbisswagen in der Nähe. Ich möchte den Imbisswagen aus dieser App zu meiner Wunschliste in Food with Friends hinzufügen, damit ich später einen Besuch planen kann.</p>  <p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/7658.contoso_truck_6C263411.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/7658.contoso_5F00_truck_5F00_6C263411.png"><img title="App, die interessante Imbisswagen in der Nähe zeigt" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="App, die interessante Imbisswagen in der Nähe zeigt" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/3022.contoso_truck_thumb_4B9EF45F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/3022.contoso_5F00_truck_5F00_thumb_5F00_4B9EF45F.png" width="700" height="394" /></a><em>Abbildung 4: App, die interessante Imbisswagen in der Nähe zeigt</em></p>  <p>Diese Abbildung zeigt die zu verwendende Freigabeziel-App-Ansicht:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/3835.contoso_truck2_565C4BB4.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/3835.contoso_5F00_truck2_5F00_565C4BB4.png"><img title="Ansicht der Freigabeziel-App" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Ansicht der Freigabeziel-App" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/8637.contoso_truck2_thumb_760B257C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/8637.contoso_5F00_truck2_5F00_thumb_5F00_760B257C.png" width="700" height="394" /></a></p>  <p align="center"><em>Abbildung 5: Ansicht der Freigabeziel-App</em></p>  <p>Durch Ausführen der Aktion „Teilen“ in der Ziel-App-Ansicht können Benutzer Restaurants in Food with Friends sammeln, ohne den Kontext der aktuellen App verlassen zu müssen. </p>  <h2>Implementieren eines Freigabeziels</h2>  <p>Da Sie nun einige Beispiel für die Implementierung eines Freigabeziels kennengelernt haben, ist es an der Zeit, einen Blick auf die Umsetzung zu werfen. Entscheiden Sie zunächst, welche Datenformate Ihre App empfangen können soll. </p>  <h3>Welche Datenformate möchten Sie unterstützen?</h3>  <p>Mit „Teilen“ können entweder Daten in Standardformaten, z. B. Text, URI, HTML, Bitmap und Dateien, oder benutzerdefinierte Datenformate unterstützt werden, beispielsweise die unter <a href="http://schema.org" target="_blank">http://schema.org</a> aufgeführten Formate. Windows filtert die Ziel-Apps nach unterstützten Datenformaten, um die gefilterte Liste der Ziel-Apps im Bereich „Teilen“ anzuzeigen. Ihre App sollte die Datenformate unterstützen, die für die Funktionalität der App von Bedeutung sind. Wenn Ihre App beispielsweise zum Anzeigen von Fotos dient, ist die Unterstützung von Textformaten möglicherweise nicht sinnvoll. Wenn Sie die Unterstützung mehrerer Datenformate deklarieren, sollten Sie entscheiden, welches den freigegebenen Daten am ehesten entspricht, sodass dieses Format als erstes aus dem Datenpaket ausgewählt werden kann. </p>  <p>Da Food with Friends eine Freigabeziel-Funktion enthält, bei der Benutzer Restaurants für die App freigeben, verwenden wir das Datenformat <a href="http://schema.org/Restaurant" target="_blank">Restaurant</a><u></u> von <a href="http://schema.org" target="_blank">http://schema.org</a>. Food with Friends kann im Zielfreigabe-Vertrag für den Empfang dieses Datenformats registriert werden. Anschließend kann die App die Daten im empfangenen Paket in der Ziel-App-Ansicht überzeugend darstellen und Benutzern so ermöglichen, Restaurants zur Wunschliste hinzuzufügen. </p>  <p>Während einige Quell-Apps möglicherweise ausschließlich Daten im Format <a href="http://schema.org/Restaurant" target="_blank">Restaurant</a><u></u> freigeben, stellen andere Apps ähnliche Informationen ggf. in anderen Datenformaten wie <a href="http://schema.org/Place" target="_blank">Place</a><u></u>, <a href="http://schema.org/LocalBusiness" target="_blank">LocalBusiness</a><u></u> und <a href="http://schema.org/FoodEstablishment" target="_blank">FoodEstablishment</a> bereit, die Sie ebenfalls bei <a href="http://schema.org/" target="_blank">schema.org</a><u></u> finden. Daher unterstützt Food with Friends im Freigabe-Vertrag den Empfang mehrere Datenformate, um mit einer größeren Anzahl von Quell-Apps kommunizieren zu können.</p>  <p>Food with Friends unterstützt in den Freigabeziel-Deklarationen des App-Manifests die folgenden Formate:</p>  <ul>   <li><u><a href="http://schema.org/Restaurant" target="_blank">Restaurant</a></u></li>    <li><u><a href="http://schema.org/Place" target="_blank">Place</a></u></li>    <li><u><a href="http://schema.org/LocalBusiness" target="_blank">LocalBusiness</a></u></li>    <li><u><a href="http://schema.org/FoodEstablishment" target="_blank">FoodEstablishment</a></u><u></u></li> </ul>  <p><u></u></p>  <p>Wir konzentrieren uns der Übersichtlichkeit halber auf den Datentyp <a href="http://schema.org/Restaurant" target="_blank">Restaurant</a><u></u>. Das Konzept gilt jedoch ebenso für andere Datentypen.</p>  <h3>Welche Datenformate und Szenarien möchten Sie ausschließen? </h3>  <p>Food with Friends unterstützt das Hinzufügen des Restaurants zur Wunschliste des Benutzers nur, wenn die zum Restaurant empfangenen Informationen einem Restaurant entsprechen, dass in der App bereits bekannt ist. Dadurch werden mehrere Kopien des Restaurants in der App verhindert. </p>  <p>Wir unterstützen keine Standarddatentypen, da die meisten Quell-Apps, die Text, Dateien, Fotos, URIs oder HTML liefern, nicht für Restaurants oder Geschäfte in der Region relevant sind. Wenn Food with Friends beispielsweise den Empfang von Text unterstützte, würde die App auch in der Liste mit den Ziel-Apps einer Quell-App für Notizen aufgeführt. In diesem Fall müsste Food With Friends eine Fehlermeldung ausgeben, die den Benutzer darauf hinweist, dass diese App nicht mit der Quell-App zusammenarbeitet. Grundsätzlich bedeutet dies, dass Datenformate die sinnvolle Verknüpfung von Quell-Apps mit Ziel-Apps darstellen. Wenn die Datenformate nicht übereinstimmen, ist das Teilen von Daten nicht nützlich.</p>  <p>Stellen Sie sicher, dass Sie alle in Frage kommenden Datenformate berücksichtigen und diejenigen ausschließen, die die Freigabefunktion beeinträchtigen.</p>  <h3>Unterstützen des Zielfreigabe-Vertrags</h3>  <p>Zur Unterstützung von Datenformaten deklarieren Sie diese im Manifest-Designer von Visual Studio für Ihre App. Folgendes geschieht, wenn ein Benutzer Ihre App als Ziel einer Freigabeaktion auswählt:</p>  <ol>   <li>Im Freigabeziel-Fenster über der Quell-App wird eine neue Instanz der App gestartet. </li>    <li>Ein <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.applicationmodel.activation.sharetargetactivatedeventargs.aspx" target="_blank">ShareTargetActivated</a>-Ereignis wird ausgelöst und die App erhält ein <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br205977.aspx" target="_blank">ShareOperation</a><b></b>-Objekt.</li>    <li>Ihre App kann die Daten abrufen, die der Benutzer über dieses Objekt teilt. </li>    <li>Sie können diese Daten verwenden, um die Ziel-App-Ansicht darzustellen und die Benutzerfreigabe abzuschließen. </li> </ol>  <p>Weitere Informationen zum Erstellen dieser Funktionalität finden Sie in der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh465255.aspx"><u>Schnellstart</u></a>-Anleitung <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh465255.aspx" target="_blank">Empfangen von geteilten Inhalten</a>. </p>  <p>Visual Studio unterstützt außerdem eine Vorlage für Freigabeziele. Klicken Sie mit der rechten Maustaste auf Ihr Projekt, wählen Sie <b>Element hinzufügen</b> und <b>Neues Element hinzufügen</b> aus und klicken Sie in der Liste auf <b>Zielfreigabe-Vertrag</b>, um den Code für die Unterstützung des Vertrags hinzuzufügen. Das <a href="http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782" target="_blank">Codebeispiel zum Freigabeziel</a><u></u> veranschaulicht den Empfang geteilter Inhalte.</p>  <h2>Entwerfen einer angepassten Ziel-App-Ansicht</h2>  <p>Wenn der Benutzer eine Ziel-App aus der App-Liste im Bereich „Teilen“ auswählt, startet Windows die App in der entsprechenden Freigabeziel-Ansicht. Bei der Ziel-App-Ansicht handelt es sich um eine spezielle, im Bereich „Teilen“ gehostete Ansicht, die sich von der Hauptansicht der App unterscheidet. Im Beitrag <a href="http://blogs.msdn.com/b/windowsappdev_de/archive/2012/03/30/aktivierung-von-windows-160-8-vertr-228-gen-in-apps.aspx" target="_blank">Aktivierung von Windows 8-Verträgen in Apps</a><u></u> finden Sie weitere Informationen zu gehosteten Ansichten sowie zur Aktivierung dieser Ansichten. Die Ziel-App-Ansicht dient zum Abschließen der vom Benutzer eingeleiteten Freigabeaktion. In dieser Ansicht erhalten Benutzer eine übersichtliche Vorschau der Inhalte und können einfache Aktionen vornehmen sowie den Freigabevorgang bestätigen. </p>  <p>Bevor wir uns den Ziel-App-Entwurf für Food with Friends ansehen, werfen wir einen kurzen Blick auf eine Ziel-App, die Ihnen wahrscheinlich bereits vertraut ist. In der folgenden Abbildung wird die Ziel-App-Ansicht neben der vollständigen Ansicht der Mail-App von <a></a>Windows 8 dargestellt.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/1307.target-app_4AC68E75.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/1307.target_2D00_app_5F00_4AC68E75.png"><img title="Freigabe von der Fotos-App an die Ziel-App Mail auf der rechten Seite" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Freigabe von der Fotos-App an die Ziel-App Mail auf der rechten Seite" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0724.target-app_thumb_5583E5CA.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0724.target_2D00_app_5F00_thumb_5F00_5583E5CA.png" width="700" height="438" /></a></p>  <p align="center"><i>Abbildung 6: Freigabe von der Fotos-App an die Ziel-App Mail auf der rechten Seite</i></p>  <p align="left"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/1385.mail_154DCC50.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/1385.mail_5F00_154DCC50.png"><img title="Verfassen einer neuen E-Mail in der Hauptansicht der Mail-App" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Verfassen einer neuen E-Mail in der Hauptansicht der Mail-App" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/2055.mail_thumb_510D6503.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/2055.mail_5F00_thumb_5F00_510D6503.png" width="700" height="438" /></a></p>  <p align="center"><em>Abbildung 7: Verfassen einer neuen E-Mail in der Hauptansicht der Mail-App</em></p>  <p>Beachten Sie, dass die Freigabeziel-App-Ansicht von Mail einfacher gestaltet ist als deren Hauptansicht. Diese Ansicht bietet eine übersichtliche, zusammenfassende Darstellung der Inhalte, die der Benutzer teilen möchte, in Form einer Miniaturansicht mit zugehörigem Text und HTML. Die Ansicht weist die Zeile <b>An</b> zum Hinzufügen von Empfängern, einen Eingabebereich zum Verfassen einer kurzen Nachricht sowie die Schaltfläche <b>Senden</b> zum Bestätigen des E-Mails-Versands auf.</p>  <p>Obwohl es sich um eine einfachere Ansicht handelt, ist die Ziel-App-Ansicht deutlich als Komponente der Mail-App zu erkennen. Dies verdeutlicht dem Benutzer das Ziel der geteilten Inhalte.</p>  <h2>Food with Friends als Freigabeziel-App</h2>  <p>Da Sie nun eine allgemeine Vorstellung über den Entwurf einer Ziel-App-Ansicht haben, lassen Sie uns erläutern, wie Food with Friends zu einer Ziel-App wird, in der Benutzer Restaurants zu ihrer Wunschliste hinzufügen können. </p>  <p>Wenn Food with Friends ein Datenpaket mit einem <a href="http://schema.org/Restaurant">Restaurant</a> von der Quell-App erhält, kann Food with Friends mithilfe der Informationen im <a href="http://schema.org/Restaurant">Restaurant</a>-Datenformat ermitteln, welches Restaurant in der vorhandenen Datenbank mit dem empfangenen Datenpaket übereinstimmt. Anschließend kann die App eine Vorschau dieses Restaurants in der Ziel-App-Ansicht anzeigen. Dadurch werden die geteilten Inhalte überzeugender dargestellt. </p>  <p>Diese Abbildung zeigt die Ziel-App-Ansicht von Food with Friends.</p>  <p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/3857.contoso_truck3_0305058E.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/3857.contoso_5F00_truck3_5F00_0305058E.png"><img title="Ziel-App-Ansicht von Food with Friends" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Ziel-App-Ansicht von Food with Friends" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/5584.contoso_truck3_thumb_1B94A2DE.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/5584.contoso_5F00_truck3_5F00_thumb_5F00_1B94A2DE.png" width="700" height="394" /></a><em>Abbildung 8: Ziel-App-Ansicht von Food with Friends</em></p>  <p>Wie Sie sehen, ist diese Ansicht von Food with Friends übersichtlich und für ihre Rolle in der Freigabeziel-App angepasst. Sie zeigt eine Vorschau des Restaurants, das der Benutzer teilen möchte, und eine einfache Aktionsschaltfläche zum <b>Hinzufügen zur Wunschliste</b>, die das Ziel der geteilten Inhalte in der Haupt-App verdeutlicht. Wenn der Benutzer auf diese Schaltfläche tippt bzw. klickt, wird der Freigabevorgang bestätigt. Durch die erforderliche Bestätigung wird ein unbeabsichtigtes Teilen verhindert und die allgemeine Zuverlässigkeit der Freigabefunktion verdeutlicht. </p>  <p>Wenn die App mehrere Restaurants findet, die den Informationen aus dem Datenpaket entsprechen, verwendet Food with Friends die Freigabeziel-App-Ansicht, um die verschiedenen teilbaren Optionen anzuzeigen, aus denen der Benutzer die gewünschte auswählen kann. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/5582.contoso_truck4_70500BD6.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/5582.contoso_5F00_truck4_5F00_70500BD6.png"><img title="Ziel-App-Ansicht mit Optionen, aus denen der Benutzer die zu teilenden Elemente auswählen kann" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Ziel-App-Ansicht mit Optionen, aus denen der Benutzer die zu teilenden Elemente auswählen kann" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/6175.contoso_truck4_thumb_6FE3D8E1.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/6175.contoso_5F00_truck4_5F00_thumb_5F00_6FE3D8E1.png" width="700" height="394" /></a></p>  <p align="center"><em>Abbildung 9: Ziel-App-Ansicht mit Optionen, aus denen der Benutzer die zu teilenden Elemente auswählen kann</em></p>  <p> </p>  <p>Wenn die App ein Restaurant oder einen Satz gültiger Auswahloptionen anhand des empfangenen Datenpakets nicht genau bestimmen kann, sollten Sie die Ziel-App-Ansicht dazu verwenden, eine entsprechende Meldung anzuzeigen. </p>  <h2>Erstellen von Direktlinks</h2>  <p>Bei einem <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.applicationmodel.datatransfer.sharetarget.quicklink.aspx" target="_blank">Direktlink</a> handelt es sich um eine Bereitstellung der Share-API, mit der Benutzer Inhalte rasch mit bekannten Zielen in der Ziel-App teilen können. Eine Direktlink fungiert als an die Ziel-App angepasster Link, der eine bestimmte Aktion ermöglicht. Wenn Windows die Liste der für den Benutzer verfügbaren Ziel-Apps filtert, wird die Direktlinkliste oben im Bereich „Teilen“ als Liste verfügbarer Ziele angezeigt. Bei diesen vertrauten Zielen und Benutzeraktionen kann es sich beispielsweise um Speicherorte oder Kontakte handeln, die häufig über die Ziel-App geteilt werden. Beispielsweise gibt die Mail-App Direktlinks für Kontakte zurück, an die bereits zuvor E-Mails gesendet wurden. Auf die gleiche Weise können Sie Direktlinks zu Ordnern, Gruppen, Notizbüchern und Wiedergabelisten hinzufügen, die oft mit der Ziel-App geteilt werden. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/5001.quicklink_2FADBF67.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/5001.quicklink_5F00_2FADBF67.png"><img title="Bereich „Teilen“ mit einem von der Ziel-App Mail bereitgestellten Direktlink für Kontakte, an die bereits zuvor E-Mails gesendet wurden" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Bereich „Teilen“ mit einem von der Ziel-App Mail bereitgestellten Direktlink für Kontakte" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/1374.quicklink_thumb_334BDA44.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/1374.quicklink_5F00_thumb_5F00_334BDA44.png" width="700" height="438" /></a></p>  <p align="center"><i>Abbildung 10: Bereich „Teilen“ mit einem von der Ziel-App Mail bereitgestellten Direktlink für Kontakte,      <br />an die bereits zuvor E-Mails gesendet wurden</i></p>  <p>Die Ziel-App kann einen <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.applicationmodel.datatransfer.sharetarget.quicklink.aspx" target="_blank">Direktlink</a><u></u> durch Aufrufen der<b><u> </u></b><a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.applicationmodel.datatransfer.sharetarget.shareoperation.reportcompleted.aspx" target="_blank">reportCompleted</a><b></b><b><u></u></b>-Methode des <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br205977.aspx" target="_blank">ShareOperation</a><u></u><b><u></u></b>-Objekts bereitstellen. Jeder Direktlink muss über einen Titel, ein Symbol und eine ID verfügen. Der Titel (z. B. „E-Mail an Mama“) und das Symbol werden angezeigt, wenn der Benutzer auf den Charm „Teilen“ tippt. Die ID wird von der App verwendet, um auf benutzerdefinierte Informationen zuzugreifen, z. B. eine E-Mail-Adresse, den Speicherort eines Ordners usw. Weitere Informationen zu diesem Tool finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh758299.aspx" target="_blank">Erstellen eines Direktlinks</a><u></u>.  </p>  <p>Hinweis: Direktlinks sind hilfreich, wenn die App mehrere Aktionen der Ziel-App unterstützt. Da Food with Friends nur eine einzige Aktion im Freigabeziel unterstützt (das <b>Hinzufügen zur Wunschliste</b>), wurden in der App keine Direktlinks implementiert. </p>  <h2>Erweiterte Freigabe und Fehlerberichterstellung</h2>  <p>Manchmal werden aus Quell-Apps große Datenmengen wie Fotos, Videos oder Dateien geteilt, bei denen die Datenübertragung länger dauert. Diese Freigabevorgänge werden als <i>erweiterte Freigaben</i> bezeichnet, bei denen die Ziel-App möglicherweise mehr Zeit benötigt, um die Daten zu empfangen und zu verarbeiten. </p>  <p>Da die Freigabe so schnell und flüssig erfolgt und es sich bei der Ziel-App-Ansicht um eine vereinfachte, über der Haupt-App gehostete Darstellung handelt, schließen Benutzer möglicherweise die Ziel-App-Ansicht, um zur Haupt-App zurückzugelangen. Daher sollten Ziel-Apps keine zusätzlichen Benutzerinteraktionen erwarten oder erfordern, nachdem das Teilen gestartet wurde. Ziel-Apps können das <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br205977.aspx" target="_blank">ShareOperation</a><b></b>-Objekt und dessen Methoden verwenden, um Windows darüber zu benachrichtigen, dass die App Daten verarbeitet. </p>  <ul>   <li><b><a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.applicationmodel.datatransfer.sharetarget.shareoperation.reportstarted.aspx" target="_blank">reportStarted</a></b> – Rufen Sie diese Methode auf, um Windows darüber zu informieren, dass der Empfang der Daten durch die App im DataPackage-Objekt von der Quell-App begonnen hat. </li>    <li><b><a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.applicationmodel.datatransfer.sharetarget.shareoperation.reportdataretrieved.aspx" target="_blank">reportDataRetrieved</a></b><b><u> </u></b>– Rufen Sie diese Methode auf, um Windows darüber zu informieren, dass die Daten im Paket vollständig von der App empfangen wurden.</li>    <li><b><a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.applicationmodel.datatransfer.sharetarget.shareoperation.reportcompleted.aspx" target="_blank">reportCompleted</a></b><b><u> </u></b>– Rufen Sie diese Methode auf, um Windows darüber zu informieren, dass der Freigabevorgang von der App abgeschlossen wurde.<b><u> </u></b><b><u></u></b></li> </ul>  <p>Wenn Ihre App Daten im Rahmen einer erweiterten Freigabe verarbeitet, sollten Sie den Fortschritt in der Ziel-App-Ansicht darstellen. Hierdurch wird der Benutzer darüber informiert, dass seine Anfrage bearbeitet wird und er einfach zu Ihrer App zurückkehren und den Fortschritt des Freigabevorgangs überprüfen kann. Unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh465487.aspx" target="_blank">Schnellstart: Hinzufügen von Statussteuerelementen</a><u></u> finden Sie weitere Informationen zu Statussteuerelementen unter Windows 8. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0702.progress-bar_52FAB40C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0702.progress_2D00_bar_5F00_52FAB40C.png"><img title="Statusanzeige" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Statusanzeige" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/3438.progress-bar_thumb_40B1ED4A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/3438.progress_2D00_bar_5F00_thumb_5F00_40B1ED4A.png" width="700" height="438" /></a></p>  <p align="center"><i>Abbildung 11: Ziel-App Mail mit einem Statusanzeigering beim Abschließen einer erweiterten Freigabe wie dem Senden großer Anlagen</i></p>  <p>Wenn bei der Datenübertragung ein Fehler auftritt und der Freigabevorgang von der Ziel-App abgebrochen werden muss, können Sie <b><u>reportError</u></b> aufrufen, um eine Fehlermeldung an Windows zu senden. Der Benutzer erhält die Meldung, wenn er den Status der Freigabe im Bereich „Teilen“ überprüft. Nachdem der Fehler gemeldet wurde, wird die App geschlossen und das Teilen beendet. Der Benutzer muss die Freigabe der Inhalte für Ihre App erneut starten.</p>  <p>Im Zielfreigabebeispiel Food with Friends sollte die App einen Fehler ausgeben, wenn in der App-Datenbank kein Restaurant gefunden wird, das mit dem über die Quell-App im <a href="http://schema.org/Restaurant" target="_blank">Restaurant</a><u></u>-Datenformat geteilten Restaurant übereinstimmt. </p>  <h2>Zusammenfassung</h2>  <p>Das Teilen zwischen Apps bietet spannende Möglichkeiten für die Freigabe von Ziel-Apps. Indem Sie einer App den Empfang geteilter Inhalte ermöglichen, können Benutzer auch dann von der App profitieren, wenn sie anderweitig beschäftigt sind. Wir hoffen, dass wir zu einem besseren Verständnis der Entwurfsprinzipien sowie der Datentypen, Klassen und der Eigenschaften beitragen konnten, die für das Erstellen eines Freigabeziels erforderlich sind. Wir freuen uns auf die Umsetzung geteilter Inhalte in Ihren Apps, damit Sie Ihren Benutzern umfangreichere Funktionen zur Verfügung stellen können.</p>  <p>Weitere Informationen zur Freigabe finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh464923.aspx" target="_blank">Freigeben und Austauschen von Daten</a><u></u> und im <a href="http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782" target="_blank">Ziel-App-Beispiel zur Freigabe von Inhalten</a><u></u>.</p>  <p>Ishita Kapur</p>  <p>Programmmanager</p>  <p>Windows-Benutzeroberfläche</p> <p>Freigabe für Ziel-Apps</p><p>Freigeben von Apps, Ziel-Apps, geteilte Inhalte, Freigabeziel, Freigeben von Ziel-Apps</p> <!-- Title: “Freigabe für Ziel-Apps” Tags: “Freigeben von Apps, Ziel-Apps, geteilte Inhalte, Freigabeziel, Freigeben von Ziel-Apps” --> </div>]]></content:encoded>
    </item>
    <item>
      <title>Entwickeln moderner Apps mit NFC</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_de/entwickeln-moderner-apps-mit-nfc</link>
      <pubDate>Wed, 24 Apr 2013 15:38:51 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_de/2013/04/24/entwickeln-moderner-apps-mit-nfc/</guid>
      <description><![CDATA[Nahfeldkommunikation (Near Field Communication, NFC) ist eine neue, immer häufiger verwendete...]]></description>
      <content:encoded><![CDATA[<div class="PostContent"> <p>Nahfeldkommunikation (Near Field Communication, NFC) ist eine neue, immer häufiger verwendete Drahtlostechnologie mit kurzer Reichweite. Innerhalb einer Entfernung von genau 2 cm können Geräte von Benutzern physisch aneinander gekoppelt werden, um Inhalte zu senden bzw. zu empfangen. Kopplung bietet Ihnen die Möglichkeit, schnell etwas (oder jemanden) auswählen. Kopplung ist nicht nur schnell, es ist auch unkompliziert. Sobald Sie es einmal gesehen haben, haben Sie es verstanden – ganz ohne Handbuch.</p>  <p>Stellen Sie sich beispielsweise vor, Sie zeigen einer Freundin ein paar Fotos und sie möchte diese Bilder haben – mit NFC müssen Sie lediglich Ihr Gerät mit dem Computer Ihrer Freundin koppeln und können dann die Fotos versenden. So einfach ist das? Im Prinzip schon. NFC dient dazu, Inhalte schnell und einfach zwischen Geräten zu teilen.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/1732.NFC-image_04E645BB.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/1732.NFC_2D00_image_5F00_04E645BB.png"><img title="&#39;Nokia 360° Lautsprecher teilt seine Bluetooth-Kopplungsdaten mit einem Windows Phone" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="&#39;Nokia 360° Lautsprecher teilt seine Bluetooth-Kopplungsdaten mit einem Windows Phone" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/3566.NFC-image_thumb_38420917.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/3566.NFC_2D00_image_5F00_thumb_5F00_38420917.png" width="400" height="348" /></a></p>  <p align="center">Abbildung 1: Nokia 360° Lautsprecher teilt seine Bluetooth-    <br />Kopplungsdaten mit einem Windows Phone</p>  <p>Bei NFC handelt es sich ähnlich wie bei Bluetooth oder WLAN um ein Standard-Drahtlosprotokoll, das vom <a href="http://www.nfc-forum.org/home/" target="_blank">NFC-Forum</a><u></u> definiert wird. <u></u>Ihr Computer muss über ein NFC-Radio verfügen. In zahlreichen Windows 8-PCs sind NFC-Radios bereits direkt integriert. Wenn Ihr PC noch nicht über NFC verfügt, können Sie NFC-Dongles erwerben, um diese am PC anzuschließen.</p>  <p>NFC bietet einige tolle Funktionen. Benutzer können Ihr Gerät mit anderen Geräten koppeln und Fotos versenden, mit einer Speisekarte koppeln und ein Essen in einem Restaurant bestellen oder sogar mit einem Bluetooth-Gerät koppeln. Die Verwendungsmöglichkeiten sind also vielfältig, aber in allen Fällen müssen zunächst Ihr Gerät und der Empfänger aneinander gekoppelt werden, auch „Tappen“ genannt. NFC macht das Verbinden von vielen unterschiedlichen Geräten – PCs, SmartPhones, Lautsprecher, Headsets, Drahtlosbildschirme – intuitiver und damit benutzerfreundlicher. Bei NFC kommen außerdem auch RFID-Tags zum Einsatz, sehr kostengünstige, leichtgewichtige passive Antennen, die eine beträchtliche Menge an Daten speichern und so gut wie überall befestigt werden können, am häufigsten auf Plakaten. Zum Beispiel könnten Sie eine Kinokarte erwerben, indem Sie einfach Ihr Gerät mit dem Filmplakat koppeln. Diese werden als NFC-Tags bezeichnet. Wir erläutern ein einfaches Beispiel einer Kopplung mit einem NFC-Tag, um einige grundlegende Konzepte der NFC-API zu demonstrieren.</p>  <p>Aber werfen wir zunächst einmal einen Blick darauf, was das Koppeln von Geräten eigentlich bedeutet.</p>  <h2>Definieren einer Kopplung</h2>  <p>Ob Sie Ihr Gerät mit einer Bluetooth-Maus koppeln oder mit einem anderen Gerät, um Fotos zu teilen: Für den Benutzer zählt, dass Geräte auf die gleiche Weise gekoppelt werden. Das „Tappen“, also das Koppeln eines PC mit einem anderen Gerät, ist für die meisten Benutzer neu und deshalb ungewohnt. Im Folgenden finden Sie einige Richtlinien für das Koppeln, mit deren Hilfe Benutzer informiert werden:</p>  <ol>   <li>     <div align="center"><b>Wo müssen die Geräte gekoppelt werden</b> – Verwenden Sie einen Berührungspunkt (auch als „Koppeln und Aktion“-Logo bekannt), der anzeigt, wo sich die NFC-Antenne befindet. Je nach PC-Modell erfolgt die Kopplung an einer unterschiedlichen Stelle des PCs. Beispielsweise erfolgt möglicherweise die Kopplung bei einem Tablet an der Rückseite, bei einem All-in-One jedoch an der Vorderseite. Im Folgenden ist das Logo abgebildet, das sich auf allen Windows 8-PCs mit vorhandenem NFC befindet:         <br /></div>     <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0830.NFC-logo_66E85720.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0830.NFC_2D00_logo_5F00_66E85720.png"><img title="„Koppeln und Aktion“-Logo" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="„Koppeln und Aktion“-Logo" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/5611.NFC-logo_thumb_3FAE0DEB.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/5611.NFC_2D00_logo_5F00_thumb_5F00_3FAE0DEB.png" width="200" height="147" /></a>      <p align="center">Abbildung 2: „Koppeln und Aktion“-Logo</p>   </li>    <li><b>Geräte kommunizieren miteinander</b> – Während der Kopplung sollten die Benutzer darauf vertrauen können, dass tatsächlich etwas passiert, auch wenn Sie die Datenübertragung selbst nicht sehen. Deshalb wird von Windows ein Sound wiedergegeben, wenn sich Geräte innerhalb der Reichweite befinden und miteinander kommunizieren.</li> </ol>  <p>All das wird von Windows automatisch ausgeführt, sodass Sie sich darum keine Gedanken machen müssen. Weitere Informationen zu diesen Elementen der Benutzerfreundlichkeit finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/hardware/hh770524.aspx" target="_blank">Windows 8 Near Field Proximity Implementation Specification</a><u></u>. Sehen wir uns nun in Anbetracht dessen einige tollen Szenarien an, die Sie mit NFC erleben können.</p>  <h2>Wann sollte NFC verwendet werden? </h2>  <p>Verwenden Sie NFC, wenn in Ihrer App ein Benutzer etwas bzw. jemanden auswählen soll. NFC bietet eine intuitive Art und Weise des Auswählens, die häufig schneller (und interessanter) als die manuelle Suche ist. Durch die Kopplung wird ein Vorgang ausgelöst. Je nach App kann dies bedeuten, dass z. B. ein Foto empfangen oder eine Wiedergabeliste gestartet wird. Es gibt viele Möglichkeiten. Was nach der Kopplung passiert, hängt ganz von Ihrer App ab. Deshalb bezeichnen wir diese Vorgänge der Einfachheit halber als „Koppeln und Aktion“-Vorgänge.</p>  <p>Im Folgenden finden Sie ein paar Beispiele, um etwas mithilfe von NFC in einer App auszuwählen. Folgende Funktionen können mit Koppeln ausgeführt werden:</p>  <ul>   <li><u>Abrufen von Informationen von einem Plakat</u>: <a href="http://www.nfc-forum.org/news/pr/view?item_key=2c0cb92de7d47bbbe7c99f13912b3307fc03c1c6" target="_blank">NFC-Tags</a> sind leichte, kostengünstige RFID-Tags. Ihre Kosten liegen zwischen 0,15 und 1,00 US-Dollar (Preis abhängig von den Druckkosten). Sie sind vergleichbar mit QR-Codes, jedoch einfacher und schneller zu verwenden. Es ist bequemer, sich an ein Tag zu koppeln, als ein Foto des Barcodes aufzunehmen (und darauf zu hoffen, dass sich die Kamera im richtigen Winkel befunden hat). In Bereichen mit hoher Verkehrsdichte, z. B. Flughäfen, U-Bahn-Stationen und Bushaltestellen, integrieren immer mehr Hersteller Tags in Plakate. Tags können 48 B bis 4 KB an Daten speichern. Sie können einen Tag so programmieren, dass Ihre App mit einer bestimmten Seite gestartet wird. </li> </ul>  <ul>   <li><u>Austauschen von Kontaktinformationen</u>: Koppeln Sie Geräte zum Austauschen von Kontaktinformationen, anstatt sie einem Freund zu buchstabieren und zu hoffen, dass er sich an keiner Stelle verschreibt. Ähnlich wie oben können Sie Ihre Informationen in eine NFC-Visitenkarte bzw. in einen NFC-Tag programmieren oder sie direkt über eine App austauschen.</li>    <li><u>Wiedergeben der Lieblingsmusikstation</u>: Ganz gleich, ob Sie gerade mit dem Training anfangen, ins Auto steigen oder sich einfach nur zu Hause entspannen – verwenden Sie einen NFC-Tag, um einen Radiosender einzuschalten. Sie können sich sogar verschiedene Musiksender für verschiedene Tags programmieren, beispielsweise jeweils einen Tag für das Fitnesscenter, einen zum Entspannen und einen für die Schlafenszeit.</li>    <li><u>Aufgeben von Bestellungen in einem gut besuchten Restaurant</u>: In beliebten Restaurants müssen Sie manchmal bereits für das Aufgeben der Bestellung lange warten. Koppeln Sie stattdessen Ihr Gerät an einen Tag auf Ihrem Tisch, um das Essen zu bestellen.</li>    <li><u>Spielen eines Multiplayer-Spiels mit einem Freund: </u>Sie können problemlos Multiplayer-Spiele wie Schiffe versenken, Schach oder Scrabble mit einem Freund verbinden, indem Sie die Geräte aneinander koppeln. Nach dem Koppeln wird die Verbindung über einen Out-of-Band-Transport mit einer größeren Reichweite und einem größeren Durchsatz beibehalten, beispielsweise über Bluetooth oder Wi-Fi Direct. </li> </ul>  <p>Wir haben nun schon eine ganz gute Vorstellung davon, wie NFC funktioniert und wann es verwendet wird. Jetzt wird es spannend! Gehen wir in media res und erstellen eine App mithilfe unserer Windows 8-Näherungs (NFC)-APIs.</p>  <h2>So implementieren Sie NFC </h2>  <p>Wie Sie sehen, erleichtert NFC Endbenutzern viele alltägliche Aufgaben. Nehmen Sie die Einstellung eines Alarms als ein Beispiel. Ich bin mir sicher, dass beinahe jeder schon einmal versehentlich eine falsche Weckzeit für den nächsten Morgen eingestellt hat. Wenn es spät ist und man eigentlich nur noch einschlafen möchte, ist man gerne einmal etwas unaufmerksam. NFC macht dies leichter, da hier nur ein voreingestellter Tag getappt und bestätigt werden muss, um dann ohne Sorgen schlafen gehen zu können. Stellen wir uns also vor, dass Sie deshalb eine einfache Alarm-App geschrieben haben, mit der Benutzer einen Alarm mithilfe eines NFC-Tags einstellen können. Dabei lassen sich zwei Szenarien unterscheiden:</p>  <ol>   <li><u>Einstellen eines Alarms <b>im</b> Tag</u>: NFC-Tags können wiederverwendet werden, daher sollte die App dem Benutzer eine Möglichkeit bieten, einen Alarm zu programmieren. Beispielsweise möchte ein Benutzer vielleicht verschiedene Alarme programmieren, einen für Werktage, einen für das Wochenende. Dies wird allgemein als Veröffentlichen in einem Tag bezeichnet.</li>    <li><u>Einstellen eines Alarms <b>vom</b> Tag</u>: Nachdem ein Benutzer einen Tag gekoppelt hat, sollte die App gestartet werden, um die Einstellung eines Alarms zu bestätigen. Dies bedeutet, dass die App mit Kontext oder Argumenten gestartet werden kann. </li> </ol>  <p>Die NFC-API bietet unterschiedliche Herangehensweisen für das gleiche Ziel, ich erläutere hier aber nur den einfachsten Weg zur Implementierung dieses Szenarios.</p>  <p>Im Folgenden werden die Schritte zum Einstellen eines Alarms auf einem NFC-Tag veranschaulicht:</p>  <ol>   <li>Jens startet die Alarm-App und gibt eine Uhrzeit an, z. B. 07:00 Uhr. Ein ganz normaler Vorgang, bei dem NFC noch keine Rolle spielt.</li>    <li>Jens wählt die Option zum Einrichten eines Alarms in einem NFC-Tag aus. An dieser Stelle ruft App die NFC-APIs auf, um Daten an das NFC-Radio zu übertragen, genauer gesagt eine App-ID-Zeichenfolge: &amp; 07:00. Bei NFC-Tags wird ein Standardnachrichtenformat mit der Bezeichnung NDEF (NFC Defined Exchange Format) verwendet. Die Formatierung der Daten in eine NDEF-Nachricht muss <b>nicht </b>von der App ausgeführt werden. Diesen Vorgang übernimmt Windows. Der Benutzer kann jetzt den NFC-Tag koppeln.</li>    <li>Jens koppelt den Tag mit dem PC und die Programmierung des Tags wird von der App bestätigt. Nach der Kopplung des Tags sollten die Benutzer unbedingt darüber informiert werden, dass der Tag erfolgreich von der App programmiert wurde. Wie bereits erwähnt, stellt die Kopplung von PCs für die meisten Anwender ein neues Konzept dar. Durch die Bestätigung erhalten die Benutzer Gewissheit, dass der Vorgang funktioniert. Durch die Registrierung eines MessageTransmittedHandlers erkennt die App, dass eine Nachricht erfolgreich übermittelt wurde.</li> </ol>  <p>Die NFC-APIs befinden sich im <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.proximity.aspx" target="_blank">Windows.Networking.Proximity</a>-Namespace. Diese APIs kommen in Schritt 2 zum Einsatz, nachdem der Benutzer die Option zum Einstellen eines Alarms auf einem NFC-Tag auswählt. Zunächst initialisiert die App ein Näherungs-Objekt. Anhand des Näherungs-Objekts kann ermittelt werden, ob sich ein Tag (oder Gerät) innerhalb oder außerhalb der Reichweite befindet. Anschließend wird der DeviceArrival-Ereignishandler hinzugefügt. Der Handler erkennt, ob der Tag gekoppelt wurde. Ist dies der Fall, können Informationen auf den Tag geschrieben werden. Die Benutzer sollten wissen, wenn auf den Tag geschrieben wird, damit sie ihn nicht außer Reichweite bewegen. Mit diesem Ereignis kann die Kopplung beliebiger Näherungs-Geräte erkannt werden.</p>  <p>Im folgenden Codeausschnitt wird das Initialisieren und Hinzufügen eines DeviceArrival-Ereignishandlers veranschaulicht.</p>  <p><strong>JavaScript</strong></p>  <blockquote>   <div>     <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> proximityDevice;<br /><br /><span style="color: rgb(0, 0, 255);">function</span> initializeProximityDevice() {<br />    proximityDevice = Windows.Networking.Proximity.ProximityDevice.getDefault();<br /><br />    <span style="color: rgb(0, 0, 255);">if</span> (proximityDevice) {<br />        proximityDevice.addEventListener(<span style="color: rgb(0, 96, 128);">&quot;devicearrived&quot;</span>, proximityDeviceArrived);<br />       <br />}<br />   <span style="color: rgb(0, 0, 255);">else</span> {<br />        <span style="color: rgb(0, 128, 0);">// No NFC radio on the PC, display an error message</span><br />    }<br /><br /><br /><span style="color: rgb(0, 0, 255);">function</span> proximityDeviceArrived(device) {<br />        <span style="color: rgb(0, 128, 0);">// Let the user know we’re ‘Writing to Tag’</span><br /><br />}<br />}<br /></pre>
  </div>
</blockquote>

<div>
  <br /><strong>C#</strong></div>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> InitializeProximityDevice()<br />{<br /><br />Windows.Networking.Proximity.ProximityDevice proximityDevice;<br />    proximityDevice = Windows.Networking.Proximity.ProximityDevice.GetDefault();<br /><br />    <span style="color: rgb(0, 0, 255);">if</span> (proximityDevice != <span style="color: rgb(0, 0, 255);">null</span>) {<br />        proximityDevice.DeviceArrived += ProximityDeviceArrived;<br />    <br />    }<br />    <span style="color: rgb(0, 0, 255);">else</span><br />    {<br />        <span style="color: rgb(0, 128, 0);">// No NFC radio on the PC, display an error message</span><br />    }<br />}<br /><br /><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> ProximityDeviceArrived(Windows.Networking.Proximity.ProximityDevice device)<br />{<br />            <span style="color: rgb(0, 128, 0);">// Let the user know we’re ‘Writing to Tag’</span><br /><br />}<br /></pre>
  </div>
</blockquote>

<p>
  <br />Im nächsten Schritt veröffentlichen wir Informationen auf dem Tag. Die App veröffentlicht zwei Komponenten: eine App-ID-Zeichenfolge (bestehend aus einer App-ID und App-Plattform) und Startargumente. Unter Windows 8 lautet die App-ID &lt;<a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.applicationmodel.packageid.familyname.aspx" target="_blank">Name der Paketfamilie</a>&gt;!&lt;<a href="http://msdn.microsoft.com/de-de/library/windows/apps/br211415.aspx" target="_blank">App-ID</a>&gt; und die App-Plattform „Windows“. Sie müssen den App-ID-Wert aus dem ID-Attribut des Anwendungselements in das Paketmanifest für Ihre App kopieren. Das Startargument lautet „07:00“ (der vom Benutzer festgelegte Alarm). Bezeichnen wir dieses Argument als die <b>Nachricht</b>.</p>

<p>Für plattformübergreifende Apps ermöglicht Windows das Veröffentlichen alternativer App-IDs und -Plattformen, sodass Sie denselben Tag mit anderen NFC-kompatiblen Geräten koppeln können, z. B. Windows Phone 8. Weitere Informationen zu <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.proximity.peerfinder.alternateidentities.aspx" target="_blank">Alternativen IDs</a> finden Sie auf MSDN.</p>

<p>Die Daten werden von der App mithilfe der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh701134.aspx" target="_blank">publishBinaryMessage</a>-Methode auf dem Tag veröffentlicht. Die Methode akzeptiert drei Parameter: „messageType“, „message“ und eine messageTransmittedHandler-Funktion. „messageType“ wird auf „LaunchApp:WriteTag“ festgelegt, woran Windows erkennt, dass die App Daten auf einen NFC-Tag schreiben möchte. Bei „message“ handelt es sich lediglich um die zuvor definierte Nachricht (App-ID-Zeichenfolge und Startargumente). Die Nachricht muss als binäre Nachricht in einem Puffer gespeichert werden. Die messageTransmittedHandler-Funktion registriert Rückrufe. Hierdurch erkennt die App, dass die Nachricht erfolgreich auf den Tag geschrieben wurde. Auf diese Weise kann dem Benutzer Folgendes mitgeteilt werden: Die Nachricht wurde erfolgreich auf den Tag geschrieben und der Tag muss sich nicht mehr in Reichweite befinden.</p>

<p>Nachrichten werden so lange veröffentlicht, bis die StopPublishingMessage-Funktion aufgerufen oder das ProximityDevice-Objekt freigegeben wird. In diesem Beispiel wird die Stop-Funktion verwendet. PublishBinaryMessage gibt eine Veröffentlichungs-ID zurück. Anhand dieser ID wird das Veröffentlichen der Nachricht auf dem NFC-Radio beendet.</p>

<p>Im nächsten Codeausschnitt wird das Schreiben von Daten auf einen NFC-Tag veranschaulicht:</p>

<p><strong>JavaScript</strong></p>

<blockquote>
  <div>
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> proximityDevice;<br /><br /><span style="color: rgb(0, 0, 255);">function</span> getAlarmTime(){<br /><br />    <span style="color: rgb(0, 128, 0);">// Grab time set by the user, call this variable ‘Alarm’</span><br />    <span style="color: rgb(0, 0, 255);">return</span> Alarm;<br /><br />}<br /><br /><span style="color: rgb(0, 0, 255);">function</span> publishLaunchApp() {<br />    proximityDevice = Windows.Networking.Proximity.ProximityDevice.GetDefault();<br /><br /><span style="color: rgb(0, 0, 255);">if</span> (proximityDevice) {<br />        <span style="color: rgb(0, 128, 0);">// The format of the app launch string is: &quot;&lt;args&gt;\tWindows\t&lt;AppName&gt;&quot;.</span><br />        <span style="color: rgb(0, 128, 0);">// The string is tab or null delimited.</span><br /><br />        <span style="color: rgb(0, 128, 0);">// The &lt;args&gt; string can be an empty string (&quot;&quot;).</span><br />        <span style="color: rgb(0, 0, 255);">var</span> launchArgs = getAlarmTime();<br /><br />        <span style="color: rgb(0, 128, 0);">// The format of the AppName is: PackageFamilyName!PRAID.</span><br />        <span style="color: rgb(0, 0, 255);">var</span> praid = <span style="color: rgb(0, 96, 128);">&quot;AlarmApp&quot;</span>; <span style="color: rgb(0, 128, 0);">// The Application Id value from your package.appxmanifest.</span><br /><br />        <span style="color: rgb(0, 0, 255);">var</span> appName = Windows.ApplicationModel.Package.current.id.familyName + <span style="color: rgb(0, 96, 128);">&quot;!&quot;</span> + praid;<br /><br />        <span style="color: rgb(0, 0, 255);">var</span> launchAppMessage = launchArgs + <span style="color: rgb(0, 96, 128);">&quot;\tWindows\t&quot;</span> + appName;<br /><br />        <span style="color: rgb(0, 0, 255);">var</span> dataWriter = <span style="color: rgb(0, 0, 255);">new</span> Windows.Storage.Streams.DataWriter();<br />        dataWriter.unicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.utf16LE;<br />        dataWriter.writeString(launchAppMessage);<br />        <span style="color: rgb(0, 0, 255);">var</span> launchAppPubId =<br />             proximityDevice.publishBinaryMessage(<br />                 <span style="color: rgb(0, 96, 128);">&quot;LaunchApp:WriteTag&quot;</span>, <br />                 dataWriter.detachBuffer(), <br />                 proximityWriteTagLaunchAppMessageTransmitCallback);<br />        <br />    <span style="color: rgb(0, 0, 255);">if</span> (launchAppPubId != -1) {<br />            <span style="color: rgb(0, 128, 0);">// Stop publishing the message on NFC radio</span><br />        proximityDevice.stopPublishingMessage(launchAppPubId);<br />    }<br /><br />     }<br />}<br /><br /><span style="color: rgb(0, 0, 255);">function</span> proximityWriteTagLaunchAppMessageTransmitCallback() {<br />    <span style="color: rgb(0, 128, 0);">// Inform the user that: the message has been successfully written to a tag &amp; the tag no longer needs to be in range</span><br />}<br /></pre>
  </div>
</blockquote>

<div>
  <br /><strong>C#</strong></div>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">Windows.Networking.Proximity.ProximityDevice proximityDevice;<br /><br /><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">string</span> GetAlarmTime(){<br /><br />    <span style="color: rgb(0, 128, 0);">// Grab time set by the user, call this variable ‘Alarm’</span><br />    <span style="color: rgb(0, 0, 255);">return</span> Alarm;<br />}<br /><br /><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> PublishLaunchApp()<br />{<br />    proximityDevice = Windows.Networking.Proximity.ProximityDevice.GetDefault();<br /><br /><span style="color: rgb(0, 0, 255);">if</span> (proximityDevice != <span style="color: rgb(0, 0, 255);">null</span>)<br />    {<br />        <span style="color: rgb(0, 128, 0);">// The format of the app launch string is: &quot;&lt;args&gt;\tWindows\t&lt;AppName&gt;&quot;.</span><br />        <span style="color: rgb(0, 128, 0);">// The string is tab or null delimited.</span><br /><br />        <span style="color: rgb(0, 128, 0);">// The &lt;args&gt; string can be an empty string (&quot;&quot;).</span><br />        <span style="color: rgb(0, 0, 255);">string</span> launchArgs = getAlarmTime();<br /><br />        <span style="color: rgb(0, 128, 0);">// The format of the AppName is: PackageFamilyName!PRAID.</span><br />        <span style="color: rgb(0, 0, 255);">string</span> praid = <span style="color: rgb(0, 96, 128);">&quot;MyAppId&quot;</span>; <span style="color: rgb(0, 128, 0);">// The Application Id value from your package.appxmanifest.</span><br /><br />        <span style="color: rgb(0, 0, 255);">string</span> appName = Windows.ApplicationModel.Package.Current.Id.FamilyName + <span style="color: rgb(0, 96, 128);">&quot;!&quot;</span> + praid;<br /><br />        <span style="color: rgb(0, 0, 255);">string</span> launchAppMessage = launchArgs + <span style="color: rgb(0, 96, 128);">&quot;\tWindows\t&quot;</span> + appName;<br /><br />        var dataWriter = <span style="color: rgb(0, 0, 255);">new</span> Windows.Storage.Streams.DataWriter();<br />        dataWriter.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf16LE;<br />        dataWriter.WriteString(launchAppMessage);<br />        var launchAppPubId =<br />        proximityDevice.PublishBinaryMessage(<br />            <span style="color: rgb(0, 96, 128);">&quot;LaunchApp:WriteTag&quot;</span>, dataWriter.DetachBuffer(), <br />            proximityWriteTagLaunchAppMessageTransmitCallback);<br />    <br />    <span style="color: rgb(0, 0, 255);">if</span> (launchAppPubId!= -1)<br />    {<br />        proximityDevice.StopPublishingMessage(launchAppPubId);<br />    <span style="color: rgb(0, 128, 0);">// Stop publishing the message on NFC radio</span><br />    }<br /><br />    }<br />}<br /><br /><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> proximityWriteTagLaunchAppMessageTransmitCallback(<br />    Windows.Networking.Proximity.ProximityDevice sender,<br />    <span style="color: rgb(0, 0, 255);">long</span> messageId)<br />{<br />        <span style="color: rgb(0, 128, 0);">// Inform the user that: the message has been successfully written to a tag &amp; the tag no longer needs to be in range</span><br />}<br /></pre>
  </div>
</blockquote>

<br />So einfach ist das! Jetzt wissen Sie, wie über eine Windows Store-App Informationen auf einen NFC-Tag geschrieben werden können. Betrachten wir nun also das nächste Szenario, das Einstellen eines Alarms <b>vom</b> Tag. Im Folgenden werden die Schritte zum Lesen eines Alarms von einem NFC-Tag veranschaulicht: 

<ol>
  <li>Jens betrachtet gerade den Startbildschirm, verfasst eine E-Mail, spielt ein Spiel oder nutzt Windows für eine beliebige andere Aufgabe, als ihm einfällt, dass er einen Alarm für Montag morgen einstellen muss. Er nimmt seinen „Wochentagsalarm“-Tag zur Hand und koppelt diesen mit seinem PC. Ein Aufforderung zum Starten der Alarm-App wird angezeigt. Bis zu diesem Punkt werden sämtliche Vorgänge von Windows ausgeführt, die App spielt noch keine Rolle.</li>

  <li>Jens stimmt zu und die App zeigt einen Bildschirm zum Bestätigen des Alarms um 07:00 Uhr an. Daraufhin werden die Startargumente (wie im obigen Beispiel) von Windows während der Aktivierung an die App übergeben. Dieser Vorgang wird als kontextgebundener Start bezeichnet und gleicht dem direkten Starten einer bestimmten Seite der App.</li>

  <li>Jens stellt den Alarm ein, ein ganz normaler Vorgang ohne Beteiligung von NFC.</li>
</ol>

<p>Die Startargumente können problemlos vom NFC-Tag abgerufen werden. Der kontextgebundene Start über einen NFC-Tag muss jedoch von der App ausgeführt werden. Bei einem kontextgebundenen Start handelt es sich um eine andere Bezeichnung für das direkte Starten einer bestimmten Seite der App. In den Startargumenten ist der Alarm „07:00 Uhr“ angegeben, der von der App als Alarmvorschlag angezeigt wird. Fall die App nicht auf dem PC installiert ist, bietet Windows Jens außerdem die Option, die App automatisch aus dem Windows Store installieren zu lassen.</p>

<p>Im folgenden Codeausschnitt ist die Implementierung des kontextgebundenen Starts veranschaulicht.</p>

<p><strong>JavaScript</strong></p>

<blockquote>
  <div>
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">app.onactivated = <span style="color: rgb(0, 0, 255);">function</span> (args) {<br />    <span style="color: rgb(0, 0, 255);">if</span> (args.detail.kind === activation.ActivationKind.launch) {<br />        <span style="color: rgb(0, 0, 255);">if</span> (args.detail.arguments == <span style="color: rgb(0, 96, 128);">&quot;Windows.Networking.Proximity.PeerFinder:StreamSocket&quot;</span>) {<br />            <span style="color: rgb(0, 128, 0);">//do nothing here.</span><br />        }<br />        <span style="color: rgb(0, 0, 255);">else</span> {<br />    <span style="color: rgb(0, 128, 0);">// Use args.detail.arguments to parse out ’07.00’ string, and display to the user</span><br />        }<br /><br />        args.setPromise(WinJS.UI.processAll());<br />    }<br />}<br /></pre>
  </div>
</blockquote>

<div>
  <br /><strong>C#</strong></div>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">async <span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> OnLaunched(LaunchActivatedEventArgs args)<br />        {<br />            <span style="color: rgb(0, 0, 255);">if</span> (args.Arguments == <span style="color: rgb(0, 96, 128);">&quot;Windows.Networking.Proximity.PeerFinder:StreamSocket&quot;</span>)<br />            {<br />                _isLaunchedByTap = <span style="color: rgb(0, 0, 255);">true</span>;<br />            }<br />            <span style="color: rgb(0, 0, 255);">else</span><br />            {<br /><span style="color: rgb(0, 128, 0);">// Use args.Arguments to parse out ’07.00’ string, and display to the user</span><br /><br />            }<br />            Window.Current.Activate();<br />        }<br /></pre>
  </div>
</blockquote>

<p>
  <br />Das ist alles, was eine App zur Unterstützung von Lese- und Schreibvorgängen auf einen NFC-Tag benötigt – ziemlich einfach für ein Szenario mit modernster Technologie. Vor der Zusammenfassung möchte ich noch auf einige schützende Maßnahmen eingehen – Fehlerbehandlung.</p>

<h2>Fehlerbehandlung</h2>

<p>Im Folgenden finden Sie einige häufige Fehler, die in dieser App auftreten können.</p>

<ul>
  <li>Der gekoppelte Tag liegt nicht im NDEF-Format vor. Die automatische Neuformatierung eines Tags in NDEF wird von Windows 8 nicht unterstützt, daher müssen Sie eine NDEF-Formatierungsanwendung herunterladen und installieren.</li>

  <li>Der gekoppelte Tag ist schreibgeschützt. Einige NFC-Tags sind möglicherweise schreibgeschützt (ähnliche wie alte <a href="http://de.wikipedia.org/wiki/Video_Home_System" target="_blank">VHS-Kassetten</a>).</li>

  <li>Der gekoppelte Tag ist zu klein und bietet nicht genügend Platz für sämtliche Daten.</li>

  <li>Der Benutzer-PC verfügt nicht über NFC. Wie anfangs erwähnt, handelt es sich bei NFC um eine neue, noch nicht weit verbreitete Technologie, die jedoch in zunehmendem Maße eingesetzt wird. Verwenden Sie die ProximityDevice.getDefault()-Methode, um zu ermitteln, ob Näherung von einem PC unterstützt wird. Wenn keine NFC-Radios installiert sind, gibt die Methode NULL zurück.</li>
</ul>

<h2>Einfach und intuitiv</h2>

<p>NFC ist endlich für den Endverbrauchermarkt bereit, und Windows bietet das entsprechende Ökosystem sowie eine hervorragende Benutzerfreundlichkeit für sämtliche zugehörige Vorgänge. Die Technologie bietet ein enormes Potenzial zur Entwicklung unglaublich interaktiver Apps und Geräte – einfach und intuitiv. </p>

<p>NFC ist ein großer Themenbereich: Sie können also auf weitere Blogbeiträge über andere interessante Erfahrungen im Rahmen der NFC-Entwicklung unter Windows 8 gespannt sein.</p>

<p>Weitere Informationen zu NFC und Näherung finden Sie in den folgenden Ressourcen.</p>

<h2>Ressourcen</h2>

<div align="center">
  <table class="b8table" cellspacing="0" cellpadding="3" width="298" align="center" border="0"><tbody>
      <tr>
        <td valign="top" width="197">
          <p><strong>Link</strong></p>
        </td>

        <td valign="top" width="99">
          <p><strong>Typen</strong></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="197">
          <p align="left"><u><a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh465215.aspx" target="_blank">Richtlinien für das Entwickeln mithilfe von Näherung (Windows Store-Apps)</a></u></p>
        </td>

        <td valign="top" width="99">
          <p>Dokumentation</p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="197">
          <p align="left"><a href="http://msdn.microsoft.com/de-de/library/windows/apps/br241250.aspx" target="_blank">Näherungs-APIs</a></p>
        </td>

        <td valign="top" width="99">
          <p>Dokumentation</p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="197">
          <p align="left"><a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh967765.aspx" target="_blank">Testen der Näherung in Apps und Behandeln von Problemen (Windows Store-Apps mit JavaScript und HTML)</a></p>
        </td>

        <td valign="top" width="99">
          <p>Dokumentation</p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="197">
          <p align="left"><a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh465223.aspx" target="_blank">Schnellstart: Veröffentlichen und Abonnieren von Nachrichten durch Koppeln (Windows Store-Apps mit JavaScript und HTML)</a></p>
        </td>

        <td valign="top" width="99">
          <p>Dokumentation</p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="197">
          <p align="left"><a href="http://code.msdn.microsoft.com/windowsapps/Proximity-Sample-88129731" target="_blank">Proximity sample</a></p>
        </td>

        <td valign="top" width="99">
          <p>Beispiel</p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="197">
          <p align="left"><a href="http://social.msdn.microsoft.com/Forums/de-de/category/windowsapps" target="_blank">Fragen zu Näherung? Hier erhalten Sie Antworten.</a></p>
        </td>

        <td valign="top" width="99">
          <p>Forum</p>
        </td>
      </tr>
    </tbody></table>
</div>

<p>Vielen Dank!</p>

<p>Priya Dandawate 
  <br />Programmmanager, Devices and Networking</p>

<p>Unter Mitarbeit von: Max Morris, Marzena Makuta, Mike Loholt, Jake Sabulsky und Vishal Mhatre</p>

<!-- Title: “Entwickeln moderner Apps mit NFC” Tags: “Teilen, NFC, Near Field Communication, Dateien teilen, Bluetooth-Kopplung, Daten teilen” --></div>]]></content:encoded>
    </item>
    <item>
      <title>Erstellen verbundener Windows Store-Apps</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_de/erstellen-verbundener-windows-store-apps</link>
      <pubDate>Wed, 17 Apr 2013 13:55:07 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_de/2013/04/17/erstellen-verbundener-windows-store-apps/</guid>
      <description><![CDATA[Benutzer sind ständig von Geräten umgeben, die mit einem Netzwerk verbunden sind. Selbst die...]]></description>
      <content:encoded><![CDATA[<div class="postcontent">  <p>Benutzer sind ständig von Geräten umgeben, die mit einem Netzwerk verbunden sind. Selbst die neuesten Kühlschränke und Waschmaschinen können eine Verbindung mit dem Internet oder mit einem Heimnetzwerk herstellen. Daher ist es nicht überraschend, wenn Endbenutzer erwarten, dass ihre Apps ebenfalls über eine Verbindung verfügen. Diese „verbundenen Apps“ rufen aktuelle Inhalte aus dem Web ab – soziale Medien, digitale Medien, Blogs und andere Inhaltstypen. Die Entwicklung verbundener Apps ist mittlerweile zur Regel geworden. Dennoch kann die Bewältigung häufiger Probleme wie Unterbrechungen der Netzwerkverbindung, die Kosten getakteter Netzwerke oder unzureichende Leistung eine Herausforderung darstellen. Mit Windows 8 ist es einfacher als je zuvor, eine verbundene App zu erstellen. </p>  <p>In diesem Beitrag werden einige nützliche Tipps erläutert, die Sie beim Entwickeln schneller, flüssiger, benutzerfreundlicher und verbundener Windows Store-Apps unterstützen: </p>  <ul>   <li>Auswählen der passenden API für Ihre Szenarien</li>    <li>Auswählen der richtigen Netzwerkfunktionen</li>    <li>Anpassen des App-Verhaltens für getaktete Netzwerke</li>    <li>Reagieren auf Änderungen des Netzwerkstatus</li>    <li>Zwischenspeichern von Inhalten für eine flüssige Darstellung</li> </ul>  <p>Sehen wir uns jeden dieser Tipps genauer an.</p>  <h2>Auswählen der passenden API</h2>  <p>Wenn Sie ein Haus bauen, sollten Sie dazu geeignete Werkzeuge verwenden: einen Hammer zum Einschlagen von Nägeln, eine Säge zum Zersägen von Brettern und einen Schraubendreher zum Befestigen von Schrauben. Gleichermaßen sollten Sie beim Entwickeln einer verbundenen Windows Store-App die passenden Netzwerk-APIs einsetzen. Windows 8 stellt eine Vielzahl von Netzwerk-APIs zur Verfügung, die von Ihrer App für die Kommunikation mit anderen Computern und Geräten genutzt werden können, ob über das Internet oder in privaten Netzwerken. Zunächst sollten Sie also überlegen, welche Netzwerkfunktionen von Ihrer App benötigt werden. </p>  <p>Eines der häufigsten Netzwerkszenarien ist der Zugriff auf eine Website, um Informationen abzurufen oder zu speichern. Ein einfaches Beispiel hierfür könnte ein Spiel sein, das eine Website verwendet, um Benutzerinformationen und Spielstände zu speichern. Ein komplexeres Beispiel könnte eine App darstellen, die eine Verbindung mit einem REST-basierten Webdienst herstellt, um eine vom Dienst bereitgestellte Bibliothek zum Abrufen und Speichern von Informationen zu nutzen. Windows 8 beinhaltet verschiedene APIs zum Herstellen von Verbindungen mit Webdiensten und Websites. Mithilfe dieser APIs kann Ihre App auf Webdienste mit REST-Unterstützung zugreifen oder grundlegende HTTP-Protokollbefehle (wie GET und POST) an einen Webserver senden. Die jeweilige für den Webzugriff benötigte API hängt von der Sprache ab, die Sie bei der Entwicklung der App verwenden:</p>  <ul>   <li>In JavaScript und HTML geschriebene Apps: <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh453379.aspx" target="_blank">XMLHTTPRequest</a> und <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br229787.aspx" target="_blank">WinJS.xhr</a></li>    <li>In C# oder Visual Basic .NET und XAML geschriebene Apps: <a href="http://msdn.microsoft.com/de-de/library/system.net.http.httpclient.aspx" target="_blank">HttpClient</a> </li>    <li>In C++ und XAML geschriebene Apps: <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh831163.aspx" target="_blank">XML HTTP Request 2</a> (IXHR2)</li> </ul>  <p>Im folgenden Code wird das Ausführen einer grundlegenden Anforderung und Antwort mit einem REST-basierten Webdienst dargestellt. Beispielsweise könnte in diesem Fall ein ASP.NET-Skript auf dem Webserver vom Webdienst ausgeführt werden.</p>  <p><strong>JavaScript</strong></p>  <blockquote>   <div id="codeSnippetWrapper">     <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> makeXHRCall() {<br />    WinJS.xhr({ uri: <span style="color: rgb(0, 96, 128);">&quot;http://www.microsoft.com/en-us/default.aspx” }).done(<br />        function onComplete(result) {<br />            print(result.responseText);<br />        },<br />        function onError(err) {<br />            print(&quot;</span>Error: &quot; + err.responseText);<br />        });<br />}<br /></pre>
  </div>
</blockquote>

<p><strong>C#</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">private</span> async <span style="color: rgb(0, 0, 255);">void</span> MakeHttpCall()<br />{<br />    HttpClient httpClient = <span style="color: rgb(0, 0, 255);">new</span> HttpClient();<br />    <span style="color: rgb(0, 0, 255);">try</span> {<br />        <span style="color: rgb(0, 0, 255);">string</span> response = await httpClient.GetStringAsync(<span style="color: rgb(0, 96, 128);">&quot;http://www.microsoft.com/en-us/default.aspx&quot;</span>);<br />    }<br />    <span style="color: rgb(0, 0, 255);">catch</span> (Exception) {<br />        <span style="color: rgb(0, 128, 0);">// Handle exception.</span><br />    }<br />}<br /></pre>

    <br /></div>
</blockquote>

<p>Weitere Informationen zu <b>WinJS.xhr</b> finden Sie unter<u> </u><a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh761502.aspx" target="_blank">Herstellen einer Verbindung mit Webdiensten (Windows Store-Apps mit JavaScript und HTML)</a>. Weitere Informationen zu <b>HttpClient</b> finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/xaml/hh781239.aspx" target="_blank">Schnellstart: Verbinden mit HttpClient (Windows Store-Apps mit C#/VB/C++ und XAML)</a> und unter <a href="http://code.msdn.microsoft.com/windowsapps/HttpClient-sample-55700664" target="_blank">HttpClient sample</a>.</p>

<p>Ein weiteres häufiges Netzwerkszenario besteht im Herunterladen oder Hochladen von Dateien, wobei die Dateiübertragung etwas Zeit in Anspruch nehmen kann. Ein Beispiel hierfür sind Kamera- oder Fotogalerie-Apps, die einen Webdienst zum Hochladen oder Herunterladen von Fotos oder Fotoalben verwenden. Diese Übertragungen beanspruchen möglicherweise viel Zeit, daher macht es wenig Sinn, den Benutzer auf das Fertigstellen der Übertragung warten zu lassen. Die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.backgroundtransfer.aspx" target="_blank">Windows.Networking.BackgroundTransfer</a>-API ermöglicht das Herunterladen oder Hochladen von Dateien, auch wenn die App nicht mehr ausgeführt wird. Die App startet die Übertragung, während sie im Vordergrund ausgeführt wird und sich im Fokus befindet. Anschließend setzt Windows 8 die Übertragung im Hintergrund fort, auch wenn die App nicht mehr ausgeführt wird.</p>

<p>Ein weiteres, spezielleres Szenario ist der Zugriff auf Inhalte von Fremdanbietern. Die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.web.syndication.aspx" target="_blank">Windows.Web.Syndication</a>-API kann Feeds im RSS- oder Atom-Format abrufen. Zudem kann eine App mithilfe der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.web.atompub.aspx" target="_blank">Windows.Web.AtomPub</a>-API Daten in verschiedenen AtomPub-Formaten veröffentlichen.</p>

<p>Für Szenarien, in denen spezifische übergeordnete Netzwerkprotokolle nicht von APIs bereitgestellt werden können, unterstützt die Windows-Runtime zudem TCP- und UDP-Sockets (zusammen mit Multicast). Die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.sockets.aspx" target="_blank">Windows.Networking.Sockets</a>-API stellt einen <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.sockets.streamsocket.aspx" target="_blank">StreamSocket</a> (TCP) und <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.sockets.datagramsocket.aspx" target="_blank">DatagramSocket</a> (UDP) zum Implementieren anderer, übergeordneter Protokolle zur Verfügung.</p>

<p><b>Hinweis: </b>Mit Windows 8 wird ein neuer Socket-Typ mit der Bezeichnung <i>WebSocket</i> eingeführt. Weitere Informationen zu WebSockets und deren Verwendungsmöglichkeiten finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh761442.aspx" target="_blank">Verbinden mit WebSockets</a>.</p>

<p>In der folgenden Tabelle finden Sie eine ausführlichere Liste unterstützter Netzwerkfunktionen sowie Links zu weiteren Informationen.</p>

<div align="center">  <table class="b8table" cellspacing="0" cellpadding="3" align="center" border="0"><tbody>
      <tr>
        <td valign="top" width="217">
          <p align="center"><b>APIs</b><b></b></p>
        </td>

        <td valign="top" width="221">
          <p align="center"><b>Funktionen</b><b></b></p>
        </td>

        <td valign="top" width="145">
          <p align="center"><b>Beispiele</b><b></b></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="217">
          <ul>
            <li>
              <div align="left"><b><a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.web.syndication.aspx" target="_blank">Windows.Web.Syndication</a></b><b></b></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left"><b><a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.web.atompub.aspx" target="_blank">Windows.Web.AtomPub</a></b><b></b></div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>

        <td valign="top" width="221">
          <p align="left"></p>

          <p align="left">Abrufen von Feeds im RSS- oder Atom-Format in verschiedenen Versionen. Durch diese APIs wird die Implementierung von Unterstützung neuerer Formate wie beispielsweise OData erleichtert. Die Windows-Runtime unterstützt außerdem das Atom Publishing Protocol und ermöglicht so das Veröffentlichen von Atom-Auflistungen. 
            <br />Weitere Informationen finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh452973.aspx/" target="_blank">Zugreifen auf und Verwalten von Inhalten von Fremdanbietern</a>.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="145">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/Syndication-sample-07ef6b0d" target="_blank">Syndication sample</a></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/AtomPub-sample-c1fcdc8e" target="_blank">AtomPub sample</a></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">RSS-Reader</div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="217">
          <p align="left"></p>

          <p align="left"><b><a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.backgroundtransfer.aspx" target="_blank">Windows.Networking.BackgroundTransfer</a></b></p>

          <p align="left"></p>
        </td>

        <td valign="top" width="221">
          <p align="left"></p>

          <p align="left">Kostenbewusstes und wiederaufnehmbares Herunterladen und Hochladen von Inhalten ohne Unterbrechungen, auch wenn die aufrufende App nicht im Vordergrund ausgeführt wird. Diese API unterstützt die Übertragung von Inhalten mithilfe der HTTP-, HTTPS- und FTP-Protokolle. 
            <br />Weitere Informationen finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh452979.aspx" target="_blank">Übertragen von Daten im Hintergrund</a>.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="145">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/Background-Transfer-Sample-d7833f61" target="_blank">Background Transfer sample</a></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">SkyDrive</div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Xbox Video</div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="217">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left"><b><a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh453379.aspx" target="_blank">XMLHTTPRequest</a></b><b> (JavaScript</b><b>) </b></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left"><b><a href="http://msdn.microsoft.com/de-de/library/windows/apps/br229787.aspx" target="_blank">WinJS.xhr</a></b><b> </b><b>(JavaScript)</b></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left"><b><a href="http://msdn.microsoft.com/de-de/library/system.net.http.httpclient.aspx" target="_blank">HttpClient</a></b><b> </b><b>(C#)</b></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left"><b><a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh831163.aspx">XML HTTP Request 2</a></b><b> (IXHR2)</b><b> </b><b>(C++)</b><b></b></div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>

        <td valign="top" width="221">
          <p align="left"></p>

          <p align="left">Interaktion mit REST-basierten Webdiensten und anderen HTTP-basierten Protokollen. 
            <br />Weitere Informationen finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh761502.aspx" target="_blank">Herstellen einer Verbindung mit Webdiensten</a>.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="145">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/XHR-handling-navigation-50d03a7a" target="_blank">XHR, handling navigation errors, and URL schemes sample</a></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/HttpClient-sample-55700664" target="_blank">HttpClient sample</a></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Bing Maps</div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="217">
          <p align="left"></p>

          <p align="left"><b><a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.proximity.aspx" target="_blank">Windows.Networking.Proximity</a></b></p>

          <p align="left"></p>
        </td>

        <td valign="top" width="221">
          <p align="left"></p>

          <p align="left">Erkennung der unmittelbaren räumlichen Nähe zweier Geräte, damit Apps mithilfe von Socket-APIs eine Netzwerkverbindung dazwischen herstellen können. 
            <br />Weitere Informationen finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh465229.aspx" target="_blank">Unterstützen von Näherung und Kopplung</a>.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="145">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/Proximity-Sample-88129731" target="_blank">Proximity sample</a></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Spiele</div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Apps für die Zusammenarbeit</div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="217">
          <p align="left"></p>

          <p align="left"><b><a href="http://msdn.microsoft.com/library/windows/apps/BR207928" target="_blank">Windows.Storage.Pickers</a></b><b></b></p>

          <p align="left"></p>
        </td>

        <td valign="top" width="221">
          <p align="left"></p>

          <p align="left">Kommunikation mit Remotedateifreigaben. 
            <br />Weitere Informationen finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh464959.aspx" target="_blank">Zugreifen auf Daten und Dateien</a>.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="145">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/File-picker-sample-9f294cba" target="_blank">File picker sample</a></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Xbox Music</div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Fotos</div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="217">
          <p align="left"></p>

          <p align="left"><b><a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.sockets.aspx" target="_blank">Windows.Networking.Sockets</a></b><b></b></p>

          <p align="left"></p>
        </td>

        <td valign="top" width="221">
          <p align="left"></p>

          <p align="left">Herstellen einer Verbindung mit einem Dienst, der ein Protokoll verwendet, das von den bisher genannten APIs nicht unterstützt wird (z. B. SMTP, MAPI oder Telnet), bzw. mit einem anderen Gerät im selben lokalen Netzwerk. Wird ebenfalls für Apps verwendet, die socketähnliche Semantik (asynchron, bidirektional) erfordern, um über das Web (einschließlich HTTP-Proxys) eine Verbindung mit einem neuen Dienst herzustellen. 
            <br />Weitere Informationen finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh452977.aspx" target="_blank">Verbinden mit Sockets</a>.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="145">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/StreamSocket-Sample-8c573931" target="_blank">StreamSocket sample</a></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/DatagramSocket-sample-76a7d82b" target="_blank">DatagramSocket sample</a></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/Connecting-with-WebSockets-643b10ab" target="_blank">Connecting with WebSockets sample</a></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/site/search?query=controlchanneltrigger&amp;f%5B0%5D.Value=controlchanneltrigger&amp;f%5B0%5D.Type=SearchText&amp;ac=3" target="_blank">ControlChannelTrigger samples</a></div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Lync, Whiteboards zur Zusammenarbeit oder Stockpicker</div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="217">
          <p align="left"></p>

          <p align="left"><b><a href="http://msdn.microsoft.com/library/windows/apps/BR241587" target="_blank">Windows.Storage.ApplicationData</a></b></p>

          <p align="left"></p>
        </td>

        <td valign="top" width="221">
          <p align="left"></p>

          <p align="left">Windows 8 überträgt automatisch bestimmte Anwendungsdaten zwischen Benutzergeräten. Das Roaming von Anwendungsdaten ist für Apps vorteilhaft, die von Benutzern auf mehreren Geräten verwendet (beispielsweise einem Büro-PC und einem privaten Tablet) und installiert werden. 
            <br />Weitere Informationen finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh465094.aspx" target="_blank">Richtlinien für das Roaming von Anwendungsdaten</a>.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="145">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left"><a href="http://go.microsoft.com/fwlink/p/?linkid=231478" target="_blank">Application data sample</a></div>
            </li>
          </ul>
        </td>
      </tr>
    </tbody></table>
</div>

<h2>Auswählen der richtigen Netzwerkfunktionen</h2>

<p>Netzwerkisolation ist eine Komponente des App-Sicherheitsmodells von Windows 8. Windows erkennt aktiv Netzwerkgrenzen und erzwingt Zugriffseinschränkungen zwecks Netzwerkisolation. Wenn Sie diese Funktionen richtig bereitstellen, können Sie Benutzer und Apps vor böswilligen Angriffen schützen.</p>

<p>Apps müssen Netzwerkisolationsfunktionen deklarieren, um das Ausmaß des Netzwerkzugriffs festzulegen. Ohne Deklaration dieser Funktionen kann die App nicht auf Netzwerkressourcen zugreifen. Weitere Informationen zum Erzwingen der Netzwerkisolation für Apps durch Windows finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/Hh770532.aspx" target="_blank">So wird's gemacht: Festlegen von Netzwerkfunktionen</a>. </p>

<p>Beachten Sie, dass Netzwerkfunktionen nicht als Kommunikationsmechanismus zwischen den Prozessen einer Windows Store-App und einer Desktop-App verwendet werden können, die sich auf demselben Gerät befinden. Beispielsweise ist es nicht möglich, IP-Loopbackadressen für eine Windows Store-App zu nutzen. Zu Entwicklungszwecken gelten bestimmte Ausnahmen, die die Verwendung von IP-Loopbackadressen im Visual Studio-Debugger ermöglichen. Weitere Informationen finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/Hh780593.aspx" target="_blank">So wird's gemacht: Aktivieren von Loopback und Problembehandlung bei der Netzwerkisolation</a>.</p>

<p>Netzwerkzugriffsanforderungen werden in die folgenden beiden Kategorien unterteilt: </p>

<ol>
  <li><b>Ausgehende, vom Client initiierte Anforderungen</b>: Die App fungiert als Client und initiiert den Netzwerkzugriff durch das Senden einer ersten Netzwerkanforderung an einen Remotecomputer, in der Regel einen Server. Die App sendet eine oder mehrere Anforderungen an den Server, und der Server gibt eine oder mehrere Antworten zurück. Der gesamte Datenverkehr zwischen einer Webclient-App und einem Webserver ist ein Beispiel für diese Kategorie.</li>

  <li><b>Eingehende, unaufgeforderte Anforderungen</b>: Die App übernimmt die Rolle eines Netzwerkservers und lauscht nach eingehenden Netzwerkanforderungen von einem Remotecomputer. Der Remotecomputer initiiert den Netzwerkzugriff durch das Senden einer ersten Anforderung an die App, die als Server fungiert. Der Remotecomputer sendet eine oder mehrere Anforderungen an die App, die eine oder mehrere Antworten an den Remotecomputer zurückgibt. Ein Beispiel für diese Kategorie wäre eine App, die als Medienserver dient.</li>
</ol>

<p>Gehen Sie nach dem Prinzip der geringsten Rechte vor, und fügen Sie Ihrer App ausschließlich benötigte Funktionen hinzu. Möglicherweise sind für Ihre App nur ausgehende, vom Client initiierte Anforderungen erforderlich. Es kann jedoch auch sein, dass eingehende unaufgeforderte Anforderungen empfangen werden können müssen. Für einige Apps kann zwecks Authentifizierung über ein Netzwerk auch der Zugriff auf Anmeldeinformationen von Benutzern und Zertifikate erforderlich sein. </p>

<p>In der folgenden Tabelle werden die Netzwerkisolationsfunktionen und weitere ähnliche Funktionen aufgeführt, die häufig für verbundene Apps benötigt werden. Bei den ersten drei Funktionen handelt es sich um die primären in verbundenen Apps eingesetzten Netzwerkisolationsfunktionen. Tatsächlich muss in einer verbundenen App mindestens eine dieser ersten drei Funktionen aktiviert sein. Die anderen Einträgen in der Tabelle stellen zusätzliche Funktionen dar, die häufig für einige verbundene Apps erforderlich sind.</p>

<p> </p>

<div align="center">
  <table class="b8table" cellspacing="0" cellpadding="3" width="612" align="center" border="0"><tbody>
      <tr>
        <td valign="top" width="146">
          <p><b>Netzwerkfunktion</b></p>
        </td>

        <td valign="top" width="273">
          <p><b>Beschreibung</b></p>
        </td>

        <td valign="top" width="191">
          <p><b>App-Beispiele</b></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="146">
          <p align="left">Internet (Client)</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="273">
          <p align="left"></p>

          <p align="left">Stellt ausgehenden Zugriff auf das Internet und öffentliche Netzwerke bereit, z. B. auf Flughäfen oder in Cafés. Diese Funktion muss für die meisten Apps deklariert werden, die Internetzugang benötigen.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="191">
          <p align="left">        </p>

          <ul>
            <li>
              <div align="left">RSS-Reader</div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Soziale Netzwerke</div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Spiele</div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="146">
          <p align="left"></p>

          <p align="left">Internet (Client und Server)</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="273">
          <p align="left"></p>

          <p align="left">Stellt sowohl eingehenden als auch ausgehenden Zugriff auf das Internet und öffentliche Netzwerke bereit, z. B. auf Flughäfen oder in Cafés. Eingehender Zugriff auf wichtige Ports wird stets blockiert. Diese Funktion beinhaltet die gesamte Internet (Client)-Funktion, es müssen daher nicht beide deklariert werden.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="191">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left">P2P-Apps</div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Multiplayer-Spiele, in denen Spieler per Multicast erkannt werden</div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="146">
          <p align="left"></p>

          <p align="left">Private Netzwerke (Client und Server)</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="273">
          <p align="left"></p>

          <p align="left">Stellt eingehenden und ausgehenden Netzwerkzugriff an privaten, vertrauenswürdigen Standorten bereit. Hierbei handelt es sich in der Regel um Heim- oder Unternehmensnetzwerke. Eingehender Zugriff auf wichtige Ports wird stets blockiert.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="191">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left">Apps mit Zugriff auf NAS (Network Attached Storage)-Inhalte</div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Branchen-Apps</div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Multiplayer-Spiele, in denen Spieler in einem privaten Netzwerk (Heimnetz oder Unternehmensnetzwerk) per Multicast erkannt werden</div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="146">
          <p align="left"></p>

          <p align="left">Näherung</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="273">
          <p align="left"></p>

          <p align="left">Erforderlich für die Nahfeldkommunikation zwischen Geräten. Ermöglicht Apps den Netzwerkzugriff, um eine Verbindung mit einem Gerät in der unmittelbaren Umgebung herzustellen. Die Benutzer müssen dem Senden oder Annehmen einer Einladung zustimmen.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="191">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left">Multiplayer-Spiele mit Personen in der näheren Umgebung<i></i></div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="146">
          <p align="left"></p>

          <p align="left">Unternehmensauthentifizierung</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="273">
          <p align="left"></p>

          <p align="left">Bietet die Möglichkeit, auf Intranetressourcen von Unternehmen zuzugreifen, für die Domänenanmeldeinformationen erforderlich sind.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="191">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left">Branchen-Apps</div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="146">
          <p align="left"></p>

          <p align="left">Freigegebene Benutzerzertifikate</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="273">
          <p align="left"></p>

          <p align="left">Bietet die Möglichkeit, zur Überprüfung der Benutzeridentität auf Software- und Hardwarezertifikate (z. B. Smartcardzertifikate) zuzugreifen. Wenn zugehörige APIs zur Laufzeit aufgerufen werden, muss der Benutzer eine Aktion ausführen (z. B. Karte einführen oder ein Zertifikat auswählen). </p>

          <p align="left"></p>
        </td>

        <td valign="top" width="191">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left">VPN-Apps</div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Branchen-Apps</div>
            </li>
          </ul>
        </td>
      </tr>
    </tbody></table>
</div>

<p>Anhand der folgenden Prüfliste können Sie sicherstellen, ob die Netzwerkisolation für Ihre App konfiguriert ist:</p>

<ul>
  <li>Ermitteln Sie, welche Richtung des Netzwerkzugriffs für Ihre App erforderlich ist: ausgehende, vom Client initiierte Anforderungen, eingehende unaufgeforderte Anforderungen oder beide.</li>

  <li>Ermitteln Sie, mit welchen Arten von Netzwerkressourcen Ihre App kommunizieren soll: vertrauenswürdige Ressourcen in einem Heim- oder Unternehmensnetzwerk, Internetressourcen oder beiden. </li>

  <li>Konfigurieren Sie im App-Manifest die mindestens erforderlichen Netzwerkisolationsfunktionen. Verwenden Sie hierzu den <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br230259.aspx" target="_blank">App-Manifest-Designer</a> in Microsoft Visual Studio 2012 oder <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br211477.aspx" target="_blank">fügen Sie sie manuell hinzu</a>.</li>

  <li>Testen Sie die Bereitstellung und Ausführung Ihrer App, indem Sie die Netzwerkisolationstools für die Problembehandlung verwenden. Weitere Informationen finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/Hh780593.aspx" target="_blank">So wird's gemacht: Aktivieren von Loopback und Problembehandlung bei der Netzwerkisolation</a>.</li>
</ul>

<p>Im folgenden Screenshot wird veranschaulicht, wie die Netzwerkfunktionen mit dem <a href="http://msdn.microsoft.com/de-de/library/windows/apps/br230259.aspx" target="_blank">App-Manifest-Designer</a> in Microsoft Visual Studio 2012 aktiviert werden.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/7268.app-manifest-design_47107BBF.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/7268.app_2D00_manifest_2D00_design_5F00_47107BBF.png"><img title="Auswählen der Netzwerkfunktionen für Ihre App im package.appxmanifest mit Visual Studio 2012" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Auswählen der Netzwerkfunktionen für Ihre App im package.appxmanifest mit Visual Studio 2012" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/7752.app-manifest-design_thumb_5EC7B325.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/7752.app_2D00_manifest_2D00_design_5F00_thumb_5F00_5EC7B325.png" width="600" height="318" /></a></p>

<p align="center"><em>Auswählen der Netzwerkfunktionen für Ihre App im package.appxmanifest mit Visual Studio 2012</em></p>

<h2>Anpassen des App-Verhaltens für getaktete Netzwerke</h2>

<p>Vielleicht erinnern Sie sich daran, wie Sie das letzte Mal das monatliche Datenlimit erreicht haben oder im Ausland unterwegs waren. In diesen Situationen verwenden Benutzer ihre Geräte und Apps in der Regel sehr zurückhaltend, um unnötige Netzwerkgebühren zu vermeiden. </p>

<p>Unter Windows 8 wird dieses Problem behoben, indem das Überwachen der verfügbaren Netzwerkressourcen durch die Apps und ein entsprechendes Verhalten in getakteten Netzwerken ermöglicht wird. Um das Vertrauen der Benutzer in Ihre Apps zu stärken, können Sie dafür sorgen, dass Ihre App anfallende Verbindungskosten erkennt und sich so verhält, dass diese Kosten vermieden oder verringert werden.</p>

<p>Die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.aspx" target="_blank">Windows.Networking.Connectivity</a>-API stellt Informationen zu Typen und Kosten von Netzwerkverbindungen bereit. Dadurch kann Ihre App ermitteln, in welcher Situation die Netzwerkressourcen normal, eher konservativ oder benutzerdefiniert verwendet werden sollten. </p>

<p>Ein <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectionprofile.aspx" target="_blank">ConnectionProfile</a> stellt eine Netzwerkverbindung dar. Ihre App kann mit der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.aspx" target="_blank">ConnectionCost</a>-Klasse einer <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectionprofile.aspx" target="_blank">ConnectionProfile</a>-Klasse ermitteln, ob das Verhalten angepasst werden soll. Durch die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.networkcosttype.aspx" target="_blank">NetworkCostType</a>-Eigenschaft wird der Typ einer Netzwerkverbindung angegeben. Folgende vier Werte sind möglich:</p>

<ul>
  <li><b>Unrestricted</b> – Die Netzwerkverbindung kann uneingeschränkt verwendet werden. Es bestehen keine Limits bezüglich der Nutzungsgebühren oder Kapazität.</li>

  <li><b>Fixed</b> – Die Netzwerkverbindung kann bis zu einem bestimmten Limit uneingeschränkt verwendet werden.</li>

  <li><b>Variable</b> – Die Netzwerkverbindung ist getaktet (pro Byte).</li>

  <li><b>Unknown</b> – Für diese Netzwerkverbindung sind keine Kosteninformationen verfügbar.</li>
</ul>

<p>Mehrere zusätzliche boolesche Eigenschaften für die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.aspx" target="_blank">ConnectionCost</a>-Klasse stellen noch mehr Informationen bereit. </p>

<ul>
  <li><a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.roaming.aspx" target="_blank">Roaming</a> – Es wird eine Verbindung zu einem anderen Netzwerk als des Heimanbieters hergestellt.</li>

  <li><a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.approachingdatalimit.aspx" target="_blank">ApproachingDataLimit</a> – Die Verbindung nähert sich dem Nutzungslimit des Datentarifs.</li>

  <li><a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.overdatalimit.aspx" target="_blank">OverDataLimit</a> – Die Verbindung hat das Nutzungslimit des Datentarifs überschritten.</li>
</ul>

<p>Gestalten Sie Ihre App so, dass sie angemessen auf die von diesen Eigenschaften angegebenen Informationen reagiert. Wenn eine Verbindung den Status <b>Roaming</b> aufweist, können sich aus der Netzwerknutzung hohe Datenkosten ergeben. Wenn die Eigenschaft <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.networkcosttype.aspx" target="_blank">NetworkCostType</a> auf den Wert <b>Variable</b> festgelegt ist, handelt es sich um ein getaktetes Netzwerk, in dem der Benutzer für die Menge der im Netzwerk gesendeten oder empfangenen Daten bezahlt. Liegt der Wert für <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.networkcosttype.aspx" target="_blank">NetworkCostType</a> bei <b>Fixed</b>, besteht Handlungsbedarf, wenn der Benutzer das Datenlimit überschritten hat oder sich diesem nähert. </p>

<p>Mithilfe dieser Informationen kann die App anhand der Richtlinien feststellen, wie Netzwerkressourcen am besten verwendet werden.</p>

<div align="center">
  <p align="left"></p>

  <p align="left"></p>

  <p align="left"></p>

  <p align="left"></p>

  <p align="left"></p>

  <p align="left"></p>

  <p align="left"></p>

  <p align="left"></p>

  <p align="left"></p>

  <p align="left"></p>

  <p align="left"></p>

  <p align="left"></p>

  <p align="left"></p>

  <p align="left"></p>

  <p align="left"></p>

  <table class="b8table" cellspacing="0" cellpadding="3" align="center" border="0"><tbody>
      <tr>
        <td valign="top" width="97">
          <p><b>Verhalten</b></p>
        </td>

        <td valign="top" width="150">
          <p><b>Verbindungskosten</b></p>
        </td>

        <td valign="top" width="168">
          <p><b>App-Richtlinien</b></p>
        </td>

        <td valign="top" width="175">
          <p><b>Beispiele</b></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="97">
          <p align="left">Normal</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="150">
          <p align="left"></p>

          <p align="left">Der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.networkcosttype.aspx" target="_blank">NetworkCostType</a> ist <b>Unrestricted</b> oder <b>Unknown</b>, und <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.aspx" target="_blank">ConnectionCost</a> weist nicht den Wert <b>Roaming</b> auf.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="168">
          <p align="left"></p>

          <p align="left">Die App wendet keine Einschränkungen an. Sie behandelt die Verbindung als <b>Unlimited</b> in Bezug auf die Kosten und als uneingeschränkt in Bezug auf Nutzungsgebühren und Kapazitätslimits.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="175">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left">Die Media Player-App kann einen ganze HD-Film wiedergeben.</div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Die App kann eine große Datei ohne Einschränkungen oder Eingabeaufforderungen herunterladen.</div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="97">
          <p align="left"></p>

          <p align="left">Konservativ</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="150">
          <p align="left"></p>

          <p align="left">Der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.networkcosttype.aspx" target="_blank">NetworkCostType</a> ist <b>Fixed</b> oder <b>Variable</b>, und <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.aspx" target="_blank">ConnectionCost</a> ist nicht auf <b>Roaming</b> oder <b>OverDataLimit</b> festgelegt.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="168">
          <p align="left"></p>

          <p align="left">Die App nimmt Einschränkungen vor, um die Netzwerknutzung für Vorgänge in getakteten Netzwerken zu optimieren.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="175">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left">Die Media Player-App kann Filme in niedrigeren Auflösungen wiedergeben.</div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Die App kann Downloads verzögern, die nicht unbedingt erforderlich sind.</div>
            </li>

            <p align="left"></p>
          </ul>

          <p align="left"></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="97">
          <p align="left"></p>

          <p align="left">Opt-In</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="150">
          <p align="left"></p>

          <p align="left">Die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.aspx" target="_blank">ConnectionCost</a> weist den Wert <b>Roaming</b> oder <b>OverDataLimit</b> auf.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="168">
          <p align="left"></p>

          <p align="left">Die App reagiert auf Ausnahmefälle, in denen die Kosten für den Netzwerkzugriff deutlich über denen des Tarifs liegen.</p>

          <p align="left"></p>
        </td>

        <td valign="top" width="175">
          <p align="left"></p>

          <ul>
            <p align="left"></p>

            <li>
              <div align="left">Die App fordert den Benutzer zum Netzwerkzugriff auf.</div>
            </li>

            <p align="left"></p>

            <li>
              <div align="left">Die App hält die gesamte Netzwerkdatennutzung im Hintergrund an.<i></i></div>
            </li>
          </ul>
        </td>
      </tr>
    </tbody></table>
</div>

<p>In diesem Codebeispiel werden die Verbindungskosten überprüft. Anschließend werden Vorschläge für ein geeignetes Verhalten ausgegeben. </p>

<p><strong>JavaScript</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> CostGuidance = { Normal: 0, Conservative: 1, OptIn: 2 };<br /><span style="color: rgb(0, 128, 0);">// GetCostGuidance returns an object with a Cost (with value of CostGuidance), </span><br /><span style="color: rgb(0, 128, 0);">// CostName (a string) and Reason, which says why the cost is what it is.</span><br /><span style="color: rgb(0, 0, 255);">function</span> GetCostGuidance() <br />{<br />    <span style="color: rgb(0, 0, 255);">var</span> connectionCost = Windows.Networking.Connectivity.NetworkInformation.getInternetConnectionProfile().getConnectionCost();<br />    <span style="color: rgb(0, 0, 255);">var</span> networkCostConstants = Windows.Networking.Connectivity.NetworkCostType;<br />    <span style="color: rgb(0, 0, 255);">var</span> Retval = <span style="color: rgb(0, 0, 255);">new</span> Object();<br />    <span style="color: rgb(0, 0, 255);">if</span> (connectionCost.roaming || connectionCost.overDataLimit)<br />    {<br />        Retval.Cost = CostGuidance.OptIn;<br />        Retval.CostName = <span style="color: rgb(0, 96, 128);">&quot;OptIn&quot;</span>;<br />        Retval.Reason = connectionCost.roaming<br />            ? <span style="color: rgb(0, 96, 128);">&quot;Connection is roaming; using the connection may result in additional charge.&quot;</span><br />            : <span style="color: rgb(0, 96, 128);">&quot;Connection has exceeded the usage cap limit.&quot;</span>;<br />    }<br />    <span style="color: rgb(0, 0, 255);">else</span> <span style="color: rgb(0, 0, 255);">if</span> (connectionCost.networkCostType == networkCostConstants.<span style="color: rgb(0, 0, 255);">fixed</span><br />        || connectionCost.networkCostType == networkCostConstants.variable)<br />    {<br />        Retval.Cost = CostGuidance.conservative;<br />        Retval.CostName = <span style="color: rgb(0, 96, 128);">&quot;Conservative&quot;</span>;<br />        Retval.Reason = connectionCost.networkCostType == NetworkCostType.<span style="color: rgb(0, 0, 255);">fixed</span><br />            ? <span style="color: rgb(0, 96, 128);">&quot;Connection has limited allowed usage.&quot;</span><br />            : <span style="color: rgb(0, 96, 128);">&quot;Connection is charged based on usage. &quot;</span>;<br />    }<br />    <span style="color: rgb(0, 0, 255);">else</span><br />    {<br />        Retval.Cost = CostGuidance.Normal;<br />        Retval.CostName = <span style="color: rgb(0, 96, 128);">&quot;Normal&quot;</span>;<br />        Retval.Reason = connectionCost.networkCostType == networkCostConstants.unknown<br />            ? <span style="color: rgb(0, 96, 128);">&quot;Connection is unknown.&quot;</span><br />            : <span style="color: rgb(0, 96, 128);">&quot;Connection cost is unrestricted.&quot;</span>;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">return</span> Retval;<br />}<br /></pre>
  </div>
</blockquote>

<p><strong>C#</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">enum</span> NetworkCost { Normal, Conservative, OptIn };<br /><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">class</span> CostGuidance<br />{<br />    <span style="color: rgb(0, 0, 255);">public</span> CostGuidance()<br />    {<br />        var connectionCost = NetworkInformation.GetInternetConnectionProfile().GetConnectionCost();<br />        Init(connectionCost);<br />    }<br />    <span style="color: rgb(0, 0, 255);">public</span> NetworkCost Cost { get; <span style="color: rgb(0, 0, 255);">private</span> set; }<br />    <span style="color: rgb(0, 0, 255);">public</span> String Reason { get; <span style="color: rgb(0, 0, 255);">private</span> set; }<br /><br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">void</span> Init(ConnectionCost connectionCost)<br />    {<br />        <span style="color: rgb(0, 0, 255);">if</span> (connectionCost == <span style="color: rgb(0, 0, 255);">null</span>) <span style="color: rgb(0, 0, 255);">return</span>;<br />        <span style="color: rgb(0, 0, 255);">if</span> (connectionCost.Roaming || connectionCost.OverDataLimit)<br />        {<br />            Cost = NetworkCost.OptIn;<br />            Reason = connectionCost.Roaming<br />                ? <span style="color: rgb(0, 96, 128);">&quot;Connection is roaming; using the connection may result in additional charge.&quot;</span><br />                : <span style="color: rgb(0, 96, 128);">&quot;Connection has exceeded the usage cap limit.&quot;</span>;<br />        }<br />        <span style="color: rgb(0, 0, 255);">else</span> <span style="color: rgb(0, 0, 255);">if</span> (connectionCost.NetworkCostType == NetworkCostType.Fixed<br />            || connectionCost.NetworkCostType == NetworkCostType.Variable)<br />        {<br />            Cost = NetworkCost.Conservative;<br />            Reason = connectionCost.NetworkCostType == NetworkCostType.Fixed<br />                ? <span style="color: rgb(0, 96, 128);">&quot;Connection has limited allowed usage.&quot;</span><br />                : <span style="color: rgb(0, 96, 128);">&quot;Connection is charged based on usage. &quot;</span>;<br />        }<br />        <span style="color: rgb(0, 0, 255);">else</span><br />        {<br />            Cost = NetworkCost.Normal;<br />            Reason = connectionCost.NetworkCostType == NetworkCostType.Unknown<br />                ? <span style="color: rgb(0, 96, 128);">&quot;Connection is unknown.&quot;</span><br />                : <span style="color: rgb(0, 96, 128);">&quot;Connection cost is unrestricted.&quot;</span>;<br />        }<br />    }<br />}<br /></pre>

    <br /></div>
</blockquote>

<p>In diesem <a href="http://code.msdn.microsoft.com/windowsapps/Network-Information-Sample-63aaa201" target="_blank">network information sample</a> erfahren Sie mehr über das Anpassen des App-Verhaltens an getaktete Netzwerke.</p>

<p>Zudem können Benutzer den Task-Manager ausführen, um anzuzeigen, in welchem Umfang Netzwerkdaten von den einzelnen App genutzt werden. Dieser Screenshot zeigt ein Beispiel.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/5618.task-manager_6C99F920.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/5618.task_2D00_manager_5F00_6C99F920.png"><img title="Anzeige der Nutzung von CPU- und Netzwerkressourcen durch Apps aus der Registerkarte &quot;App-Verlauf&quot; im Task-Manager" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Anzeige der Nutzung von CPU- und Netzwerkressourcen durch Apps aus der Registerkarte &quot;App-Verlauf&quot; im Task-Manager" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/3554.task-manager_thumb_4C7EEC63.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/3554.task_2D00_manager_5F00_thumb_5F00_4C7EEC63.png" width="600" height="545" /></a></p>

<p align="center"><em>Anzeige der Nutzung von CPU- und Netzwerkressourcen durch Apps aus der Registerkarte "App-Verlauf" im Task-Manager</em></p>

<h2>Reagieren auf Änderungen des Netzwerkstatus</h2>

<p>Für mobile Geräte ändert sich gelegentlich das Netzwerk. Beispielsweise können mobile 3G- oder 4G-Breitbandnetzwerke im Haus oder der Garage von Benutzern außer Reichweite sein, während das WLAN weiterhin verfügbar ist. Entsprechend kann beim Verlassen des Hauses die WLAN-Verbindung verloren gehen. Zudem kann es vorkommen, dass gar kein Netzwerk verfügbar ist. Angesichts der Verbreitung von WLAN- und mobilen Breitbandnetzwerken treten diese Netzwerkänderungen häufig auf. </p>

<p>In diesem Fall gibt ein <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.networkinformation.networkstatuschanged" target="_blank">NetworkStatusChanged</a>-Ereignis an, dass sich möglicherweise die <i>verfügbaren Kosten</i>- oder <i>Verbindungsoptionen</i> geändert haben. Um auf derartige Änderungen des Netzwerkstatus zu reagieren und eine unterbrechungsfreie Verbindung zu gewährleisten, sollten Sie bei Ihren verbundenen Apps folgende szenariospezifische Richtlinien berücksichtigen.</p>

<h3>Verbindungsverlust aufgrund eines Fehlers</h3>

<p>Verbindungen können in der Regel wiederhergestellt werden, indem einfach der Netzwerkvorgang erneut ausgeführt wird. Schlägt dieser Versuch fehl, warten Sie auf ein <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.networkinformation.networkstatuschanged" target="_blank">NetworkStatusChanged</a>-Ereignis. Wir empfehlen die Verwendung steigender Backoff-Intervalle zwischen den einzelnen Versuchen. Die App sollte mit einem Wert von 50 Millisekunden beginnen und das Intervall exponentiell steigern, wenn die Verbindung nicht hergestellt werden kann.</p>

<h3>Verlust der Netzwerkverbindung</h3>

<p>Informieren Sie den Benutzer darüber, dass die Verbindung getrennt wurde, und warten Sie nach einer entsprechenden Registrierung auf ein <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.networkinformation.networkstatuschanged" target="_blank">NetworkStatusChanged</a>-Ereignis.</p>

<h3>Verfügbarkeit eines neuen Netzwerks</h3>

<p>Es kann vorkommen, dass ein Gerät mit mehreren Netzwerken verbunden ist. Angenommen, ein Benutzer chattet mit der Nachrichten-App von Windows 8 über eine mobile Breitbandverbindung mit Freunden, während er zu Hause ankommt und dort eine weitere Verbindung zum uneingeschränkten Netzwerk herstellt. Gemäß der Standardrichtlinie von Windows 8 ist ein uneingeschränktes Netzwerk einem getakteten Netzwerk vorzuziehen, und ein schnelleres Netzwerk einem langsameren. Allerdings wechseln Apps, die bereits über eine Verbindung verfügen, nicht automatisch zu einem neuen Netzwerk. Die App muss einbezogen werden, da nur so die richtige Entscheidung bezüglich eines Netzwerkwechsels getroffen werden kann. </p>

<p>Wenn z. B. ein Videostream kurz vor dem Abschluss steht, ist es wenig sinnvoll, in das neue Netzwerk zu wechseln. Sollte das aktuelle Netzwerk jedoch Pakete verlieren, zu langsam sein oder zusätzliche Zeit zum Beenden des Streams benötigen, bietet sich ein Wechsel in das neue Netzwerk an.</p>

<p>Wenn Sie den Wechsel des Netzwerks für Ihr App-Szenario in Erwägung ziehen, beachten Sie diese Richtlinien, falls ein neues Netzwerk erkannt wird:</p>

<ol>
  <li>Überprüfen Sie die Kosten des vorhandenen und des neuen Netzwerks. Wenn Sie den Wechsel in das neue Netzwerk für sinnvoll halten, versuchen Sie, eine neue Netzwerkverbindung herzustellen, und wiederholen Sie den Netzwerkvorgang gemäß der oben genannten Richtlinien. Windows wählt uneingeschränkte Netzwerke automatisch vor getakteten Netzwerken aus, und ein schnelleres Netzwerk wird einem langsameren bevorzugt (sofern vorhanden).</li>

  <li>Nachdem die neue Netzwerkverbindung erfolgreich hergestellt wurde, verwenden Sie diese für Ihre App, und brechen Sie den ursprünglichen Vorgang im vorherigen Netzwerks ab, falls bereits eine Verbindung besteht.</li>
</ol>

<h3>Änderung der Netzwerkkosten</h3>

<p>Die Netzwerkkosten können sich ändern, wenn der <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.networkcosttype.aspx" target="_blank">NetworkCostType</a> den Wert <b>Fixed</b> aufweist und sich die Datennutzung dem Limit nähert oder dieses übersteigt. Zudem können sich die Netzwerkkosten ändern, wenn der Wert für <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.networkcosttype.aspx" target="_blank">NetworkCostType</a> auf <b>Variable</b> festgelegt ist oder der Wert für <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.connectioncost.roaming.aspx" target="_blank">Roaming</a> zu „true“ wechselt. Passen Sie in diesen Fällen das App-Verhalten anhand der Richtlinien aus dem vorherigen Tipp an.</p>

<p>In den folgenden Codebeispielen wird das <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.networkinformation.networkstatuschanged" target="_blank">NetworkStatusChanged</a>-Ereignis verwendet, um im Fall verschiedener Änderungen des Netzwerkstatus eine nahtlose Ausführung der App zu gewährleisten. In beiden Beispielen kommt die globale boolesche Variable <i>registeredNetworkStatusNotification</i> zum Einsatz, die zunächst auf <b>false</b> festgelegt ist. </p>

<p><strong>JavaScript</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">// Register for NetworkStatusChanged notifications, and display new </span><br /><span style="color: rgb(0, 128, 0);">// Internet ConnectionProfile info upon network status change.</span><br /><span style="color: rgb(0, 0, 255);">function</span> registerForNetworkStatusChange() {<br />    <span style="color: rgb(0, 0, 255);">try</span> {<br /><br />        <span style="color: rgb(0, 128, 0);">// Register for network status change notifications.</span><br />        <span style="color: rgb(0, 0, 255);">if</span> (!registeredNetworkStatusNotification) {<br />            <span style="color: rgb(0, 0, 255);">var</span> networkInfo.addEventListener(<span style="color: rgb(0, 96, 128);">&quot;networkstatuschanged&quot;</span>, onNetworkStatusChange);<br />            registeredNetworkStatusNotification = <span style="color: rgb(0, 0, 255);">true</span>;<br />        }<br />    }<br />    <span style="color: rgb(0, 0, 255);">catch</span> (e) {<br />        print(<span style="color: rgb(0, 96, 128);">&quot;An unexpected exception occurred: &quot;</span> + e.name + <span style="color: rgb(0, 96, 128);">&quot;: &quot;</span> + e.message);<br />    }<br />}<br /><br /><span style="color: rgb(0, 128, 0);">// Event handler for NetworkStatusChanged event</span><br /><span style="color: rgb(0, 0, 255);">function</span> onNetworkStatusChange(sender) {<br />    <span style="color: rgb(0, 0, 255);">try</span> {<br />        <span style="color: rgb(0, 128, 0);">// Get the ConnectionProfile that is currently used to connect </span><br />        <span style="color: rgb(0, 128, 0);">// to the Internet.</span><br />        <span style="color: rgb(0, 0, 255);">var</span> internetProfile = networkInfo.getInternetConnectionProfile();<br />        <span style="color: rgb(0, 0, 255);">if</span> (internetProfile === <span style="color: rgb(0, 0, 255);">null</span>) {<br />            print(<span style="color: rgb(0, 96, 128);">&quot;Not connected to Internet\n\r&quot;</span>);<br />        }<br />        <span style="color: rgb(0, 0, 255);">else</span> {<br />            internetProfileInfo += getConnectionProfileInfo(internetProfile) + <span style="color: rgb(0, 96, 128);">&quot;\n\r&quot;</span>;<br />            print(internetProfileInfo);<br />        }<br />        internetProfileInfo = <span style="color: rgb(0, 96, 128);">&quot;&quot;</span>;<br />    }<br />    <span style="color: rgb(0, 0, 255);">catch</span> (e) {<br />        print(<span style="color: rgb(0, 96, 128);">&quot;An unexpected exception occurred: &quot;</span> + e.name + <span style="color: rgb(0, 96, 128);">&quot;: &quot;</span> + e.message);<br />    }<br />}<br /></pre>

    <br /></div>
</blockquote>

<p><strong>C#</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">// Register for NetworkStatusChanged notifications, and display new </span><br /><span style="color: rgb(0, 128, 0);">// Internet ConnectionProfile info upon network status change.</span><br /><span style="color: rgb(0, 0, 255);">void</span> NetworkStatusChange()<br />{<br />    <span style="color: rgb(0, 128, 0);">// Register for network status change notifications.</span><br />    <span style="color: rgb(0, 0, 255);">try</span><br />    {<br />        var networkStatusCallback = <span style="color: rgb(0, 0, 255);">new</span> NetworkStatusChangedEventHandler(OnNetworkStatusChange);<br />        <span style="color: rgb(0, 0, 255);">if</span> (!registeredNetworkStatusNotification)<br />        {<br />            NetworkInformation.NetworkStatusChanged += networkStatusCallback;<br />            registeredNetworkStatusNotification = <span style="color: rgb(0, 0, 255);">true</span>;<br />        }<br />    }<br />    <span style="color: rgb(0, 0, 255);">catch</span> (Exception ex)<br />    {<br />        rootPage.NotifyUser(<span style="color: rgb(0, 96, 128);">&quot;Unexpected exception occurred: &quot;</span> + ex.ToString(), NotifyType.ErrorMessage);<br />    }<br />}<br /><br /><span style="color: rgb(0, 128, 0);">// Event handler for NetworkStatusChanged event</span><br />async <span style="color: rgb(0, 0, 255);">void</span> OnNetworkStatusChange(<span style="color: rgb(0, 0, 255);">object</span> sender)<br />{<br />    <span style="color: rgb(0, 0, 255);">try</span><br />    {<br />        <span style="color: rgb(0, 128, 0);">// Get the ConnectionProfile that is currently used to connect </span><br />        <span style="color: rgb(0, 128, 0);">// to the Internet                </span><br />        ConnectionProfile InternetConnectionProfile = NetworkInformation.GetInternetConnectionProfile();<br /><br />        <span style="color: rgb(0, 0, 255);">if</span> (InternetConnectionProfile == <span style="color: rgb(0, 0, 255);">null</span>)<br />        {<br />            await _cd.RunAsync(CoreDispatcherPriority.Normal, () =&gt;<br />            {<br />                rootPage.NotifyUser(<span style="color: rgb(0, 96, 128);">&quot;Not connected to Internet\n&quot;</span>, NotifyType.StatusMessage);<br />            });<br />        }<br />        <span style="color: rgb(0, 0, 255);">else</span><br />        {<br />            connectionProfileInfo = GetConnectionProfile(InternetConnectionProfile);<br />            await _cd.RunAsync(CoreDispatcherPriority.Normal, () =&gt;<br />            {<br />                rootPage.NotifyUser(connectionProfileInfo, NotifyType.StatusMessage);<br />            });<br />        }<br />        internetProfileInfo = <span style="color: rgb(0, 96, 128);">&quot;&quot;</span>;<br />    }<br />    <span style="color: rgb(0, 0, 255);">catch</span> (Exception ex)<br />    {<br />        rootPage.NotifyUser(<span style="color: rgb(0, 96, 128);">&quot;Unexpected exception occurred: &quot;</span> + ex.ToString(), NotifyType.ErrorMessage);<br />    }<br />}<br /></pre>
  </div>
</blockquote>

<p>Weitere Informationen zum <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.networking.connectivity.networkinformation.networkstatuschanged" target="_blank">NetworkStatusChanged</a>-Ereignis finden Sie unter <a href="http://msdn.microsoft.com/de-de/library/windows/apps/hh700376.aspx" target="_blank">Schnellstart: Verwalten von Verbindungsereignissen und Änderungen der Verfügbarkeit</a> und auf der Seite <a href="http://code.msdn.microsoft.com/windowsapps/Network-Information-Sample-63aaa201" target="_blank">Network information sample</a>.</p>

<h2>Zwischenspeichern von Inhalten für eine flüssige Darstellung</h2>

<p>Durch das Zwischenspeichern von Inhalten auf einen Datenträger können Sie für eine schnelle und flüssige Ausführung Ihrer App sorgen. Eine RSS-Reader-App kann beispielsweise Feeds unmittelbar anzeigen, die in einer vorherigen Sitzung auf einem Datenträger zwischengespeichert wurden. Sobald die neue Feeds verfügbar sind, wird der Inhalt der App aktualisiert. Durch das Zwischenspeichern wird sichergestellt, dass Benutzer bereits beim Start Inhalte nutzen können, während neue Inhalte von der App abgerufen werden.</p>

<p>Windows 8 stellt die Klasse <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.storage.applicationdata.aspx" target="_blank">ApplicationData</a><b></b> im Namespace <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.storage.aspx" target="_blank">Windows.Storage</a><b></b> bereit. Diese Klasse ermöglicht den Zugriff auf den App-Datenspeicher. Der Datenspeicher besteht aus Dateien und Einstellungen, die sich entweder lokal auf dem Gerät befinden, zwischen mehreren Geräten geroamt werden oder temporär sind.</p>

<p>Dateien eignen sich optimal zum Speichern von großen Datensätzen, Datenbanken oder Daten mit gleichem Format. Die Dateien können sich im Roaming-, Lokal- oder Temporär-Ordner befinden. Dies bedeutet Folgendes:</p>

<ul>
  <li>Roaming-Dateien werden auf mehreren Computern und Geräten synchronisiert, auf denen die Benutzer mit verbundenen Konten angemeldet sind. Das Roaming der Dateien erfolgt nicht unmittelbar, da das System zunächst mehrere Faktoren überprüft, um den Zeitpunkt der Datenübertragung festzulegen. Halten Sie die Nutzung von Roamingdaten unterhalb des Kontingents (verfügbar über die <a href="http://msdn.microsoft.com/de-de/library/windows/apps/windows.storage.applicationdata.roamingstoragequota.aspx" target="_blank">RoamingStorageQuota</a><b></b>-Eigenschaft). Bei einer Überschreitung des Kontingents wird das Datenroaming angehalten. Das Roaming von Dateien, in die gerade von der App geschrieben wird, ist nicht möglich. Achten Sie also darauf, die Dateiobjekte Ihrer App zu schließen, wenn diese nicht benötigt werden. </li>

  <li>Lokale Dateien werden nicht auf mehreren Computern synchronisiert. Sie verbleiben auf dem Computer, auf dem sie erstellt wurden. </li>

  <li>Temporäre Dateien werden entfernt, wenn sie nicht verwendet werden. Um festzustellen, ob eine temporäre Datei entfernt werden soll, überprüft das System Faktoren wie die verfügbare Datenträgerkapazität und das Alter einer Datei.</li>
</ul>

<p>In den folgenden Codebeispielen werden Inhalte auf dem Datenträger zwischengespeichert. Durch das Zwischenspeichern der Serverantwort kann die App Inhalte unmittelbar nach dem Beenden und Neustart anzeigen. Der Einfachheit halber wird in diesen Beispielen nicht gezeigt, wie Einstellungen in den App-Datenspeicher geschrieben und wie auf Roaming-Ereignisse geantwortet wird. Informationen hierzu finden Sie unter <a href="http://code.msdn.microsoft.com/windowsapps/ApplicationData-sample-fb043eb2" target="_blank">Application data sample</a>.</p>

<p><strong>JavaScript</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> roamingFolder = Windows.Storage.ApplicationData.current.roamingFolder;<br /><span style="color: rgb(0, 0, 255);">var</span> filename = <span style="color: rgb(0, 96, 128);">&quot;serverResponse.txt&quot;</span>;<br /><br /><span style="color: rgb(0, 0, 255);">function</span> cacheResponse(strResponse) {<br />    roamingFolder.createFileAsync(filename, Windows.Storage.CreationCollisionOption.replaceExisting)<br />        .done(<span style="color: rgb(0, 0, 255);">function</span> (file) {<br />            <span style="color: rgb(0, 0, 255);">return</span> Windows.Storage.FileIO.writeTextAsync(file, strResponse);<br />        });<br />}<br /><br /><span style="color: rgb(0, 0, 255);">function</span> getCachedResponse() {<br />    roamingFolder.getFileAsync(filename)<br />        .then(<span style="color: rgb(0, 0, 255);">function</span> (file) {<br />            <span style="color: rgb(0, 0, 255);">return</span> Windows.Storage.FileIO.readTextAsync(file);<br />        }).done(<span style="color: rgb(0, 0, 255);">function</span> (response) {<br />            print(response);<br />        }, <span style="color: rgb(0, 0, 255);">function</span> () {<br />            <span style="color: rgb(0, 128, 0);">// getFileAsync or readTextAsync failed. </span><br />            <span style="color: rgb(0, 128, 0);">// No cached response.</span><br />        });<br />}<br /></pre>

    <br /></div>
</blockquote>

<p><strong>C#</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">MainPage rootPage = MainPage.Current;<br />StorageFolder roamingFolder = <span style="color: rgb(0, 0, 255);">null</span>;<br /><span style="color: rgb(0, 0, 255);">const</span> <span style="color: rgb(0, 0, 255);">string</span> filename = <span style="color: rgb(0, 96, 128);">&quot;serverResponse.txt&quot;</span>;<br /><br />async <span style="color: rgb(0, 0, 255);">void</span> cacheResponse(<span style="color: rgb(0, 0, 255);">string</span> strResponse)<br />{<br />    StorageFile file = await roamingFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);<br />    await FileIO.WriteTextAsync(file, strResponse);<br />}<br /><br />async <span style="color: rgb(0, 0, 255);">void</span> getCachedResponse()<br />{<br />    <span style="color: rgb(0, 0, 255);">try</span><br />    {<br />        StorageFile file = await roamingFolder.GetFileAsync(filename);<br />        <span style="color: rgb(0, 0, 255);">string</span> response = await FileIO.ReadTextAsync(file);<br />    }<br />    <span style="color: rgb(0, 0, 255);">catch</span> (Exception)<br />    {<br />        <span style="color: rgb(0, 128, 0);">// getFileAsync or readTextAsync failed.</span><br />        <span style="color: rgb(0, 128, 0);">// No cached response.</span><br />    }<br />}<br /></pre>

    <br /></div>
</blockquote>

<p>Weitere Informationen zum App-Datenspeicher finden Sie im Beitrag <a href="http://blogs.msdn.com/b/windowsappdev_de/archive/2012/07/26/roaming-von-app-daten.aspx" target="_blank">Roaming von App-Daten</a> und im <a href="http://code.msdn.microsoft.com/windowsapps/ApplicationData-sample-fb043eb2" target="_blank">Application data sample</a>.</p>

<h2>Zusammenfassung</h2>

<p>Verwenden Sie die Richtlinien dieses Beitrags beim Entwerfen Ihrer Windows Store-Apps. Auf diese Weise können Sie faszinierende, benutzerfreundliche und unterbrechungsfreie Apps bereitstellen. Diese Tipps sollen Ihren Entwicklungsprozess vereinfachen und gleichzeitig die Flexibilität und das Vertrauen der Benutzer in Ihre Apps stärken.</p>

<p>– Suhail Khalid, Programmmanager II, Windows</p>

<p>Unter Mitarbeit von: Steven Baker und Peter Smith</p>

<!-- Title: “Erstellen verbundener Windows Store-Apps” Tags: “Windows Store-Apps, HttpClient, verbundene Apps, XMLHTTPRequest, IXHR2, XML HTTP Request 2, WinJS.xhr” -->
</div>]]></content:encoded>
    </item>
    <item>
      <title>Registrieren Sie sich jetzt für die //build/ 2013!</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_de/registrieren-sie-sich-jetzt-fr-die-build-2013</link>
      <pubDate>Fri, 05 Apr 2013 10:31:13 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_de/2013/04/05/registrieren-sie-sich-jetzt-fr-die-build-2013/</guid>
      <description><![CDATA[Letzte Woche hat Steve Guggenheimer die //build/ 2013 angekündigt. Die Konferenz findet vom 26. bis...]]></description>
      <content:encoded><![CDATA[<div class="PostContent"><p>Letzte Woche hat Steve Guggenheimer die //build/ 2013 <a href="http://blogs.technet.com/b/microsoft_blog/archive/2013/03/26/announcing-build-2013.aspx" target="_blank">angekündigt</a>. Die Konferenz findet vom 26. bis 28. Juni 2013 im Moscone Center in San Francisco statt. Die //build/ ist die Gelegenheit, mehr über die Entwicklung von Windows Store-Apps zu erfahren. Auf der Konferenz finden zahlreiche Präsentationen, Vorführungen und Info-Veranstaltungen statt. Viele Mitglieder unseres Entwicklerteams kommen für diese Vorführungen nach San Francisco und beantworten Ihre Fragen. Es gibt keinen besseren Ort, um das Neueste und Wichtigste über die Entwicklung von Windows Store-Apps in Erfahrung zu bringen. </p>  <p>Die Registrierung beginnt am Dienstag, den 2. April<sup></sup>. Alle Informationen zur Konferenz finden Sie unter <a href="http://www.buildwindows.com" target="_blank">www.buildwindows.com</a>, wo Sie sich auch registrieren können. </p>  <p>Wir freuen uns auf Ihren Besuch!</p> <!-- Title: “Registrieren Sie sich jetzt für die //build/ 2013!” Tags: “build” --></div>]]></content:encoded>
    </item>
  </channel>
</rss>