speakers 이길복 mvp 휴즈플로우 cto 주신영 mvp 스마트쉐어 ceo windows 8.1: free for...

Post on 16-Dec-2015

217 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

윈도우 8.1 앱개발새로운 API 들

이길복 / 주신영

Speakers

이길복 MVP휴즈플로우 CTO

주신영 MVP스마트쉐어 CEO

Windows 8.1: Free for all Windows 8 PCs

1

TextBlock<TextBlock Text="First line is using the defaults" />

<TextBlock Text="Second line"

FontSize="40" FontWeight="Bold" FontStyle="Italic"

FontFamily="Times New Roman"/>

<TextBlock Text="I will not be able to finish this sentence."

FontSize="30" HorizontalAlignment="Left" TextTrimming="WordEllipsis"

Width="450" />

<TextBlock Text="1/4, 1/2, 1/3, 3263827/8675309"

FontSize="40" TextAlignment="Right" Typography.Fraction="Slashed"/>

<TextBlock Text="Microsoft Windows"

FontSize="60" FontFamily="Gabriola" Foreground="Aqua"

Typography.StylisticSet4="True"/>

<TextBlock Text="Microsoft Windows"

FontSize="60" FontFamily="Gabriola"

Typography.StylisticSet5="True"/>

<TextBlock Text="Microsoft Windows"

FontSize="60" FontFamily="Gabriola" Foreground="LightGreen"

Typography.StylisticSet6="True"/>

<TextBlock Text="Microsoft Windows"

FontSize="60" Foreground="#FFAA00FF" FontFamily="Gabriola"

Typography.StylisticSet7="True"/>

RichTextBlock<RichTextBlock OverflowContentTarget="{Binding ElementName=SecondColumnOverflow}" FontSize="25" Grid.Column="0" Margin="5"> <Paragraph TextAlignment="Justify" Margin="5"> This is justified text. Lorem ipsum dolor sit amet, consectetur … </Paragraph> <Paragraph> <Hyperlink NavigateUri="http://microsoft.com" FontSize="25">Link to Microsoft Main Site</Hyperlink> </Paragraph> <Paragraph TextAlignment="Right" Margin="5"> This is right-justified text. Integer hendrerit diam vitae …. <InlineUIContainer> <Button Content="Button" Width="120" Height="40" /> </InlineUIContainer> <Run Foreground="LightBlue"> And so is this. Class aptent taciti sociosqu ad … </Run> </Paragraph> <Paragraph TextAlignment="Center" Margin="5"> This is centered text. Duis vel semper augue... <Run Text="This is some text in its own run, using its own text style" FontStyle="Italic" Foreground="Orange"/> This is also centered. In commodo eros … </Paragraph></RichTextBlock>

<RichTextBlockOverflow x:Name="SecondColumnOverflow" Grid.Column="1" Margin="5"/>

TextBox and PasswordBox

<TextBox Text="Hello world" /> <TextBox Text="Headers can be templated" Header="TextBox Header Text"/>

<TextBox Text="I am going to the store for moar bread." Header="Spell-checking" IsSpellCheckEnabled="True"/>

<TextBox Header="Placeholder text" PlaceholderText="please enter your first name"/>

<TextBox Header="Color Font Support" Text="I like tapioca. &#x1F600;" IsColorFontEnabled="True" FontFamily="Segoe UI Emoji" />

<TextBox Text="For on-screen keyboards only" Header="Text Prediction" IsTextPredictionEnabled="True"/> <TextBox Text="pete@contoso.com" Header="Input scope control" PlaceholderText="For touch keyboard" InputScope="EmailSmtpAddress"/>

<TextBox Text="Peter piper picked a peck" Header="Selection highlight color control" SelectionHighlightColor="Orange"/>

<PasswordBox Header="Please enter your password" FontSize="40" Margin="20" IsPasswordRevealButtonEnabled="True" Password="Password1" />

<TextBox InputScope="EmailSmtpAddress"/>

<TextBox InputScope="Formula"/>

<TextBox InputScope="Number"/>

Input scope키보드 레이아웃 결정 .

데이터 검증까지 제공하진 않음 .

좋은 UX 에 도움되는 것은 알지만 , 설정하는 것을 잊기 쉬운데…타블렛과 터치스크린 사용자들을 위해서 꼭 신경써줘야 할 것 .

DatePicker and TimePicker

<DatePicker Header="Gregorian Calendar Identifier" CalendarIdentifier="GregorianCalendar" DayFormat="{}{day.integer} {dayofweek.full}" />

