SlideShare a Scribd company logo
1 of 217
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ądzeo 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 przeciwieostwie 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ń
Demo
Windows 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_MACHINESoftwarePoliciesMicrosoftWindowsAppx
AllowAllTrustedApps = 1
Sideloading – c.d.
 Wgranie certyfikatu użytego do podpisania aplikacji
 PowerShell
 import-module appx
 add-appxpackage udziałsieciowyapp1.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=b809e47cd0110a4db0
43b3f73e83acd917fe1336
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 Platform
WinRT API z bliska
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
Demo
Typescript
HTML 5 i Windows 8
Windows 8 – akcelerowana platforma HTML
Najpopularniejsze cechy HTML5
Demo
IE 10 i HTML 5, CSS 3
WinJS
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ąd 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
Demo
Windows 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 zatrzymad – e.Handled = true
Hierarchia klas
 Dependency Object (dependency property system)
 UIElement (klawiatra, touch, …)
 FrameworkElement (layout, loaded / unloaded, binding, style)
Dependency Property
public static readonly DependencyProperty
MyNumberProperty = 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 byd 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ń 2
Programowanie 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" "capCreateCaptureWindow"
static extern int
string int
int int int int
int int
DllImport "avicap32.dll"
static extern bool
int
MarshalAs UnmanagedType ref string
int
MarshalAs UnmanagedType ref string
int
// więcej i więcej w podobny sposób...
...a w Windows 8
using Windows.Media.Capture;
var new CameraCaptureUI
new Size
var await CameraCaptureUIMode
if
var new BitmapImage
await FileAccessMode
 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:WindowsSystem32WinMetadata
Projekcje językowe
Projekcje językowe
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
.NET i Windows Runtime
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ą byd dystrybuowane w sklepie samodzielnie
 Nie mogą byd współdzielone pomiędzy aplikacjami
 Mogą byd sprzedawane developerom
Demo
Wł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
DownloadDataAsync ProcessData
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ą zwracad void lub Task<T>
 Wykorzystują operator “await” do przekazania kontroli
 Wskrzeszane, kiedy operacje zostają zakooczone
 Łą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 chaining
Task 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 t2
Task t4 = t.WhenAll(taskCollection);
// Oczekiwanie na zakończenie tasków
Task.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
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
Demo
Async w Windows 8
Cykl życia aplikacji
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….
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
Demo
Task switching
Splash screen
Podstawowy szablon projektu
 SuspensionManager
 Zarządzanie stanem aplikacji (lokalny dla stron, globalny)
 Serializuje wynik pracy do:
%userprofile%appdatalocalpackages...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 lokalny
protected 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);
}
Demo
Zarzą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śd 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
Demo
LayoutAwarePage – c.d.
Binding
Środowisko uruchomieniowe i
uprawnienia
 Paczka aplikacyjna
 App Manifest
 Blockmap – hashe wszystkich plików
 Podpis – sprawdza spójnośd
 Model uprawnieo
 App Container i System Broker
 Capabilities
 Permissions
 Izolacja procesów
Demo
Capabilities
 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 data
var 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 elastycznie
MyObject 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()
Demo
WCF, ASP.NET MVC Web API
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 byd 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 in
cvsActivities.Source = result;
// Dla zoomout
this.groupGridView.ItemsSource = this.cvsActivities.View.CollectionGroups;
Demo
Semantic Zoom
Kontrakty, integracja z
systemem
Proces share’owania
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));
Demo
Share 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ąd okno share i wrócid do aplikacji
 shareOperation.ReportDataRetreived(); (opcja)
 Po pobraniu danych z DataPackage
 Zgłasza mozliwośd uśpienia / zamknięcia aplikacji źródłowej - optymalizacja
 Może byd 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 zakooczenia
 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)
Demo
Share 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)
Demo
Search 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 - kod
SettingsPane.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);
}
Demo
Ustawienia
Zapisywanie danych
 Katalog instalacyjny
 App data
 Ustawienia lokalne – ApplicationData.Current.LocalSettings
 Kontenery - proste grupowanie ustawieo
 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 byd composite
 ApplicationData.Current.SetVersion – aby uniknąd problemów z wersjonowaniem
 DataChangedHandler
