Programowanie aplikacji dla Windows 8 (WinRT)

Post on 28-Nov-2014

2065 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

Podstawy tworzenia aplikacji dla Windows 8 (Modern UI) w XAML, C# i komponentach WinRT.

Transcript

Programowanie Windows 8

Bartłomiej ZassTechnical EvangelistMicrosoft Polska

Na czym się skupimy?

Trochę o pisaniu w HTML 5 XAML i Windows 8 ASP.NET (czasem trochę) - C# (jeśli zdążymy) - Windows Phone

MS-DOS Executive, 1985 r.

Niepełny OS – tylko warstwa na MS-DOS

Windows 95

Win32 – uzupełnianie granicy między 16-biti 32-bit

Hello, world w C++

#include<iostream.h>int main(){ cout << "Hello World" << endl; return 0;}

Hello, World w Win32 (MFC)#include <afxwin.h>class HelloApplication : public CWinApp{public:virtual BOOL InitInstance();};HelloApplication HelloApp;class HelloWindow : public CFrameWnd{CButton* m_pHelloButton;public:HelloWindow();};BOOL HelloApplication::InitInstance(){m_pMainWnd = new HelloWindow();m_pMainWnd->ShowWindow(m_nCmdShow);m_pMainWnd->UpdateWindow();return TRUE;}HelloWindow::HelloWindow(){Create(NULL,"Hello World!",WS_OVERLAPPEDWINDOW|WS_HSCROLL,CRect(0,0,140,80));m_pHelloButton = new CButton();m_pHelloButton->Create("Hello World!",WS_CHILD|WS_VISIBLE,CRect(20,20,120,40),

COM – od 1993

Model komponentowy Wygodniej i łatwiej w VB

Komunikacja między procesami C -> brak obiektów C++ -> współdzielenie kodu między programistami COM -> komunikacja między procesami SOA -> komunikacja między usługami, systemami

.NET Framework

Prace od 1990 r. Next Generation Windows Services (NGWS) Pierwsza beta – 2000 r. MSIL, CLR, CTS, Garbage Collector, … Windows Forms

GDI/GDI+ - bezpośredni dostęp do hardware’u 2006 r. - .NET Framework 3.0

WPF – Windows Presentation Foundation XAML

NUI

iPad – 2010 r. 15 milionów urządzeń w pierszym roku

Natural User Interface (NUI) Historia maszyny do pisania (1870 r.) – Christopher Sholes Mysz – 1960r., Xerox

Kiedy jedno kliknięcie, kiedy dwa, … iPhone (2007 r.), Nintendo Wii, … Kinect – 2009 r. Obecnie – konsumeryzacja IT (Gartner), BYOD

Windows Store Application

WinRT

W przeciwieństwie do Win32 – object oriented Wiele języków COM, projekcje DirectX zamiast GDI Application Container i zamrażanie (w desktop przesłonięte działa) Bezpośrednie wywołania do kernela lub brokered call

WinRT

WinRT – c.d.

Oparte o COM Zgodne z Application Binary Interface (ABI) – interface między

systemem i komponentami Iinspectable, Iunknown

Reference counting Javascript – własny garbage collector .NET – COM Interop, komunikacja przy pomocy Runtime Callable

Wrapper (RCW)

Wiele typów urządzeń

DemoWindows 8

Modern UI

Windows Store

Duży zasięg

Integracja z przeglądarką

Transparentny proces

Różne modele biznesowe

Wysoki zysk dla programistów

Windows Store

Integracja z IE

Get the app / switch to the app <meta name="msApplication-ID"content="microsoft.build.App"/> <meta name="msApplication-PackageFamilyName"content="microsoft.build_8wekyb3d8bbwe"/>

Pinned sites Badges Polling

<META name="msapplication-badge" content="frequency=30; polling-uri=http://mysite.com/id45453245/polling.xml"/>

Ręczne odświeżenie z JS window.external.msSiteModeRefreshBadge();

<badge value = "1-99" | "none" | "activity" | "alert" | "available" | "away" | ... version? = integer />

Link previews (share) - thumbnail Direct invoke

Sideloading Warunki

Windows 8 Enterprise lub Windows Server 2012 Dołączenie do domeny

Windows 8 Pro, Windows RT lub nie dołączony do domeny Zakupiony Sideloading Product Activation Key

Visual Studio Express ;) Uwaga: teoretycznie monitorowane

Instalacja Per user – skrypty powershell Przygotowany obraz przez IT

Podpisanie aplikacji zaufanym certyfikatem Group Policy

Wymagane: Allow all trusted applications to install Dostęp do Windows Store i aktualizacji (np. zablokowanie)

Sideloading - group policy

HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Appx\AllowAllTrustedApps = 1

Sideloading – c.d.

Wgranie certyfikatu użytego do podpisania aplikacji PowerShell

import-module appx add-appxpackage \\udziałsieciowy\app1.appx Get-AppxPackage –AllUsers (listuje pakiety) Remove-AppxPackage Package1

DISM /Online /Add-ProvisionedAppxPackage /PackagePath:C:\App1.appx /SkipLicense (przygotowanie obrazu)

Windows Store

Domyślny trial + zakupy – odblokowane dla wszystkich kont GetAppReceiptAsync – per device, per user

AppReceipt ProductReceipt Signature https://go.microsoft.com/fwlink/?

LinkId=246509&cid=b809e47cd0110a4db043b3f73e83acd917fe1336

Receipt<Receipt Version="1.0" ReceiptDate="2012-08-28T22:11:33Z" CertificateId="b809e47cd0110a4db043b3f73e83acd917fe1336"

ReceiptDeviceId="4e362949-acc3-fe3a-e71b-89893eb4f528">

<AppReceipt Id="8ffa256d-eca8-712a-7cf8-cbf5522df24b" AppId="55428GreenlakeApps.CurrentAppSimulatorEventTest_z7q3q7z11crfr" PurchaseDate="2012-06-04T23:07:24Z" LicenseType="Full" />

<ProductReceipt Id="2559fa9a-9f86-0525-e655-536a6c96fac6" ProductId="Product1" PurchaseDate="2012-06-04T23:07:50Z" ExpirationDate="2012-06-07T23:07:49Z" ProductType="Durable" AppId="55428GreenlakeApps.CurrentAppSimulatorEventTest_z7q3q7z11crfr" />

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">

<SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /> <Reference URI=""> <Transforms> <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> <DigestValue>npmBq7pdtq9FkfILSsHuVyD+QWiZg6J/klBKsyWhrw8=</DigestValue> </Reference> </SignedInfo>

<SignatureValue>LKZSHmk6XjLaEHoJPFBB1GxVsFf2(...) 9PiVyBEOlZw==</SignatureValue></Signature>

Windows 8 PlatformWindows Store Apps

HTMLJavaScript

CC++

C#VB

Desktop Apps

Win32 .NET / SL

Internet Explorer

Communication & Data

Application Model

Devices & Printing

WinRT APIs

Graphics & Media

Syst

em S

ervi

ces

JavaScript(Chakra)

CC++

C#VB

XAML HTML / CSSView

Mod

el

Cont

rolle

r

Windows Core OS ServicesCore

WinRT API z bliska

Fundamentals

Application Services Threading/Timers Memory Management Authentication Cryptography Globalization

DevicesGeolocation Portable Sensors NFC