<DatePicker Header="Korean Calendar Identifier" CalendarIdentifier="KoreanCalendar" DayFormat="{}{day.integer} {dayofweek.full}" />

<DatePicker Header="Julian Calendar Identifier" CalendarIdentifier="JulianCalendar" DayFormat="{}{day.integer} {dayofweek.full}" />

<DatePicker Header="Day of week without day" DayFormat="{}{dayofweek.solo.full}" />

<DatePicker Header="Day of week abbreviated" DayFormat="{}{day.integer} {dayofweek.abbreviated}" />

<TimePicker Header="Time Picker with 12 hour clock" ClockIdentifier="12HourClock" />

<TimePicker Header="Time Picker with 24 hour clock" ClockIdentifier="24HourClock" />

Date

Pick

er

Tim

ePi

cke

r

Flyouts

<Button Content="Show Normal Flyout" Margin="100, 20, 100, 20"> <Button.Flyout> <Flyout> <StackPanel Width="250"> <TextBlock Text="Some header text" FontSize="24" Margin="0,0,0,20" FontWeight="Light" Foreground="CornflowerBlue"/> <TextBlock Text="This type of flyout is a ..." FontSize="16" TextWrapping="Wrap" /> <Button Content="Do Something" HorizontalAlignment="Right" Margin="0,20,0,0"/> </StackPanel> </Flyout> </Button.Flyout></Button>

<Button Content="Show Menu Flyout" Margin="20, 20, 100, 20"> <Button.Flyout> <MenuFlyout> <MenuFlyoutItem Text="Option 1" /> <MenuFlyoutItem Text="Option 2" /> <MenuFlyoutSeparator /> <ToggleMenuFlyoutItem Text="Toggle Option 1" IsChecked="True" /> <ToggleMenuFlyoutItem Text="Toggle Option 2" /> </MenuFlyout> </Button.Flyout></Button>

AppBar

Image

<TextBlock Text="UI Resize" FontSize="30" />

<Image Source="ms-appx:///Assets/Images/Pro2.png"

Width="400"/>

<TextBlock Text="Decode Resize" FontSize="30" />

<Image Width="400">

<Image.Source>

<BitmapImage DecodePixelWidth="600"

UriSource="ms-appx:///Assets/Images/Pro2.png" />

</Image.Source>

</Image>

DecodePixelWidth/Height불러올 때 크기를 제공하면 메모리를 절약할 수 있다 . 퍼포먼스도 좋아진다 . 확대 / 축소된 결과도 더 품질이 좋다 .

2

ChineseFrenchGermanIndianItalianMexican

DataData template

ListView

<ListView x:Name="ItemListView"

Height="325"

HorizontalAlignment="Left"

ItemTemplate="{StaticResource StoreFrontTileTemplate}"

ItemContainerStyle="{StaticResource ContainerStyle}"

ShowsScrollingPlaceholders="False"

BorderBrush="LightGray"

BorderThickness="1"

SelectionMode="None"/>

GridView

<GridView x:Name="ItemGridView2"

ItemTemplate="{StaticResource StoreFrontTileTemplate}"

ItemContainerStyle="{StaticResource StoreFrontTileStyle}"

ItemsPanel="{StaticResource StoreFrontGridItemsPanelTemplate}"

ShowsScrollingPlaceholders="False"

BorderBrush="LightGray"

BorderThickness="1" />

<FlipView x:Name="FlipView1" Width="480" Height="270"

BorderBrush="Black" BorderThickness="1">

<FlipView.ItemTemplate>

<DataTemplate>

<Grid>

<Image Width="480" Height="270" Source="{Binding Image}"

Stretch="UniformToFill"/>

<Border Background="#A5000000" Height="80" VerticalAlignment="Bottom">

<TextBlock Text="{Binding Title}" FontFamily="Segoe UI"

FontSize="26.667" Foreground="#CCFFFFFF"

Padding="15,20"/>

</Border>

</Grid>

</DataTemplate>

</FlipView.ItemTemplate>

</FlipView>

Data

Tem

pla

te

FlipView

DataContext for binding is the item being ren-dered

Panning perf overview – UI virtualization

Panning perf overview – UI virtualization

8

8.1

가상화 불가

새 가상화는 기본으로 활성화 되어있음 .ItemsStackPanel 과 ItemsWrapGrid