Demo
Ustawienia
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, ...
Demo
Drukowanie
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’owania
function 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
Demo
Contacts 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
Demo
Wł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
Demo
Touch
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
SystemEventTrigger
ControlChannelReset #
InternetAvailable
LockScreenApplicationAdded/Removed
NetworkStateChange
OnlineIdConnectedStateChange
ServicingComplete
SessionConnected/Disconnected #
SmsReceived
TimeZoneChange
UserAway/UserPresent #
ControlChannelTrigger # (**)
TimeTrigger #
PushNotificationTrigger # (**)
MaintenanceTrigger # wymaga lock permission
**może byd 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, które mogą
działad w tle
Zwłaszcza aplikacje
komunikacyjne (poczta,
komunikator, VoIP)
Okresowe uruchamianie
Uruchamianie 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 ograniczeo)
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
Demo
Praca 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 aktualizacji
Lokalne API
Notyfikacje 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
Kolejkowanie notyfikacji
Secondary Tiles
 „Pinowanie” zawartości z wewnątrz aplikacji
 Proste wywołanie API
 Użytkownik potwierdza (systemowe UI)
 Personalizowana przestrzeo aplikacji
 Takie same możliwości jak główne kafelki
 Tylko lokalne obrazy
 Uruchomienie przekierowuje do określonej sekcji aplikacji
Demo
Live tiles / secondary tiles
Notyfikacje Toast
 Podobna struktura do kafelków (oparta o szablony)
 Różne możliwości wizualne
Demo
Notyfikacje 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łania
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
Demo
Azure 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 Trial
private 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 purchase
var 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);
Demo
Integracja ze sklepem
DPI
 System automatycznie przeskalowuje w zależności od DPI
 Elementy wektorowe – bez problemu
 Grafika – może byd gorsza jakośd
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ągleo
Demo
High 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ęd na podstawie kontrastu, skali, języka
 Pierwszeostwo 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
• 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>
Demo
Zasoby
Animacje
 Animacje
 Nowe elementy StoryBoardów
 Np. Popin/PopoutAnimation
 Content Transitions
 Popup
 Page
 Content Control (kontenery typu Grid, StackPanel, itp.)
Demo
Animacje
MVVM – po co?
 Separacja warstw
 Testowanie
 Wsparcie Blend
Model-View-ViewModel
 Widok
 Jak wyświetlid informację?
 View Model
 Którą informację wyświetlid?
 Interakcja, przepływ
 Model
 Obiekty reprezentujące dane
 Logika biznesowa
Databinds
Demo
MVVM 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
Demo
Portable Class Libraries i MVVM
Nieco bardziej komplikujemy...
 Nawigacja
 IoC
 Ninject
 Autofac
 async
 ...
Demo
Nieco 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śd
 iOS
 Android
 Windows Phone
 Windows 8
 Bazuje na konwencjach (podobnie jak Caliburn.micro)
Wybrane zagadnienia (luźne)
Debugowanie komponentów WinRT
 Nie można debugowad 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ład
Standard WinRT types Windows.Foundation.Collections.PropertySet,
Windows.Networking.Sockets.DatagramSocket
Primitive types Byte, Int32, String, Object
Projected types Windows.Foundation.Uri,
Windows.Foundation.DateTime
Projected interfaces Windows.Foundation.Collections.IVector<T>,
Windows.Foundation.Iclosable
Types with .NET helpers Windows.Storage.Streams.IInputStream,
Windows.Foundation.IasyncInfo

More Related Content

Similar to Programowanie aplikacji dla Windows 8 (WinRT)

Seminarium - Tworzenie Aplikacji Mobilnych 2004
Seminarium - Tworzenie Aplikacji Mobilnych 2004Seminarium - Tworzenie Aplikacji Mobilnych 2004
Seminarium - Tworzenie Aplikacji Mobilnych 2004Tomasz Cieplak
 
Silverlight i PHP - jak budować interfejs nowoczesnych aplikacji internetowych?
Silverlight i PHP - jak budować interfejs nowoczesnych aplikacji internetowych?Silverlight i PHP - jak budować interfejs nowoczesnych aplikacji internetowych?
Silverlight i PHP - jak budować interfejs nowoczesnych aplikacji internetowych?PHPCon Poland
 
Aplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxAplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxDawid Rusnak
 
Jak stworzyć udany system informatyczny
Jak stworzyć udany system informatycznyJak stworzyć udany system informatyczny
Jak stworzyć udany system informatycznyqbeuek
 