User Interface

SVG Tiles Input Accessibility Printing

HTML5/CSS XAML DirectX Controls Data Binding

Communications & Data

Memory Management XML Networking SMS

Notifications Streams

Contracts Local & Cloud Storage Web

MediaPlayback Capture PlayTo Visual Effects

WinRT

Aplikacja jest też komponentem HKEY_CURRENT_USER→Software→Classes→Activatable

Classes→Package Dane paczki, host uruchomieniowy

HKEY_CURRENT_USER→Software→Classes→Extensions→ContractId Kontrakty Tile – tak naprawdę Launch contract

Kilka przykładów użycia Javascript...

Aplikacje dla Windows 8 Gry – np. Cut The Rope, Angry Birds PhoneGap Node.js Sharepoint Rozszerzenia Office 2013 Azure Mobile Services Inne ciekawostki

http://jscriptlinq.codeplex.com/ - LINQ w JS http://bellard.org/jslinux/ - implementacja Linux w JS

DemoTypescript

HTML 5 i Windows 8

Windows 8 – akcelerowana platforma HTML

CSS 2D Transforms

CSS 3D Transforms

CSS Animations

CSS Backgrounds & Borders

CSS Color

CSS Flexbox

CSS Fonts

CSS Grid Alignment

CSS Hyphenation

CSS Image Values (Gradients)

CSS Media Queries

CSS multi-column Layout

CSS Namespaces

CSS OM Views

CSS Positioned Floats (Exclusions)

CSS Selectors

CSS Transitions

CSS Values and Units

Data URI

DOM Element Traversal

DOM HTML

DOM Level 3 Core

DOM Level 3 Events

DOM Style

DOM Traversal and Range

DOMParser and XMLSerializer

ECMAScript 5

File APIs

FormData

HTML5 Application Cache

HTML5 async

HTML5 Canvas

HTML5 Drag and drop

HTML5 Forms and Validation

HTML5 Geolocation

HTML5 History API

HTML5 Parser

HTML5 Sandbox

HTML5 Selection

HTML5 semantic elements

HTML5 video and audio

ICC Color Profiles

IndexedDB

Page Visibility

Pointer (Mouse, Pen, and Touch) Events

Selectors API Level 2

Filter Effects

SVG, standalone and in HTML

Timing callbacks

Web Messaging

Web Sockets

Web Workers

XHTML/XML

XMLHttpRequest (Level 2)

Najpopularniejsze cechy HTML5Web Sockets

Web Workers

IndexedDB

Ecmascript 5

File API & Blobs

Geolocation

Audio tag

Video tag

Touch-first

Pointer events

Zoom regions

Snap Points

Forms

Validation

Input types

Spell checking

DemoIE 10 i HTML 5, CSS 3

WinJS

Helpers for Namespaces, Constructor Definition

Promises

App Model

Navigation

Page & User controls

Data binding

Controls

Animations

Templates

Utilities

Default CSS Styles

jQuery, XHR i local context

jQuery xhr robi cross-domain check (wer. > v1.6) W kontekście lokalnym, jesteśmy w “ms-wwa://{something}” Błąd przy cross domain check

Workaround Skorzystaj z WinJS XHR Powiedz jQuery aby pominąć weryfikację

$.support.cors = true; http://api.jquery.com/jQuery.support/

Zabezpieczenia hosta

Zabezpieczenie przed wstrzykiwaniem “złego” HTMLa Skrypty, iframes, event handlers, itp.

Wywyływane gdy korzystamy z innerHTML outerHTML setAdjacentHTML

Atrybuty “data-” również nie są dozwolone Specyficzne dla WinJS są OK

Wyłączenie zabezpieczeń

toStaticHTML method DOM creation APIs WinJS.Utilities.setInnerHTMLUnsafe msWWA.execUnsafeLocalFunction

DemoWindows 8 i HTML

XAML - podstawy

XAML - podstawy

Dialekt XML Wprowdzony przez WPF, następnie Silverlight, Windows Phone,

Windows 8 Także inne technologie (składniowo) – np. WF Drzewo kontrolek Style, animacje, bindingi

Zdarzenia

W WPF różne – routed, bubbling, tunnel, … W Silverlight / Windows Phone / Windows 8 – routed

Zdarzenie wędruje w górę drzewa Można je zatrzymać – e.Handled = true

Hierarchia klas

Dependency Object (dependency property system) UIElement (klawiatra, touch, …)

FrameworkElement (layout, loaded / unloaded, binding, style)

Dependency Property

public static readonly DependencyPropertyMyNumberProperty = DependencyProperty.Register("MyNumber",typeof (int),typeof (MyDependencyObject),new PropertyMetadata(2, OnMyNumberPropertyChange));

Attached Property

Doklejanie swoich atrybutów do innych kontrolek Wszystkie inne zalety DP (style, animacje, itp.)

var row = ValueText.GetValue(Grid.RowProperty);

Opakowanie jakiejś funkcjonalności

Wspierane przez designer

Attached Property

public static readonly DependencyProperty IsShareButtonProperty =DependencyProperty.RegisterAttached("IsShareButton",typeof(Boolean),typeof(MagicButton),new PropertyMetadata(false,new PropertyChangedCallback(Changed)));

<Grid.DataContext><local:MyDependencyObject/>

</Grid.DataContext>

Bindowanie

POCO WinRT + BindbleAttribute lub ICustomPropertyProvider

<TextBlock Text="{Binding ElementName=Slider, Path=Value}"/><TextBlock Text="{Binding RelativeSource={RelativeSource Self}, Path=FontSize}"/>

Two-way binding

Dependency Properties INotifyPropertyChanged

Zdarzenie PropertyChanged Czasem łączenie z CallerMemberName Model danych nie powinien być z UI – często konieczna implementacja

Binding - inne

Konwertery Statyczne zasoby

Lokalne Globalne

Style

Globalne / lokalne Resource Dictionaries

<ResourceDictionary Source="Common/StandardStyles.xaml"/>

var firstOne = (Storyboard)MainGrid.Resources["FirstOneAnimation"];

foreach (var storyboard in MainGrid.Resources.Values.OfType<Storyboard>()){

storyboard.Begin();}

Dzień 2Programowanie Windows 8

Przypomnienie

Windows 8, Windows Store, sideloading, itp. Trochę o HTML 5, TypeScript i Windows 8 + Blend XAML - wprowadzenie

Dependency properties, attached property User control Binding, datacontext, konwertery Style, zasoby Blend + edycja template’u

Demo

Animacje

StoryBoard Wykorzystywany w wielu miejscach – np. stany i szablony kontrolek 2 typy – klasyczny i keyframe (object.property).(object.property)

<Storyboard x:Name="FirstOneAnimation"Storyboard.TargetName="FirstOne">

<DoubleAnimation Duration="0:0:5"Storyboard.TargetProperty="(Rectangle.RenderTransform).(ScaleTransform.X)"From="-300" To="300"/>

</Storyboard>

Timeline (klasa bazowa)

Storyboard – c.d.

ColorAnimation DoubleAnimation PointAnimation ObjectAnimationUsingKeyFrames

Layout Główny element – Frame Wewnątrz Frame – Page Komponowanie ekranu z różnych layoutów

Canvas Grid StackPanel VirtualizingStackPanel WrapGrid VariableSizedWrapGrid ContentControl ItemsControl ScrollViewer ViewBox