가변사이즈 아이템을 지원할 때는 가상화 불가 .같은 크기에 , 같은 템플릿을 사용하는 경우에만 가상화 작동 .VariableSizedWrapGrid 는 가상화 불가

가상화 가능

가상화 불가

Large list performance

<GridViewItemPresenter SelectionCheckMarkVisualEnabled="False" SelectedBackground="#FFFF8c00" SelectedBorderThickness="5" />

+ =

퍼포먼스 개선불필요한 엘리먼트의 생성을 줄이기 .GridViewItemPresenter 의 사용 .

<GridView ShowsScrollingPlaceholders="true">

Placeholders 로 가시적인 퍼포먼스 개선

Incrementally updating the data tem-plate

GridView 의 ContainerContentChanging이벤트

3

Windows 8 view states

Full landscape

FilledSnapped

Full portrait

Windows in Windows 8.1

Wider than tall window

Taller than wide win-

dow

Taller than wide win-

dowTaller than wide

window

Windows 8.1 접근

앱은 최소 500px 폭을 지원해야함 .세로로 긴 레이아웃을 지원할 것 .

320px 에서 499px 는 선택적으로 지원

Page 기초 클래스나 View State 를 더 이상 지원 안 함 .이제 좋은 툴킷을 맘대로 쓰고 개발자 마음대로 하세용

동시에 두 개 이상의 앱을 지원대형화면은 앱을 다섯 개까지 ! 보통은 두 , 세 가지 .

App-specific visual states

<VisualStateManager.VisualStateGroups>

<VisualStateGroup>

<VisualState x:Name="PrimaryLayout">

<Storyboard> ... </Storyboard>

</VisualState>

<VisualState x:Name="NarrowLayout">

<Storyboard> ... </Storyboard>

</VisualState>

<VisualState x:Name="TallLayout">

<Storyboard> ... </Storyboard>

</VisualState>

<VisualState x:Name="ExtraLargeLayout">

<Storyboard> ... </Storyboard>

</VisualState>

</VisualStateGroup>

</VisualStateManager.VisualStateGroups>

Visual States

Visual states 는 UI 와 코드를 분리해 주죠 .

코드에서 수동으로 엘리먼트 이동하고 , 크기변경하고 하는 대신에 간단히 이 변경사항들을 처리하는 Storyboard 를 가진 visual state 로 변경하는 게 깔끔하죠 .

Setting visual states from code

const string _primaryVS = "PrimaryLayout";

const string _narrowVS = "NarrowLayout";

const string _tallVS = "TallLayout";

const string _xlVS = "ExtraLargeLayout";

const double _minPrimaryWidth = 500.0;

const double _maxPrimaryWidth = 1920.0;

const double _maxPrimaryHeight = 1080.0;

Use constantsSizes and state names will almost certainly change during design iterations

void OnWindowSizeChanged(object sender, WindowSizeChangedEventArgs e){ if (e.Size.Width < _minPrimaryWidth) VisualStateManager.GoToState(this, _narrowVS, true);

else if (e.Size.Width < e.Size.Height) VisualStateManager.GoToState(this, _tallVS, true);

else if (e.Size.Width > _maxPrimaryWidth && e.Size.Width > _maxPrimaryWidth) VisualStateManager.GoToState(this, _xlVS, true);

else VisualStateManager.GoToState(this, _primaryVS, true);}

방향과 위치

OrientationApplicationView.Orientation (Landscape 또는 Portrait 을 반환 )

PlacementApplicationView.AdjacentToLeftDisplayEdgeApplicationView.AdjacentToRightDisplayEdge

Full ScreenApplicationView.IsFullScreen

Window 크기

페이지 불러올 때 창크기Window.Current.Bounds : 초기 크기

런타임 사이즈는 Window.SizeChanged 이벤트 핸들러에서페이지가 사라질 때는 핸들러를 끊어주는 센스 !

Window 크기와 실제 화면 사이즈와는 아무 관계 없음 !전체화면일 때조차도 픽셀은 논리적 픽셀수 .

Handling the SizeChanged event

protected override void OnNavigatedTo(NavigationEventArgs e)

{

navigationHelper.OnNavigatedTo(e);

Window.Current.SizeChanged += OnWindowSizeChanged;

}

protected override void OnNavigatedFrom(NavigationEventArgs e)

{

navigationHelper.OnNavigatedFrom(e);

Window.Current.SizeChanged -= OnWindowSizeChanged;

}