Functional widgets in Rails
Functional widgets in RailsFunctional widgets in Rails
Functional widgets in RailsSebastian Sito
 
Współdzielenie kodu aplikacji Windows Phone i Windows 8
Współdzielenie kodu aplikacji Windows Phone i Windows 8Współdzielenie kodu aplikacji Windows Phone i Windows 8
Współdzielenie kodu aplikacji Windows Phone i Windows 8Bartlomiej Zass
 
Seminarium .Net CF 2004
Seminarium .Net CF 2004Seminarium .Net CF 2004
Seminarium .Net CF 2004Tomasz Cieplak
 
Drobne błędy w portalach WWW -- prawdziwe studium przypadku
Drobne błędy w portalach WWW -- prawdziwe studium przypadkuDrobne błędy w portalach WWW -- prawdziwe studium przypadku
Drobne błędy w portalach WWW -- prawdziwe studium przypadkumsobiegraj
 
Bohater UI bez front end developera ?
Bohater UI bez front end developera ?Bohater UI bez front end developera ?
Bohater UI bez front end developera ?Quick-Solution
 
Michał Dec - Quality in Clouds
Michał Dec - Quality in CloudsMichał Dec - Quality in Clouds
Michał Dec - Quality in Cloudskraqa
 
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychGanymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychSKN Shader
 
ITAD PolSl 2014 - Nowości w .NET 2015
ITAD PolSl 2014 - Nowości w .NET 2015ITAD PolSl 2014 - Nowości w .NET 2015
ITAD PolSl 2014 - Nowości w .NET 2015Michał Dudak
 
Jak podwoić wartość kodu .NET?
Jak podwoić wartość kodu .NET?Jak podwoić wartość kodu .NET?
Jak podwoić wartość kodu .NET?javOnet
 
Mts 2013 tomasz kopacz - windows 8, office 365, workflow manager, windows a...
Mts 2013   tomasz kopacz - windows 8, office 365, workflow manager, windows a...Mts 2013   tomasz kopacz - windows 8, office 365, workflow manager, windows a...
Mts 2013 tomasz kopacz - windows 8, office 365, workflow manager, windows a...Tomasz Kopacz
 
Xdebug – debugowanie i profilowanie aplikacji PHP
Xdebug – debugowanie i profilowanie aplikacji PHPXdebug – debugowanie i profilowanie aplikacji PHP
Xdebug – debugowanie i profilowanie aplikacji PHP3camp
 
Mts 2013 tomasz kopacz - wydajność aplikacji dla windows 8 - jak ją mierzyć...
Mts 2013   tomasz kopacz - wydajność aplikacji dla windows 8 - jak ją mierzyć...Mts 2013   tomasz kopacz - wydajność aplikacji dla windows 8 - jak ją mierzyć...
Mts 2013 tomasz kopacz - wydajność aplikacji dla windows 8 - jak ją mierzyć...Tomasz Kopacz
 

Similar to Programowanie aplikacji dla Windows 8 (WinRT) (20)

Seminarium - Tworzenie Aplikacji Mobilnych 2004
Seminarium - Tworzenie Aplikacji Mobilnych 2004Seminarium - Tworzenie Aplikacji Mobilnych 2004
Seminarium - Tworzenie Aplikacji Mobilnych 2004
 
Silverlight i PHP - jak budować interfejs nowoczesnych aplikacji internetowych?
Silverlight i PHP - jak budować interfejs nowoczesnych aplikacji internetowych?Silverlight i PHP - jak budować interfejs nowoczesnych aplikacji internetowych?
Silverlight i PHP - jak budować interfejs nowoczesnych aplikacji internetowych?
 
Silverlight i PHP
Silverlight i PHPSilverlight i PHP
Silverlight i PHP
 
Behat
BehatBehat
Behat
 
Aplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxAplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/Redux
 
Jak stworzyć udany system informatyczny
Jak stworzyć udany system informatycznyJak stworzyć udany system informatyczny
Jak stworzyć udany system informatyczny
 
Functional widgets in Rails
Functional widgets in RailsFunctional widgets in Rails
Functional widgets in Rails
 
Współdzielenie kodu aplikacji Windows Phone i Windows 8
Współdzielenie kodu aplikacji Windows Phone i Windows 8Współdzielenie kodu aplikacji Windows Phone i Windows 8
Współdzielenie kodu aplikacji Windows Phone i Windows 8
 