Podstawowe kontenery na dane

GridView ListView ListBox FlipView

Źródło danych - CollectionViewSource

AppBar

<Page.BottomAppBar><AppBar x:Name="AppBar" Margin="10,0,10,0">

<local:ApplicationCommand x:Name=”AppBarCommands”/>

</AppBar></Page.BottomAppBar>

Demo

Windows 8 i XAML

Wywoływanie kodu natywnego z C#[DllImport("avicap32.dll", EntryPoint="capCreateCaptureWindow")]static extern int capCreateCaptureWindow( string lpszWindowName, int dwStyle, int X, int Y, int nWidth, int nHeight, int hwndParent, int nID);

[DllImport("avicap32.dll")] static extern bool capGetDriverDescription( int wDriverIndex, [MarshalAs(UnmanagedType.LPTStr)] ref string lpszName, int cbName, [MarshalAs(UnmanagedType.LPTStr)] ref string lpszVer, int cbVer);

// więcej i więcej w podobny sposób...

...a w Windows 8

using Windows.Media.Capture;

var ui = new CameraCaptureUI();ui.PhotoSettings.CroppedAspectRatio = new Size(4, 3);

var file = await ui.CaptureFileAsync(CameraCaptureUIMode.Photo);

if (file != null) { var bitmap = new BitmapImage() ;

bitmap.SetSource(await file.OpenAsync(FileAccessMode.Read)); Photo.Source = bitmap;

}

Integralna część komponentu WinRT – metadane (tzw. WinMD) Standard zgodny z ECMA-355 (.NET) CLR wiąże definicje z implementacją automatycznie

Visual Studio 2012 „patrzy” na WinRT przez pryzmat WinMD Natywny dla danego języka sposób wywoływania komponentu

C:\Windows\System32\WinMetadata

Projekcje językowe

Projekcje językowe

WindowsRuntime

Object(or Component)

Writtenin C++, C#, VB

Windows Metadata

C++ App

Projection

CLR

C#/VB App

ProjectionHTML AppChakra

Projection

ImageEncodingProperties^ imageProperties = ref new ImageEncodingProperties();imageProperties->Subtype = „JPEG”;imageProperties->Width = 320;imageProperties->Height = 240;

auto opCapturePhoto = m_mediaCaptureMgr->CapturePhotoToStorageFileAsync(imageProperties,this->m_photoStorageFile);

ImageEncodingProperties imageProperties = new ImageEncodingProperties();imageProperties.Subtype = „JPEG”;imageProperties.Width = 320;imageProperties.Height = 240;await mediaCaptureMgr.CapturePhotoToStorageFileAsync(imageProperties, photoStorageFile);