핸들러 제거하는 것 잊지 마세요 !팁 : 모든 닷넷 프로그램에서 메모리 누수가 발생하는 흔한 원인 중 하나가 제대로 이벤트 핸들러를 제거하지 않는 것이다 . 싱글턴 객체나 정적 클래스의 이벤트에 대한 핸들러는 꼭 제거합시다 .

Show

Cre

-ate

Setu

p w

indow

conte

nt

Show a secondary view

var view = CoreApplication.CreateNewView();

var viewId = 0;

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

{

viewId = ApplicationView.GetForCurrentView().Id;

var window = Window.Current;

var frame = new Frame();

window.Content = frame;

frame.Navigate(typeof(SecondaryWindowContentPage));

});

await ApplicationViewSwitcher.TryShowAsStandaloneAsync(viewId,

ViewSizePreference.UseHalf,

ApplicationView.GetForCurrentView().Id,

ViewSizePreference.UseHalf);

ViewSizePrefer-ence

Default기본값은 UseHalf 와 같은 절반 .

UseMore가로 50% 이상을 차지

UseHalf절반

UseLess가로 50% 이하를 차지

UseMinimumManifest 에 정해 놓은 최소값인320 또는 500 픽셀

UseNone보여주지 않음

4Speech Synthesis

Speech synthesis

Voice

David(en-US, 남성 )

Zira(en-US, 여성 )

Hazel(en-UK, 여성 )

Heami(ko-KR, 여성 )

외 13 개국 음성 지원

Code

Speech synthesis

단순 텍스트 음성 출력 synthesizeTextToStreamAsync

PC 의 위치 설정에 따라 음성 지원

var synth = new Windows.Media.SpeechSynthesis.SpeechSynthe-sizer();

SpeechSynthesisStream stream = await synth.SynthesizeText-ToStreamAsync("Welcome!");

media.SetSource(stream, stream.ContentType); media.Play();

Speech synthesis

SSML(Speech Synthesis Markup Lan-

guage) synthesizeSsmlToStreamAsync

음성 특징 , 발음 , 볼륨 , 피치 , 비율 / 속도 , 강도Code

string Ssml = @"<speak version='1.0' " + "xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='en-US'>" + "<prosody contour='(0%,+80Hz) (10%,+80%) (40%,+80Hz)'>Welcome! Shinyoung" + "<break time='500ms' />" + "Have a good time" + "</prosody></speak>";

var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer(); SpeechSynthesisStream stream = await synth.SynthesizeSsmlToStrea-mAsync(Ssml);

media.SetSource(stream, stream.ContentType); media.Play();

5Contact &Appointment

Contact

People 앱을 통한 연락처 관리 이메일 및 소셜 계정의 연락처 연동됨 모든 연락처의 추가 / 수정 / 삭제

ContactPickerUI 를 통한 연락처들 호출 ContactManager.ShowContactCard() 를

통해 바로 원하는 연락처의 ContactCard 를 호출

대부분의 사용자는 개인정보 유출에 대한 우려로 앱 자체에서 연락처정보의 관리 / 보호 / 저장 하는 것을 원하지 않음 .

Contact Picker

Appxmanifest 에서 Contact Picker 사용 선언

Contact Picker

Code

ContactPicker picker = new ContactPicker();

picker.SelectionMode = ContactSelectionMode.Contacts;// Contact contacts = await picker.PickContactAsync(); // 1 개

IList<Contact> contacts = await picker.PickContactsAsync(); // 여러개foreach (Contact contact in contacts){

// process each contact returnedDebug.WriteLine(contact.FirstName + " " +

contact.LastName);}ContactPickerUI 로 UI 를 커스텀 가능

Contact cardContact card workflow

View Profile

ContactManager

Source App Target App

From: Ben Miller

Windows Contact Store

Windows Runtime

Action + Object

ContactManager

Code

Contact contact = new Contact();contact.FirstName = " 주 ";contact.LastName = " 신영 ";

ContactEmail email = new ContactEmail();email.Address = “bit1010@live.com";contact.Emails.Add(email);

Rect rect = Helper.GetElementRect(sender as FrameworkElement);ContactManager.ShowContactCard(contact, rect, Windows.UI.Popups.-Placement.Default);

Appointments

Calrendar 앱을 통한 일정 관리

이메일 및 소셜 계정의 일정 연동됨

모든 일정의 추가 / 수정 / 삭제

AppointmentManager. ShowAddAp-

pointmentAsync(…) 를 통해 바로 원하는 일정