Seminarium .Net CF 2004
Seminarium .Net CF 2004Seminarium .Net CF 2004
Seminarium .Net CF 2004
 
Drobne błędy w portalach WWW -- prawdziwe studium przypadku
Drobne błędy w portalach WWW -- prawdziwe studium przypadkuDrobne błędy w portalach WWW -- prawdziwe studium przypadku
Drobne błędy w portalach WWW -- prawdziwe studium przypadku
 
Bohater UI bez front end developera ?
Bohater UI bez front end developera ?Bohater UI bez front end developera ?
Bohater UI bez front end developera ?
 
Michał Dec - Quality in Clouds
Michał Dec - Quality in CloudsMichał Dec - Quality in Clouds
Michał Dec - Quality in Clouds
 
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychGanymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
 
ITAD PolSl 2014 - Nowości w .NET 2015
ITAD PolSl 2014 - Nowości w .NET 2015ITAD PolSl 2014 - Nowości w .NET 2015
ITAD PolSl 2014 - Nowości w .NET 2015
 
Jak podwoić wartość kodu .NET?
Jak podwoić wartość kodu .NET?Jak podwoić wartość kodu .NET?
Jak podwoić wartość kodu .NET?
 
Responsive Web Design - Michał Rachowski Squiz
Responsive Web Design - Michał Rachowski SquizResponsive Web Design - Michał Rachowski Squiz
Responsive Web Design - Michał Rachowski Squiz
 
Mts 2013 tomasz kopacz - windows 8, office 365, workflow manager, windows a...
Mts 2013   tomasz kopacz - windows 8, office 365, workflow manager, windows a...Mts 2013   tomasz kopacz - windows 8, office 365, workflow manager, windows a...
Mts 2013 tomasz kopacz - windows 8, office 365, workflow manager, windows a...
 
Xdebug – debugowanie i profilowanie aplikacji PHP
Xdebug – debugowanie i profilowanie aplikacji PHPXdebug – debugowanie i profilowanie aplikacji PHP
Xdebug – debugowanie i profilowanie aplikacji PHP
 
Mts 2013 tomasz kopacz - wydajność aplikacji dla windows 8 - jak ją mierzyć...
Mts 2013   tomasz kopacz - wydajność aplikacji dla windows 8 - jak ją mierzyć...Mts 2013   tomasz kopacz - wydajność aplikacji dla windows 8 - jak ją mierzyć...
Mts 2013 tomasz kopacz - wydajność aplikacji dla windows 8 - jak ją mierzyć...
 
Pure MVC - Mediovski
Pure MVC - MediovskiPure MVC - Mediovski
Pure MVC - Mediovski
 