var photoProperties = new Windows.Media.MediaProperties.ImageEncodingProperties();photoProperties.subtype = „JPEG”;photoProperties.width = 320;photoProperties.height = 240;mediaCaptureMgr.capturePhotoToStorageFileAsync(photoProperties, photoStorage).then(…

C++

C#

JavaScript

Bezpośrednie mapowania

Primitives(strings, numbers,

etc) Interfaces Enums Structs Delegates Classes

Constructors Static Members Methods Properties Events

.NET i Windows Runtime

IReadOnlyDictionary<K,V>IMapView<K,V>

IEnumerable<T>IIterable<T>

IList<T>IVector<T>

IReadOnlyList<T>IVectorView<T>

IDictionary<K,V>IMap<K,V>

Konwersje typów

FileOpenPicker picker = new FileOpenPicker();picker.FileTypeFilter.Add("*");

StorageFile file = await picker.PickSingleFileAsync();

Windows.Storage.Streams.IInputStream inputStream = await file.OpenForReadAsync();

System.IO.Stream stream = inputStream.AsStream();System.IO.StreamReader reader = new StreamReader(stream);

string contents = reader.ReadToEnd();

String – nie może być null Przy próbie przekazania do komponentu WinRT – exception Nigdy nie otrzymamy null od komponentu WinRT

Tablice, kolekcje - read-only lub write-only void PassArray([In] int[] array); void FillArray([Out] int[] array, out int size);

Interfejs, nie implementacja List<string> vs IList<string>

Virtual - nie Uri – tylko absolute DateTime – tracimy informację o strefie czasowej

Kiedy należy uważać

Możesz tworzyć własne komponenty WinRT Logika wywoływana przez C# / JS / C++

2 typy komponentów Natywne – C++ .NET – C# / VB

Własne komponenty WinRT

Sygnatury API muszą wykorzystywać typy WinRT Tylko dla publicznych typów i właściwości Część typów ma sposoby na konwersję – np. extension methods

Struktury mogą mieć tylko publiczne pola Wszystkie typy muszą być oznaczone jako sealed

(oprócz kontrolek XAML) Tylko systemowe typy ogólne

Własne komponenty WinRT – zasady

Pod spodem klasyczny .NET (aplikacje pisane w C#) Specjalny profil dla aplikacji Windows Store Sztuczki z Reflection – nie przejdą przez certyfikację Windows Store Class Libraries lub Portable Class Libraries

Dozwolone niektóre API COM i Win32 Lista dozwolonych API

Dozwolone API

Dystrybucja komponentów WinRT

Nie mogą być dystrybuowane w sklepie samodzielnie Nie mogą być współdzielone pomiędzy aplikacjami Mogą być sprzedawane developerom

DemoWłasny komponent WinRT, integracja z HTML

Interfejs ma być „Fast & Fluid” Wszystkie API trwające >50 ms muszą być asynchroniczne

API bazują na Task<T>

Asynchroniczność

var data = DownloadData(...);ProcessData(data);

var future = DownloadDataAsync(...); future.ContinueWith(data => ProcessData(data));

DownloadDataAsync

ProcessData

STOP

ProcessDataDownloadData

private void DownloadPage(){    WebClient client = new WebClient();    client.DownloadStringCompleted += (o, e) =>        {            if (e.Error == null)            {                WebClient client2 = new WebClient();                client2.DownloadStringCompleted += (o, e) =>                    {                                                if (e.Error == null)                        {                            ...                        }                    };                client2.DownloadStringAsync(new Uri("http://www.microsoft.com"));            }        };    client.DownloadStringAsync(new Uri("http://www.bing.com"));}

Asynchroniczność - trudności

private async void DownloadPage() { HttpClient client = new HttpClient(); string bing = await client.GetStringAsync("http://www.bing.com"); string ms = await client.GetStringAsync("http://www.microsoft.com");

naszTextbox.Text = ms; }

Asynchroniczność w Windows 8 – C#

Asynchroniczność w C#

Task<T> async, await

Automatyczna transformacja na callbackową maszynę stanów Asynchroniczne metody

Oznaczone nowym słowem kluczowym “async” Muszą zwracać void lub Task<T> Wykorzystują operator “await” do przekazania kontroli Wskrzeszane, kiedy operacje zostają zakończone Łączone z klasycznymi konstrukcjami językowymi Wygląda jak stary, prosty kod synchroniczny!

Inne Windows Phone 7 – async CTP Silverlight 5 i .NET 4 - Async Targeting Pack

Automatyczna transformacja na callbackową maszynę stanów

Asynchroniczne metody Oznaczone nowym słowem kluczowym “async” Muszą zwracać void lub Task<T> Wykorzystują operator “await” do przekazania kontroli Wskrzeszane, kiedy operacje zostają zakończone Łączone z klasycznymi konstrukcjami językowymi

Wygląda jak stary, prosty kod synchroniczny!

Async, await

Task t, t1, t2 = ...

// Task chainingTask t3 = t.ContinueWith( () => { ... } );

Task[] taskCollection = new Task[] { client.GetStringAsync("http://www.bing.com"), client.GetStringAsync("http://www.bing.com"),};

// Task, który wykona się po zakończeniu tasków t1 i t2Task t4 = t.WhenAll(taskCollection);

// Oczekiwanie na zakończenie taskówTask.WaitAll(taskCollection);Task.WaitAny(taskCollection);

Taski - łączenie

// Wywołanie kodu w innym wątku z ThreadPool – jako Task

int result = await Task.Run(async () => { // Tu długotrwałe przetwarzanie danych w innym wątku... // ...

    await Task.Delay(1000);     return 42; });

Dowolny kod jako Task

Przykłady

private async void Button_Click_2(object sender, RoutedEventArgs e)

{

Button b = (Button) sender;

await Task.Run(() => {

b.Content += ".";

});

}

private async void Button_Click_2(object sender, RoutedEventArgs e)

{

Button b = (Button) sender;

await b.Dispatcher.RunAsync(

Windows.UI.Core.CoreDispatcherPriority.Normal,

() => {

b.Content += ".";

});

}

Przykłady

Windows.Media.Capture.CameraCaptureUI ccui;

private async void Button_Click_1(object sender, RoutedEventArgs e)

{

ccui = new Windows.Media.Capture.CameraCaptureUI();

await Task.Run(() => {

ccui.PhotoSettings.AllowCropping = true;

});

}

Windows.Media.Capture.CameraCaptureUI ccui;

private async void Button_Click_3(object sender, RoutedEventArgs e)

{

ccui = new Windows.Media.Capture.CameraCaptureUI();

await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,

() => {

ccui.PhotoSettings.AllowCropping = true;

});

}

public Task<string> GetStringAsync(Uri uri) { var tcs = new TaskCompletionSource<string>(); // .....długotrwała operacja asynchroniczna

var wc = new WebClient(); Wc.DownloadCompleted += (s, e) => { if (e.Error != null) { tcs.TrySetException(e.Error); } else if (e.Cancelled) { tcs.TrySetCanceled(); } else { tcs.TrySetResult(e.Result); } }; return tcs.Task; }

Opakowanie kodu w Task<T>

// tzw. Promises

WinJS.xhr({ url:"http://www.example.org/somedata.json"}).then(function (response) { updateDisplay( JSON.parse(response.responseText));}, function (ex) { reportXhrError(ex);});

Asynchroniczność w Windows 8 - Javascript

Asynchroniczność

Każde wywołanie API, które zajmuje powyżej 50 ms Dotychczas uciążliwe pisanie wielu callbacków

JavaScript .then .done (tzw. Promise)

C# async await CancellationToken, TPL, Task<T>, …

C++ Różne biblioteki Klasa task, metoda .then

Promises - asynchroniczność

Obietnica dostarczenia wartości w przyszłości Wiązane przez metodę then()

then(completion, error, progress) then() zwraca kolejny obiekt promise Implementacja w base.js: WinJS.Promise

Promise

WinJS.xhr({ url:"http://www.example.org/somedata.json"}).then(function (response) { updateDisplay( JSON.parse(response.responseText));}, function (ex) { reportXhrError(ex);});

DemoAsync w Windows 8

Cykl życia aplikacji

Uruchomionaaplikacja Zawieszona

zawieszanie Zamknięta

aplikacjaBrak pamięci

Kod jest wywoływany Kod wstrzymany Aplikacja wyłączona

wznawianie

App gets 5s to handle suspend

App is not notified before termination

Apps are notified when they have been resumed

Użytkownik uruchamia

Splash screen

Cykl życia aplikacji – c.d.

Wstrzymanie aplikacji Fizycznie pozostaje w pamięci

Zamknięcie Zamknięta przez użytkownika System potrzebuje pamięci Przełączenie użytkownika Wyłączenie komputera Wyjątek Brak notyfikacji!

Zapis stanu - najlepsze praktyki

Scenariusz Powinniśmy….

Użytkownik pracuje z aplikacją

Inkrementalny zapis stanu

Aplikacja wstrzymywanaZapisanie informacji gdzie jest użytkownik (np. aktywna strona)

Aktywacja wyłączonej aplikacji

Odczyt sesji tak, aby aplikacja sprawiała wrażenie nie zamkniętej

Aktywacja zawieszonej aplikacji

Nic nie rób

Aktywacja

// Override App’s OnLaunched

protected async override void OnLaunched(LaunchActivatedEventArgs args){ if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) { // Do an asynchronous restore await SuspensionManager.RestoreAsync(); }

if (args.Kind == ActivationKind.Launch) { if ( !string.IsNullOrEmpty ( args.Arguments ) { // handle arguments } } else if ( args.Kind == ActivationKind.ShareTarget ) { } // … }

Wznawianie

App.Current.Suspending += OnSuspending;

void OnSuspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e){} App.Current.Resuming += OnResuming;

void OnResuming(object sender, object e)}// Z reguły nie potrzebne

Splash screen

Domyślnie – grafika w manifest 15 sekund na wyświetlenie pierwszej strony Extended Splash Screen

Przekierownie na inną stronę od razu (progress bar) Doczytywanie na drugiej stronie

DemoTask switchingSplash screen

Podstawowy szablon projektu

SuspensionManager Zarządzanie stanem aplikacji (lokalny dla stron, globalny)

Serializuje wynik pracy do: %userprofile%\appdata\local\packages\...\LocalState\_sessionState.xml

LayoutAwarePage Klasa bazowa dla wszystkich stron

Przełączanie Visual State (dla snapped, filled, itp.)

Nawigacja

Zarządzanie stanem

DefaultViewModel

Konwertery, style (przycisk wstecz, itp.), klasa bazowa (INotifyPropertyChanged)

SuspensionManager RegisterFrame - rejestruje do automatycznego zapisywania / przywracania historii nawigacji Dependency property dla klasy Frame

FrameSessionStateKeyProperty FrameSessionStateProperty

Stan globalny - SuspensionManager.SessionState[„MojKlucz”] Uwaga na zarejestrowne „Frames”!

Sesja – struktura MojFrame1 (z reguły tylko jeden)

[„Navigation”, string] [„page-1”, Dictionary<string, object>]

[„GodzinaUruchomienia”, ...] ...

[„page-2”, Dictionary<string, object>] ...

[MojFrame2, ...] [MojKlucz, ...]

LayoutAwarePage – stan lokalny stron Automatyczne zapisywanie / wczytywanie stanu lokalnego

LoadState – przekazany stan oraz parametr nawigacyjny SaveState – przekazany kontener do uzupełnienia

Usuwanie stanu, kiedy nawigujemy na nową stronę

Stan lokalnyprotected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState){

var group = SampleDataSource.GetGroup((String)navigationParameter);this.DefaultViewModel["Group"] = group;this.DefaultViewModel["Items"] = group.Items;

if (pageState != null && pageState.ContainsKey("Date")){

pageTitle.Text = (String)pageState["Date"];}

}

protected override void SaveState(Dictionary<string, object> pageState){

pageState["Date"] = pageTitle.Text;base.SaveState(pageState);

}

DemoZarządzanie stanem

LayoutAwarePage - nawigacja

GoBack, GoHome, GoForward Mysz - wstecz / dalej Klawiatura – wstecz / dalej

Domyślnie – zawsze nowa instancja po back (inaczej niż w WP) Możliwość zmiany NavigationCacheMode – zachowanie jak w WP

Zarządzanie stanem wizualnym

WindowSizeChanged Zmiana stanu (filled / snapped, itp.) Zmiana orientacji ekranu

Visual States FullScreenLandscape Filled FullScreenPortrait Snapped

DemoLayoutAwarePage – c.d.Binding

Środowisko uruchomieniowe i uprawnienia Paczka aplikacyjna

App Manifest Blockmap – hashe wszystkich plików Podpis – sprawdza spójność

Model uprawnień App Container i System Broker Capabilities Permissions

Izolacja procesów

DemoCapabilities

Klient bliski Silverlightowi czy Windows Phone Obecnie brak WCF RIA Services

Obsługiwane typy komunikacji HttpClient (JSON, XML, ...) Usługi ASMX WCF ODATA Sockets

Bindingi WCF BasicHttpBinding NetTcpBinding NetHttpBinding CustomBinding

Windows 8 i usługi

Komunikacja

HttpClient (brak WebClient) DownloadOperation / BackgroundDownloader – kiedy potrzebny

progress XmlDocument.LoadFromUriAsync – kiedy wczytujemy XML WCF – specjalne proxy dla async/await

public async Task<string> MakeWebRequest(){ HttpClient http = new System.Net.Http.HttpClient(); HttpResponseMessage response = await http.GetAsync("http://www.example.com"); return await response.Content.ReadAsStringAsync();}

// Parse the JSON datavar array = JsonArray.Parse(result);

foreach (var item in array){

var obj = item.GetObject(); RecipeDataItem recipe = new RecipeDataItem();

foreach (var key in obj.Keys) { IJsonValue val; if (!obj.TryGetValue(key, out val)) continue;

switch (key) { case "key": recipe.UniqueId = val.GetNumber().ToString(); break; case "title": recipe.Title = val.GetString(); break;

case "ingredients": var ingredients = val.GetArray(); var list = (from i in ingredients select i.GetString()).ToList(); recipe.Ingredients = new ObservableCollection<string>(list); break;

}}

Json - serializacja [DataContract] internal class Person { [DataMember] internal string name;

[DataMember] internal int age; }

// Klasycznie (DataContractJsonSerializer)MemoryStream stream1 = new MemoryStream();DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));stream1.Position = 0;Person p2 = (Person)ser.ReadObject(stream1);

// Newtonsoft Json (nuGet) – szybciej i bardziej elastycznieMyObject obj = JsonConvert.DeserializeObject<MyObject>(jsonEncodedString);

Live Connect Single sign on (SSO) Możliwe wykorzystanie kontekstu użytkownika

WebAuthenticationBroker Integracja z innymi usługami OAUTH 2.0 Bezpieczny, gotowy mechanizm logowania Facebook, Google, Flickr, Twitter, Live

Uwierzytelnienie – zewnętrzne usługi

await WebAuthenticationBroker.AuthenticateAsync()

DemoWCF, ASP.NET MVC Web API

Baza relacyjnaJetAPI C++, JetCreateDatabase2 itp. (to samo co AD, Exchange itp.)

IndexedDBHTML5, ale..

IDBDatabase

SQLite (wersja Release by przeszła WACK!)

SQLiteExtension + biblioteka kliencka z Nuget

Kompilować w Release – inaczej nie przejdzie WACK

DemoBaza danych

Semantic zoom

Zmiana „kontekstu” listy na bardziej ogólny Ctrl + rolka, ctrl +/-, przycisk

Kontrolka SemanticZoom ZoomedInView ZoomedOutView

ISemantizZoomInformation ListView GridView

Źródło dla zoomin i zoomout musi być powiązane CollectionViewSource - this.groupedItemsViewSource.View.CollectionGroups;

<CollectionViewSource x:Name="groupedItemsViewSource" Source="{Binding Groups}" IsSourceGrouped="true" ItemsPath="TopItems"/>

// ItemsPath – dla grup LINQ nie jest potrzebne

List<Activity> Activities = new List<Activity>(); Activities.Add(new Activity() { Name = "Activity 1", Complete = true, DueDate = startDate.AddDays(4), Project = "Project 1" }); Activities.Add(new Activity() { Name = "Activity 2", Complete = true, DueDate = startDate.AddDays(5), Project = "Project 1" }); Activities.Add(new Activity() { Name = "Activity 3", Complete = false, DueDate = startDate.AddDays(7), Project = "Project 1" }); Activities.Add(new Activity() { Name = "Activity 4", Complete = false, DueDate = startDate.AddDays(9), Project = "Project 1" }); Activities.Add(new Activity() { Name = "Activity 5", Complete = false, DueDate = startDate.AddDays(14), Project = "Project 1" });

var result = from act in Activities group act by act.Project into grp orderby grp.Key select grp;

// Dla zoom incvsActivities.Source = result;

// Dla zoomoutthis.groupGridView.ItemsSource = this.cvsActivities.View.CollectionGroups;

DemoSemantic Zoom

Kontrakty, integracja z systemem

Proces share’owaniaAplikacja docelowaShare Broker

Użytkownik wybiera “Share”, zdarzenie w app

Aktywowana do share’owania

Rejestracja w DataTransfer Manager

Aplikacja źródłowa

Filtrowanie listy target i quick links

Użytkownik wybiera aplikację lub quick link

Przetwarzanie zawartości DataPackage

Zgłasza koniec

Kończy Async call i kończy pracę

Otrzymuje event i wypełnia DataPackage

DataPackage żyje w aplikacji źródłowej

Aktywacja docelowej aplikacji (kind: shareTarget)

Share

Share target Konieczne deklaracje w manifeście typu obsługiwanych danych

Share source – zdarzenie DataTransferManager OnDataRequested (args.Data – paczka z wymienianymi danymi) Właściwości (description, title, itp.) – Title wymagany DataTransferManager.ShowShareUI(); - programowe wywołane

Lista aplikacji docelowych filtrowana na podstawie tego co umieścimy w paczce (np. SetText, SetHTML, ...)

Możliwe umieszczenie danych w kilku „szufladach” jednocześnie (np. tekst i HTML)

np. Poczta szuka w kolejności Html -> Link -> Tekst

Share source - przykład

DataTransferManager.GetForCurrentView().DataRequested += OnDataRequested;

void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args) { var request = args.Request; var item = (ModelItem)this.flipView.SelectedItem; request.Data.Properties.Title = item.Title; request.Data.Properties.Description = „Something to share";

// Share text var textToShare = „Text to share";

request.Data.SetText(textToShare); request.Data.SetHtmlFormat(textToShare);

}

Data Package

Zwykły tekst (SetText) Sformatowany tekst (SetRtf) URI (SetUri) HTML (SetHtmlFormat) Pliki (SetStorageItems) Zdjęcia (SetBitmap)

Zalecane dodatkowo SetStorageItems Własne formaty danych (SetData)

Własne formaty

Zalecane sprawdzenie czy typ nie jest już publicznie udokumentowany http://schema.org/ (np. http://schema.org/Book) Obsługa wyjątków podczas wczytywania

Obsługiwane typy Skalary (integer, string, DateTime, itp.) poprzez IPropertyValue. IRandomAccessStream, IRandomAccessStreamReference - np. własna klasa i

DataContractSerializer IUri IStorageItem Kolekcje powyższych

Data Provider

Zalecane, kiedy długotrwałe przetwarzanie danych Np. pomniejszenie zdjęcia przed udostepnieniem

Deferral providerRequest.GetDeferral();

Standardowe typy (StandardDataFormats) lub własne

requestData.SetDataProvider(StandardDataFormats.Bitmap, providerRequest => this.OnDeferredImageRequestedHandler(providerRequest, this.selectedImage));

DemoShare source

Share target Konieczna deklaracja w manifeście

Formaty danych Formaty plików

OnShareTargetActivated(ShareTargetActivatedEventArgs args) args.ShareOperation Zalecane pobranie ShareOperation i przetwarzanie asynchroniczne

ShareOperation Data – obiekt DataPackageView (praktycznie r/o DataPackage) QuickLinkId

await Task.Factory.StartNew(async () =>

{

// Przetwarzamy Data Package

}

await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>

{

// Wracamy do wątku UI

}

Długie przetwarzanie shareOperation.ReportStarted();

Od tego momentu brak interakcji z aplikacją share’ującą Użytkownik może zamknąć okno share i wrócić do aplikacji

shareOperation.ReportDataRetreived(); (opcja) Po pobraniu danych z DataPackage Zgłasza mozliwość uśpienia / zamknięcia aplikacji źródłowej - optymalizacja Może być wywołany przed ReportStarted() – np. Task po aktywacji Share, ale przed kliknięciem „wyślij” w celu

przyspieszenia procesu shareOperation.ReportSubmittedBackgroundTask(); (opcja)

Sugerowane zgłoszenie, kiedy korzystamy z BackgroundTransfer – optymalizacja shareOperation.ReportCompleted([quicklink]);

Zgłoszenie zakończenia Zapisanie quicklinka i (samodzielnie) identyfikatora np. w bazie

shareOperation.ReportError(txt); Przerwanie operacji, toast + komunikat o błędzie

QuickLink quickLinkInfo = new QuickLink{

Id = QuickLinkId.Text,Title = QuickLinkTitle.Text,

SupportedFileTypes = { "*" },SupportedDataFormats =

{StandardDataFormats.Text,StandardDataFormats.Uri,StandardDataFormats.Bitmap,StandardDataFormats.StorageItems,StandardDataFormats.Html,dataFormatName

}};

Quick Link

Formaty i typy plików niezależne od manifestu Czyszczone / wyłączane z panelu sterowania (share -> clear list)

DemoShare target

Search

Wpis w deklaracjach manifestu OnSearchActivated

Kiedy search wywołany gdy aplikacja była zamknięta, OnLaunched NIE WYWOŁYWANY

Konieczne ręczne zainicjalizowanie aplikacji (jak w OnLaunched) ShowOnKeyboardInput – automatyczne otwieranie charms bar

Podpowiedzi

Wcześniej aktywowanie aplikacji (wybranie jej z listy charms) SearchPane.GetForCurrentView().SuggestionsRequested

args.QueryText args.Request.SearchSuggestionCollection.AppendQuerySuggestion(...);

SetLocalContentSuggestionSettings - pliki Separatory – AppendSearchSeparator Rezultaty (ze zdjęciem i opisem) - AppendResultSuggestion

Łącznie 5 elementów (sugestie, rezultaty, separatory)

DemoSearch contract

Ustawienia

Domyślnie tylko Permissions – na podstawie capabilities SettingsPane.GetForCurrentView().CommandsRequested

Komendy obsługiwane przez daną stronę Flyout – najprościej z Callisto

Najlepiej w App.xaml.cs W przeciwnym wypadku trzymanie referencji do strony (GC)

Flyout Zwykła kontrolka Popup odpowiednio wypozycjonowana Transitions 346 lub 646 pikseli

Ustawienia - kodSettingsPane.GetForCurrentView().CommandsRequested += onCommandsRequested;

void onCommandsRequested(SettingsPane settingsPane, SettingsPaneCommandsRequestedEventArgs eventArgs){

UICommandInvokedHandler handler = new UICommandInvokedHandler(onSettingsCommand);

SettingsCommand generalCommand = new SettingsCommand("generalSettings", "General", handler);eventArgs.Request.ApplicationCommands.Add(generalCommand);

}

// To samo z flyout (callisto) void OnCommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args) { // Add an About command var about = new SettingsCommand("about", "About", (handler) => { var settings = new SettingsFlyout(); settings.Content = new AboutUserControl(); settings.HeaderBrush = new SolidColorBrush(_background); settings.Background = new SolidColorBrush(_background); settings.HeaderText = "About"; settings.IsOpen = true; });

args.Request.ApplicationCommands.Add(about); }

DemoUstawienia

Zapisywanie danych

Katalog instalacyjny App data

Ustawienia lokalne – ApplicationData.Current.LocalSettings Kontenery - proste grupowanie ustawień Composite ms-appdata://local //roaming //temp

Pliki, sesja – ApplicationData.Current.LocalFolder User data

Dokumenty, zdjęcia, muzyka, filmy Roaming

Roaming Settings ApplicationData.Current.RoamingSettings Dostępne nawet, kiedy brak sieci / nie połączone konto LiveID Max 100 KB

ApplicationData.Current.RoamingStorageQuota;

Synchronizacja, kiedy system zadecyduje Typ połączenia z siecią, obciążenie, itp. Brak możliwości wymuszenia synchronizacji

Composite settings dla „atomowych” zmian (konflikty) ApplicationDataCompositeValue

Ustawienie HighPriority dla bardzo istotnych Może być composite

ApplicationData.Current.SetVersion – aby uniknąć problemów z wersjonowaniem DataChangedHandler

DemoUstawienia

Devices

Drukowanie NFC DLNA

Tylko Windows Certified (podzbiór „Play To”) Obecnie m.in. najnowsze Samsung Smart TV, amplitunery Onkyo, Sony, PlayTo

API, Windows Media Player, ...

DemoDrukowanie

Play To

Strumieniowanie z naszej aplikacji MediaElement – muzyka, film Image (może zdalny PowerPoint?)

Dostęp do danych z Media Serwerów Aplikacja jako odbiorca Play To

Teoretycznie do wykorzystania dla dowolnego strumienia

Implementacja Play To

<MediaElement x:Name="videoplayer" Source = "http://www.contoso.com/clip.mp4" AutoPlay="true" />

// Krok 1: PlayToManager dla widoku.

PlayToManager ptm = Windows.Media.PlayTo.PlayToManager.GetForCurrentView();

// Krok 2: Zdarzenie SourceRequested (użytkownik wskazał urządzenie).

ptm.SourceRequested += (PlayToManager sender, PlayToSourceRequestedEventArgs e) => {

request = e.SourceRequest;

// Krok 3: określenie mediów do strumieniowania

PlayToSourceDeferral deferral = request.GetDeferral();

request.SetSource(videoplayer.PlayToSource);

deferral.Complete();

}

// Media strumieniowane do urządzenia

DemoPlay to

Shareowanie z osobami w pobliżu

// Rejestrujemy w klasyczny sposób kontrakt do share’owaniafunction setupShare() { var dtm = Windows.appModel.DataTransfer.DataTransferManager.getForCurrentView(); dtm.addEventListener("datarequested", function (e) { onDataRequested(e); });}

// Obsługujemy tak jak lokalne żądanie do share’owania function onDataRequested(e) {

var dp = new Windows.appModel.DataTransfer.DataPackage(); dp.properties.title = "Our Test Text"; // required dp.properties.description = "Test Description"; // required dp.setUri(new Windows.Foundation.Uri("http://www.oddfellows.com")); e.request.data = dp;}

App To App pickers

App To App pickers

DemoContacts picker

Własne protokoły

mojprotokol://jakies/parametry Z przeglądarki (zarówno Metro jak i Desktop) Przekazywane parametry do OnActivated Działa także jako link w aplikacji Jeśli kilka aplikacji zarejestrowanych – wybór za pierwszym razem

DemoWłasny protokół

Touch

Proste gesty Tap

Nie to samo co mouse_down W przypadku myszki – dowolny czas, bez ruchu W przypadku ekranu dotykowego – max. pół sekundy

DoubleTap, Holding, ...

Pointer events PointerPressed, PointerReleased, PointerMoved Dla palca, myszki, rysika, ... Unikalne identyfikatory

DemoTouch

Praca w tle

Background Audio Kilka niezależnych typów (komunikator, media, gra,itp.) Jeden typ strumienia na raz

Background Transfer Upload / download danych w tle

Execution = Trigger + [Condition]

Trigger Condition

InternetAvailable, InternetNotAvailable, SessionConnected, SessionDisconnected, UserNotPresent, UserPresent

SystemEventTriggerControlChannelReset #InternetAvailableLockScreenApplicationAdded/RemovedNetworkStateChange OnlineIdConnectedStateChangeServicingCompleteSessionConnected/Disconnected #SmsReceivedTimeZoneChangeUserAway/UserPresent #

ControlChannelTrigger # (**)TimeTrigger #PushNotificationTrigger # (**)MaintenanceTrigger # wymaga lock permission

**może być in-proc (nie BackgroundTaskHost.exe)

„Condition latching”Maintenance trigger – na zasilaniu

Rejestracja - manifest

<Extensions> <Extension Category="windows.backgroundTasks" EntryPoint="Tasks.SampleBackgroundTask"> <BackgroundTasks> <Task Type="systemEvent" /> <Task Type="timer" /> </BackgroundTasks> </Extension> <Extension Category="windows.backgroundTasks" EntryPoint="Tasks.ServicingComplete"> <BackgroundTasks> <Task Type="systemEvent" /> </BackgroundTasks> </Extension></Extensions>

Rejestracja – c.d.

string BackgroundTaskName = "SampleBackgroundTask";string BackgroundTaskEntryPoint = "BackgroundTask.SampleBackgroundTask";

void RegisterBackgroundTask(){ var taskBuilder = new Windows.ApplicationModel.Background.BackgroundTaskBuilder(); var systemTrigger = new SystemTrigger(SystemTriggerType.InternetAvailable , false); var userPresentCondition = new SystemCondition(SystemConditionType.UserPresent);

taskBuilder.SetTrigger(systemTrigger); taskBuilder.AddCondition(userPresentCondition); taskBuilder.Name = BackgroundTaskName; taskBuilder.TaskEntryPoint = BackgroundTaskEntryPoint;

var task = taskBuilder.Register(); task.Progress += task_Progress; task.Completed += task_Completed; }

Aplikacje Lock Screen

Aplikacje, które mogą działać w tleZwłaszcza aplikacje komunikacyjne (poczta, komunikator, VoIP)

Okresowe uruchamianieUruchamianie kodu w odpowiedzi na zdarzenia systemowe

Zarządzane przez użytkownika (max 7)

Przydzielanie zasobów

CPU quota Odświeżanie

Z lock screen 2 sekundy CPU 15 minut

Bez lock screen 1 sekunda CPU 2 godziny

Tylko kiedy naprawdę „background” (przy uruchomionej aplikacji brak ograniczeń) Dotyczy tylko faktycznej pracy CPU!!!

Ograniczenia dla połączeń

Tylko kiedy praca na baterii

Okres odświeżania 15 min 2 godziny dziennie

Limit na dane (lock) 0.469 MB n/a 45 MB

Limit na dane (nie lock) n/a 0.625 MB 7.5 MB

Krytyczne zadania

Np. VOIP Triggery: Control Channel, notyfikacje Push PUSH

Brak SLA Backend musi być przystosowany

Control Channel Triggery: Control Channel lub Keep-alive (co 15 minut podtrzymanie połączenia) Przetwarzanie komunikatów, kiedy aplikacja zawieszona Software i hardware slot (dla ARM) Nieco więcej pracy Podtrzymywane połączenie

Gwarantowane zasoby dla poszczególnych zadań (takie same jak dla aplikacji)

Globalna pula Dodatkowe zasoby współdzielone między aplikacjami

Co 15 minut uzupełniana Wielkość zasobów zależy od wielu czynników

Nie należy na niej polegać

Lepiej wyłączyć podczas testów HKEY_LOCAL_MACHINE\ SOFTWARE\Microsoft\Windows NT\CurrentVersion\BackgroundModel\Policy\CpuEnableGlobalPool HKEY_LOCAL_MACHINE\ SOFTWARE\Microsoft\Windows NT\CurrentVersion\BackgroundModel\Policy\NetEnableGlobalPool

Może mimo wszystko nie wystarczyć… Event log BackgroundTaskInstnce.SuspendedCount

DemoPraca w tle

Live Tiles – wrażenie aktywności

Dostarczają informacji, kiedy aplikacja jest wyłączona

Wrażenie, że aplikacja działa w tle i zaproszenie do powrotu

Dwa mechanizmy do aktualizacjiLokalne APINotyfikacje PUSH

Tiles

2 rozmiary 150x150 px 310x150 px (opcja)

Wide – konieczne ustawienie w manifeście

var tile = new SecondaryTile( item.UniqueId, // Tile ID item.ShortTitle, // Tile short name item.Title, // Tile display name item.UniqueId, // Activation argument TileOptions.ShowNameOnLogo, // Tile options uri // Tile logo URI );

await tile.RequestCreateAsync();

Live Tiles

Wiele możliwości prezentacyjnych

Aktualizowane przy pomocy predefiniowanych szablonów

Tekstowe, graficzne lub mix

JPEG lub PNG, max rozmiar 150KB

Opcjonalna animacja “peek”

Lokalna lub zdalna aktualizacja

Kolejkowanie notyfikacji

Opcjonalnie rotowanie między 5 ostatnimi notyfikacjami

Domyślnie tylko ostatnia wyświetlana

Secondary Tiles

„Pinowanie” zawartości z wewnątrz aplikacji Proste wywołanie API Użytkownik potwierdza (systemowe UI) Personalizowana przestrzeń aplikacji Takie same możliwości jak główne kafelki

Tylko lokalne obrazy Uruchomienie przekierowuje do określonej sekcji aplikacji

DemoLive tiles / secondary tiles

Notyfikacje Toast

Podobna struktura do kafelków (oparta o szablony) Różne możliwości wizualne

DemoNotyfikacje Toast

Notyfikacje PUSH - WNS

Zdalne zmiany kafelków i notyfikacje Toast (Internet) Także, kiedy aplikacja jest wyłączona

Skalowalne, bezpłatne

PUSH – schemat działaniaWindows 8 Usługa w

chmurze

Windows Notification

Service

Aplikacja Metro Style

NotificationClient

Platform

2

3

1 3

1. Żądamy URI kanału PUSH

2. Rejestracja w naszej usłudze

3. Uwierzytelnienie i wysłanie notyfikacji

Notyfikacje – c.d.

Komunikaty: Tile, Badge, Toast, Raw Raw wymaga locked screen!

Wygasają po 30 dniach Wznowienie podczas uruchamiania aplikacji Maintenance trigger

Azure Toolkit for Windows 8

Azure Mobile Services

Bardzo prosty back-end w Azure Storage PUSH Uwierzytelnienie Live Connect

Bezpłatnie (obecnie preview) Do 10 instancji 165 MB Reserved – kiedy jest potrzeba

Dodatkowe opłaty 100 usług Transfer pay-as-you-go

DemoAzure Mobile Services

Windows Store

Podział zysków 70:30 lub 80:20 Reklamy – dowolnie Trial In-app purchase Rejestracja

49 lub 99 USD / rok Dreamspark, MSDN, Bizspark – bezpłatnie 1 rok!

Od strony dewelopera Pełne dane na temat licencji Recipes (przypomnienie) Symulator

Konwersja z Trialprivate async void ConvertTrial(){ var licenseInformation = CurrentApp.LicenseInformation;

licenseInformation.LicenseChanged += licenseInformation_LicenseChanged;if (licenseInformation.IsTrial)

await CurrentApp.RequestAppPurchaseAsync(); }

void licenseInformation_LicenseChanged(){

if (CurrentApp.LicenseInformation.IsActive) { //Enable features..

} }

In-app purchasevar licenseInformation = CurrentApp.LicenseInformation;var productLicense = licenseInformation.ProductLicenses["product1"];if (!productLicense.IsActive && licenseInformation.IsActive ) {

try { await CurrentAppSimulator.RequestProductPurchaseAsync("product1“, false);

// No exception: enable product1 }catch (Exception){

//product 1 was not purchased }

}

Symulator

CurrentAppSimulator.ReloadSimulatorAsync(file);

DemoIntegracja ze sklepem

DPI

System automatycznie przeskalowuje w zależności od DPI Elementy wektorowe – bez problemu Grafika – może być gorsza jakość

Grafika i DPI

Modern Resource Technology (MRT) Automatycznie, na podstawie nazw Uwaga – nie zmieni się w runtime <img src=„projector.jpg” width=80px height=80px /> Konwencja nazewnicza

...\projector.scale-100.jpg ...\projector.scale-140.jpg ...\projector.scale-180.jpg

Manualnie (zdarzenie)

Grid i typografia

Jedno z UX Guidelines Zaprojektowany, aby skalował się bez zaokrągleń

DemoHigh DPI

Zasoby i lokalizacja

Automatyczne rozpoznawanie języka (ustawienia) systemowe Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride

Katalogi i pliki *.resw Domyślny – Resources.resw x:Uid

Wybór zdjęć na podstawie kontrastu, skali, języka Pierwszeństwo zasobów nad zapisaną wartością w XAML Ręcznie

var resourceLoader = new ResourceLoader([ew. plik resw]);this.tb.Text = resourceLoader.GetString("string1");

Manifest - ms-resource:appDescription

Zadania MAT• Pomaga weryfikować zasoby, wykryć nowe

nieprzetłumaczone.• UI do wyboru języka.• Wykorzystuje standard XLIFF file format.

• OASIS XML Localisation Interchange File Format (XLIFF) TC• https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=xliff

• Dostarcza motor pseudo-języka, co pomaga zidentyfikować problemy podczas developmentu

• Pozwala wykorzystać Microsoft Translator (sugestie, może tłumaczenie).

• Nie pomaga w „uresourceowieniu” aplikacji – to robota programisty!

• Wsparcie korekty

Skórki

<ResourceDictionary.ThemeDictionaries> <ResourceDictionary x:Key="Default"> <x:String x:Key="BackButtonGlyph">&#xE071;</x:String> <x:String x:Key="BackButtonSnappedGlyph">&#xE0BA;</x:String> </ResourceDictionary>

<ResourceDictionary x:Key="HighContrast"> <x:String x:Key="BackButtonGlyph">&#xE0A6;</x:String> <x:String x:Key="BackButtonSnappedGlyph">&#xE0C4;</x:String> </ResourceDictionary> </ResourceDictionary.ThemeDictionaries>

DemoZasoby

Animacje

Animacje Nowe elementy StoryBoardów Np. Popin/PopoutAnimation

Content Transitions Popup Page Content Control (kontenery typu Grid, StackPanel, itp.)

DemoAnimacje

MVVM – po co?

Separacja warstw Testowanie Wsparcie Blend

Model-View-ViewModel

Widok Jak wyświetlić informację?

View Model Którą informację wyświetlić? Interakcja, przepływ

Model Obiekty reprezentujące dane Logika biznesowa

Model

View Model

View Platform-specific

PortableReferences

Databinds

DemoMVVM Light Toolkit

Problem z class libraries i przenośnością...

Portable Class Libraries

Jedno źródło Jeden projekt Jeden plik binarny Wiele platform!

Dostępne mechanizmy

Aplikacja cross-platform

Startup

Views

Windows Store App

Platform specific functionality

View Models

Models

Portable Class Library

Platform functionality abstractions

Startup

Views

Windows Phone App

Platform specific functionality

Reference Reference

DemoPortable Class Libraries i MVVM

Nieco bardziej komplikujemy...

Nawigacja IoC

Ninject Autofac

async ...

DemoNieco bardziej skomplikowany przykład...

Potrzebujemy jeszcze Android, iOS?

HTML 5 – Apache Cordova aka PhoneGap Xamarin Framework

Cross-plaformowy C# Generics, Linq, Async, ...

Bazuje na Mono Komercyjny (400 USD / platforma)

Trial w pełni sprawny (emulator) iOS (potrzebny MAC), MonoDevelop Android – także Visual Studio!

MvvmCross

Bazuje (już) na Portable Class Libraries Cross-platformowość

iOS Android Windows Phone Windows 8

Bazuje na konwencjach (podobnie jak Caliburn.micro)

Wybrane zagadnienia (luźne)

Debugowanie komponentów WinRT

Nie można debugować jednocześnie kodu JS i managed (np. komponent)

WinMD i managed code

Ildasm /project – włączenie adaptera Bez tego – widzimy jak zapisane na dysku Z parametrem project – widzimy tak jak widzi CLR

Typy WinRT

Kategoria PrzykładStandard WinRT types Windows.Foundation.Collections.PropertySet,

Windows.Networking.Sockets.DatagramSocketPrimitive types Byte, Int32, String, ObjectProjected types Windows.Foundation.Uri,

Windows.Foundation.DateTimeProjected interfaces Windows.Foundation.Collections.IVector<T>,

Windows.Foundation.IclosableTypes with .NET helpers Windows.Storage.Streams.IInputStream,

Windows.Foundation.IasyncInfo

top related