ContactCard 를 호출

Appointments

Source App Target App

Windows Appointment

Store

Windows Runtime

Action + Object

AppointmentManager. ShowAddAppointmentAsync(…)

AppointmentsCode

private async void AddAppointment_Click(object sender, RoutedEventArgs e) { var appointment = new Appointment();

appointment.Subject = "Prepare for next session"; appointment.StartTime = DateTime.Now.AddMinutes(2); appointment.Duration = TimeSpan.FromHours(1); appointment.Location = "Speaker room"; appointment.Uri = new Uri("http://dev.windows.com"); appointment.Sensitivity = AppointmentSensitivity.Public; appointment.Details = "Nothing like a little procrastination!";

AppointmentsCode

Rect rect = Helper.GetElementRect(sender as FrameworkElement);

var id = await AppointmentManager.ShowAddAppointmentAsync( appointment, rect, Windows.UI.Popups.Placement.Above);

if (!string.IsNullOrEmpty(id)) ResultDisplay.Text = "Returned appointment id " + id; else ResultDisplay.Text = "Appointment not added."; } }

Contact &Appointment

demo

6

Bluetooth in Windows 8.1

RFCOMM

• General device control• Robots• Sphero• Netduino• Gadgeteer• More…

GATT

• Custom and low-power devices• Smart watches• Health monitors• Fitness monitors• Home automation• More…

Windows 8.1 PC running your Windows Store app

Windows.Devices.Bluetooth.RfcommWindows.Devices.Bluetooth.GenericAt-

tributeProfile

Bluetooth Pairing

Bluetooth RFCOMM: Connection Windows.Devices.Bluetooth.RfcommDeviceService _service;Windows.Networking.Sockets.StreamSocket _socket;

async void Initialize(){ // Enumerate devices with the object push service DeviceInformationCollection _DICollection = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync( RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));

if (_DICollection.Count > 0) { // Typically, check protection level and version compatibility here

// Initialize the target Bluetooth device _service = await RfcommDeviceService.FromIdAsync(services[0].Id);

// Create a standard networking socket and connect to the target _socket = new StreamSocket();

await _socket.ConnectAsync(_service.ConnectionHostName, _service.ConnectionServiceName, SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication);

// The socket is connected. Data transfer happens using standard WinRT Sockets API }}

Bluetooth RFCOMM: receiving data

Socket..

StreamSocketListener socketListener = new StreamSocketListener();….

DataReader reader = new DataReader(socket.InputStream);

// Read the message.uint messageLength = reader.ReadByte();// Loads data from the input stream.uint actualMessageLength = await reader.LoadAsync(messageLength);

// Reads a string value from the input stream.string message = reader.ReadString(actualMessageLength);

…..

Package.appxmanifest 중요 !

Bluetooth

demo

7

Industry-leading economics

Starts at 70%for new apps

Jumps to 80%once your app makes $25,000

Developer registration

$19 Individual

$99 Business

Registration cov-ers both Win-dows and Win-dows Phone

Trials

Simple time-based trials

/* No code*/

Initialize the license

private void InitializeLicense()

{

#if DEBUG

// debug license information

licenseInformation = CurrentAppSimulator.LicenseInformation;

#else

// release license information

licenseInformation = CurrentApp.LicenseInformation;

#endif

}

Use the right license providerWinRT provides the CurrentAppSimulator for testing trial mode, in-app purchases, and more without your app being listed in the Windows Store. CurrentApp is for submission to the Windows Store. You cannot submit an app which uses CurrentAppSimulator.

Handle license events

...

licenseInformation.LicenseChanged += new LicenseChangedEventHandler(OnLicenseChanged);

private void OnLicenseChanged()

{

if (licenseInformation.IsActive)

{

if (licenseInformation.IsTrial)

{

// Show the features that are available during trial.

}

else

{

// Show the features that are available only with a full license.

}

}

else

{

// A license is inactive only when there's an error.

}

}

Conditionally enable features

private void EnableFeatures()

{

if (licenseInformation.IsActive)

{

if (licenseInformation.IsTrial)

{

// trial mode. You decide if you should inform the user that the

// feature is not available, or simply not enable the UI for the feature

}

else

{

// enable feature ...

}

}

}

Hide or inform?You may find that providing a UI with a warning that the feature is only enabled in the full version is a better approach than simply hiding the feature. Whenever you prompt, be sure to give the user the option to purchase right then.

Trial

demo

Thank you!

top related