Programowanie aplikacji dla Windows 8 (WinRT)

  • 1.
  • 2. 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
  • 3. MS-DOS Executive, 1985 r.  Niepełny OS – tylko warstwa na MS-DOS
  • 4. Windows 95  Win32 – uzupełnianie granicy między 16-biti 32-bit
  • 5. Hello, world w C++ #include<iostream.h> int main() { cout << "Hello World" << endl; return 0; }
  • 6. 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),
  • 7.
  • 8. 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
  • 9. .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
  • 10.
  • 11. NUI  iPad – 2010 r.  15 milionów urządzeo 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
  • 13. WinRT  W przeciwieostwie 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
  • 14. WinRT
  • 15. 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)
  • 20. Duży zasięg Integracja z przeglądarką Transparentny proces Różne modele biznesowe Wysoki zysk dla programistów Windows Store
  • 21. 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
  • 22. 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)
  • 23. Sideloading - group policy  HKEY_LOCAL_MACHINESoftwarePoliciesMicrosoftWindowsAppx AllowAllTrustedApps = 1
  • 24. Sideloading – c.d.  Wgranie certyfikatu użytego do podpisania aplikacji  PowerShell  import-module appx  add-appxpackage udziałsieciowyapp1.appx  Get-AppxPackage –AllUsers (listuje pakiety)  Remove-AppxPackage Package1  DISM /Online /Add-ProvisionedAppxPackage /PackagePath:C:App1.appx /SkipLicense (przygotowanie obrazu)
  • 25. 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=b809e47cd0110a4db0 43b3f73e83acd917fe1336
  • 26. 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>
  • 28. WinRT API z bliska
  • 29. 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
  • 30. 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
  • 32. HTML 5 i Windows 8
  • 33. Windows 8 – akcelerowana platforma HTML
  • 35. Demo IE 10 i HTML 5, CSS 3
  • 36. WinJS
  • 37. 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ąd weryfikację  $.support.cors = true;  http://api.jquery.com/jQuery.support/
  • 38. 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
  • 39. Wyłączenie zabezpieczeń  toStaticHTML method  DOM creation APIs  WinJS.Utilities.setInnerHTMLUnsafe  msWWA.execUnsafeLocalFunction
  • 42. 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
  • 43.
  • 44. 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 zatrzymad – e.Handled = true
  • 45. Hierarchia klas  Dependency Object (dependency property system)  UIElement (klawiatra, touch, …)  FrameworkElement (layout, loaded / unloaded, binding, style)
  • 46. Dependency Property public static readonly DependencyProperty MyNumberProperty = DependencyProperty.Register( "MyNumber", typeof (int), typeof (MyDependencyObject), new PropertyMetadata(2, OnMyNumberPropertyChange));
  • 47. 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
  • 48. Attached Property public static readonly DependencyProperty IsShareButtonProperty = DependencyProperty.RegisterAttached( "IsShareButton", typeof(Boolean), typeof(MagicButton), new PropertyMetadata(false, new PropertyChangedCallback(Changed)));
  • 50. Bindowanie  POCO  WinRT + BindbleAttribute lub ICustomPropertyProvider <TextBlock Text="{Binding ElementName=Slider, Path=Value}"/> <TextBlock Text="{Binding RelativeSource={RelativeSource Self}, Path=FontSize}"/>
  • 51.
  • 52.
  • 53. Two-way binding  Dependency Properties  INotifyPropertyChanged  Zdarzenie PropertyChanged  Czasem łączenie z CallerMemberName  Model danych nie powinien byd z UI – często konieczna implementacja
  • 54. Binding - inne  Konwertery  Statyczne zasoby  Lokalne  Globalne
  • 55. 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(); }
  • 57. 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
  • 58. Demo
  • 59. 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>
  • 61. Storyboard – c.d.  ColorAnimation  DoubleAnimation  PointAnimation  ObjectAnimationUsingKeyFrames
  • 62. 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
  • 63. Podstawowe kontenery na dane  GridView  ListView  ListBox  FlipView  Źródło danych - CollectionViewSource
  • 64. AppBar <Page.BottomAppBar> <AppBar x:Name="AppBar" Margin="10,0,10,0"> <local:ApplicationCommand x:Name=”AppBarCommands”/> </AppBar> </Page.BottomAppBar>
  • 65. Demo
  • 66. Windows 8 i XAML
  • 67. Wywoływanie kodu natywnego z C# DllImport "avicap32.dll" "capCreateCaptureWindow" static extern int string int int int int int int int DllImport "avicap32.dll" static extern bool int MarshalAs UnmanagedType ref string int MarshalAs UnmanagedType ref string int // więcej i więcej w podobny sposób...
  • 68. ...a w Windows 8 using Windows.Media.Capture; var new CameraCaptureUI new Size var await CameraCaptureUIMode if var new BitmapImage await FileAccessMode
  • 69.  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:WindowsSystem32WinMetadata Projekcje językowe
  • 71. 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
  • 73. .NET i Windows Runtime
  • 74. 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();
  • 75.  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ć
  • 76.  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
  • 77.  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
  • 78.  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
  • 79. Dystrybucja komponentów WinRT  Nie mogą byd dystrybuowane w sklepie samodzielnie  Nie mogą byd współdzielone pomiędzy aplikacjami  Mogą byd sprzedawane developerom
  • 80. Demo Własny komponent WinRT, integracja z HTML
  • 81.  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 DownloadDataAsync ProcessData ProcessDataDownloadData
  • 82. 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
  • 83. 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#
  • 84. Asynchroniczność w C#  Task<T>  async, await  Automatyczna transformacja na callbackową maszynę stanów  Asynchroniczne metody  Oznaczone nowym słowem kluczowym “async”  Muszą zwracad void lub Task<T>  Wykorzystują operator “await” do przekazania kontroli  Wskrzeszane, kiedy operacje zostają zakooczone  Łą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
  • 85.  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
  • 86. Task t, t1, t2 = ... // Task chaining Task 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 t2 Task t4 = t.WhenAll(taskCollection); // Oczekiwanie na zakończenie tasków Task.WaitAll(taskCollection); Task.WaitAny(taskCollection); Taski - łączenie
  • 87. // 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
  • 88.
  • 89.
  • 90. 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>
  • 91. // 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
  • 92. 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
  • 93. 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
  • 97. 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!
  • 98. Zapis stanu - najlepsze praktyki Scenariusz Powinniśmy….
  • 99. 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 ) { } // … }
  • 100. 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
  • 101. 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
  • 103. Podstawowy szablon projektu  SuspensionManager  Zarządzanie stanem aplikacji (lokalny dla stron, globalny)  Serializuje wynik pracy do: %userprofile%appdatalocalpackages...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)
  • 104. 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, ...]
  • 105. 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ę
  • 106. Stan lokalny protected 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); }
  • 108. LayoutAwarePage - nawigacja  GoBack, GoHome, GoForward  Mysz - wstecz / dalej  Klawiatura – wstecz / dalej  Domyślnie – zawsze nowa instancja po back (inaczej niż w WP)  Możliwośd zmiany NavigationCacheMode – zachowanie jak w WP
  • 109. Zarządzanie stanem wizualnym  WindowSizeChanged  Zmiana stanu (filled / snapped, itp.)  Zmiana orientacji ekranu  Visual States  FullScreenLandscape  Filled  FullScreenPortrait  Snapped
  • 111. Środowisko uruchomieniowe i uprawnienia  Paczka aplikacyjna  App Manifest  Blockmap – hashe wszystkich plików  Podpis – sprawdza spójnośd  Model uprawnieo  App Container i System Broker  Capabilities  Permissions  Izolacja procesów
  • 113.  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
  • 114. 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(); }
  • 115. // Parse the JSON data var 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; } }
  • 116. 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 elastycznie MyObject obj = JsonConvert.DeserializeObject<MyObject>(jsonEncodedString);
  • 117.  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()
  • 119.
  • 120.
  • 121.
  • 122. 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 byd powiązane  CollectionViewSource - this.groupedItemsViewSource.View.CollectionGroups;
  • 123. <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 in cvsActivities.Source = result; // Dla zoomout this.groupGridView.ItemsSource = this.cvsActivities.View.CollectionGroups;
  • 127. 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
  • 128. 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); }
  • 129. 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)
  • 130. 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
  • 131. 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));
  • 133. 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 }
  • 134. Długie przetwarzanie  shareOperation.ReportStarted();  Od tego momentu brak interakcji z aplikacją share’ującą  Użytkownik może zamknąd okno share i wrócid do aplikacji  shareOperation.ReportDataRetreived(); (opcja)  Po pobraniu danych z DataPackage  Zgłasza mozliwośd uśpienia / zamknięcia aplikacji źródłowej - optymalizacja  Może byd 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 zakooczenia  Zapisanie quicklinka i (samodzielnie) identyfikatora np. w bazie  shareOperation.ReportError(txt);  Przerwanie operacji, toast + komunikat o błędzie
  • 135. 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)
  • 137. 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
  • 138. 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)
  • 140. 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
  • 141. Ustawienia - kod SettingsPane.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); }
  • 143. Zapisywanie danych  Katalog instalacyjny  App data  Ustawienia lokalne – ApplicationData.Current.LocalSettings  Kontenery - proste grupowanie ustawieo  Composite  ms-appdata://local //roaming //temp  Pliki, sesja – ApplicationData.Current.LocalFolder  User data  Dokumenty, zdjęcia, muzyka, filmy  Roaming
  • 144. 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 byd composite  ApplicationData.Current.SetVersion – aby uniknąd problemów z wersjonowaniem  DataChangedHandler
  • 146. 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, ...
  • 147.
  • 149. 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
  • 150. 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
  • 152. Shareowanie z osobami w pobliżu // Rejestrujemy w klasyczny sposób kontrakt do share’owania function 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; }
  • 153. App To App pickers
  • 154. App To App pickers
  • 156. 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
  • 158. 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
  • 160. 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
  • 161. Execution = Trigger + [Condition] Trigger Condition InternetAvailable, InternetNotAvailable, SessionConnected, SessionDisconnected, UserNotPresent, UserPresent SystemEventTrigger ControlChannelReset # InternetAvailable LockScreenApplicationAdded/Removed NetworkStateChange OnlineIdConnectedStateChange ServicingComplete SessionConnected/Disconnected # SmsReceived TimeZoneChange UserAway/UserPresent # ControlChannelTrigger # (**) TimeTrigger # PushNotificationTrigger # (**) MaintenanceTrigger # wymaga lock permission **może byd in-proc (nie BackgroundTaskHost.exe) „Condition latching” Maintenance trigger – na zasilaniu
  • 162. 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>
  • 163. 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; }
  • 164. Aplikacje, które mogą działad w tle Zwłaszcza aplikacje komunikacyjne (poczta, komunikator, VoIP) Okresowe uruchamianie Uruchamianie kodu w odpowiedzi na zdarzenia systemowe
  • 166.
  • 167. 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 ograniczeo) Dotyczy tylko faktycznej pracy CPU!!!
  • 168. 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
  • 169.
  • 170.
  • 172. 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 aktualizacji Lokalne API Notyfikacje PUSH
  • 173. 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();
  • 175.
  • 177. Secondary Tiles  „Pinowanie” zawartości z wewnątrz aplikacji  Proste wywołanie API  Użytkownik potwierdza (systemowe UI)  Personalizowana przestrzeo aplikacji  Takie same możliwości jak główne kafelki  Tylko lokalne obrazy  Uruchomienie przekierowuje do określonej sekcji aplikacji
  • 178. Demo Live tiles / secondary tiles
  • 179. Notyfikacje Toast  Podobna struktura do kafelków (oparta o szablony)  Różne możliwości wizualne
  • 181. Notyfikacje PUSH - WNS  Zdalne zmiany kafelków i notyfikacje Toast (Internet)  Także, kiedy aplikacja jest wyłączona  Skalowalne, bezpłatne
  • 182. PUSH – schemat działania 1. Żądamy URI kanału PUSH 2. Rejestracja w naszej usłudze 3. Uwierzytelnienie i wysłanie notyfikacji
  • 183. 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
  • 184. 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
  • 186. 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
  • 187. Konwersja z Trial private 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.. } }
  • 188. In-app purchase var 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 } }
  • 191. DPI  System automatycznie przeskalowuje w zależności od DPI  Elementy wektorowe – bez problemu  Grafika – może byd gorsza jakośd
  • 192. 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)
  • 193. Grid i typografia  Jedno z UX Guidelines  Zaprojektowany, aby skalował się bez zaokrągleo
  • 195. 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ęd na podstawie kontrastu, skali, języka  Pierwszeostwo 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
  • 196. • 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
  • 197. 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>
  • 199. Animacje  Animacje  Nowe elementy StoryBoardów  Np. Popin/PopoutAnimation  Content Transitions  Popup  Page  Content Control (kontenery typu Grid, StackPanel, itp.)
  • 201. MVVM – po co?  Separacja warstw  Testowanie  Wsparcie Blend
  • 202. Model-View-ViewModel  Widok  Jak wyświetlid informację?  View Model  Którą informację wyświetlid?  Interakcja, przepływ  Model  Obiekty reprezentujące dane  Logika biznesowa Databinds
  • 204.
  • 205. Problem z class libraries i przenośnością...
  • 206. Portable Class Libraries  Jedno źródło  Jeden projekt  Jeden plik binarny  Wiele platform!
  • 210. Nieco bardziej komplikujemy...  Nawigacja  IoC  Ninject  Autofac  async  ...
  • 212. 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!
  • 213. MvvmCross  Bazuje (już) na Portable Class Libraries  Cross-platformowośd  iOS  Android  Windows Phone  Windows 8  Bazuje na konwencjach (podobnie jak Caliburn.micro)
  • 215. Debugowanie komponentów WinRT  Nie można debugowad jednocześnie kodu JS i managed (np. komponent)
  • 216. WinMD i managed code  Ildasm /project – włączenie adaptera  Bez tego – widzimy jak zapisane na dysku  Z parametrem project – widzimy tak jak widzi CLR
  • 217. Typy WinRT Kategoria Przykład Standard WinRT types Windows.Foundation.Collections.PropertySet, Windows.Networking.Sockets.DatagramSocket Primitive types Byte, Int32, String, Object Projected types Windows.Foundation.Uri, Windows.Foundation.DateTime Projected interfaces Windows.Foundation.Collections.IVector<T>, Windows.Foundation.Iclosable Types with .NET helpers Windows.Storage.Streams.IInputStream, Windows.Foundation.IasyncInfo