2020년은 오프라인 비지니스 환경에서 언텍트 비지니스 환경으로 변화하는 변곡점이라고 있을 같습니다. 그에 따라 이제는 PC 뿐만 아니라 다양한 모바일 디바이스에서 실행되는 크로스플랫폼 개발 환경이 더욱더 발전을 것이라고 생각됩니다.

 

2018 5 최초로 공개된 Uno Platform 크로스 플랫폼에서 실행되는 비지니스 응용 프로그램을 개발하는 가장  빠른 방법이라고 생각하며, 포스트에서 Microsoft Contoso UWP앱을 Uno Platform Prism으로 포팅할 참고할 사항이나 필요한 기술에 대해서 이야기를 하려고 합니다. Uno Platform 대한 자세한 사항은 여기 참고하시기 바랍니다.

 

Contoso UWP app

https://github.com/microsoft/Windows-appsample-customers-orders-database

UnoContoso app – Uno Platform

Uno.Samples/UI/UnoContoso at master · unoplatform/Uno.Samples (github.com)

 

포팅시 어려웠던 부분?

  1. Entity Framework Core 버전이 2.1에서 3.x 버전으로 변경되면서 발생한 문제를 해결하는데  시간이 오래 걸렸습니다. 변경 사항은 여기 참고하시기 바랍니다.
  2. Sqlite Entity Framework Core 이용해서 앱에서 직접 접근해서 사용하는 방식이 Wasm, iOS, macOS 등에서 원활하지 않아서, Web API 통해서만 사용할 있도록 수정하는데 시간이 걸렸습니다.
  3. Contoso UWP앱이 Event-driven 방식을 사용하고 있어서, 부분을 MVVM Pattern으로 변경하는 부분도 시간이 걸렸습니다.

프로젝트에 대한 간단한 설명

  • UnoContoso.Droid : 안드로이드 해더 프로젝트
  • UnoContoso.iOS : iOS 헤더 프로젝트
  • UnoContoso.macOS : macOS 헤더 프로젝트
  • UnoContoso.Uwp : Uwp 헤더 프로젝트
  • UnoContoso.Wasm : Wasm 헤더 프로젝트
  • UnoContoso.Models : 모델 프로젝트, .NET Standard 2.0
  • UnoContoso.Repository : 레파지토리 프로젝트, .NET Standard 2.0
  • UnoContoso.Service : 서비스 프로젝트, .NET Core 3.1
  • UnoContoso.Shared : 공유 프로젝트

Tips

  • NavigationView
    • AlwaysShowHeader=”False” :상단에 헤더를 표시하지 않습니다. 헤더를 표시하는 보다 표시 하지 않는 것이 아래의 이유로 인해서 개발이 용이 합니다.
      • iOS 경우 헤더의 위치가 다른 플랫폼과 다르게 위로 올라가서 표시됩니다.
      • Windows, Wasm, macOS에서는 헤더 위치에 CommandBar 표시하고, Android, iOS에서는 화면 하단에 표시하기 때문에, NavigationView.HeaderTemplate 사용이 어렵습니다.
    • NavigationViewBehavior : NavigationView 표시되는 메뉴를 동적으로 구현하고, 선택된 Menu ViewModel 바인딩하기 위해서 Behavior 만들었습니다. Behavior 일반적인 사항은 여기 참고하시기 바랍니다.
    • ContentControl : Prism에서 일반적으로 Region 지정하는 컨트롤입니다. 컨트롤을 통해서 View 네비게이션 됩니다. 자세한 사항은 Prism RegionNavigation 참고하시기 바랍니다.
      • 컨트롤의 Padding 화면의 기본 Margin입니다.
      • iOS 경우 ios:Padding=”10,20,0,0” 사용해야 합니다.
<!--Code1-->
        <NavigationView
            IsBackButtonVisible="Collapsed"
            OpenPaneLength="160"
            IsSettingsVisible="False"
            AlwaysShowHeader="False"
            IsTabStop="False">
            <i:Interaction.Behaviors>
                <behaviors:NavigationViewBehavior 
                    MenuItems="{Binding Menus}"
                    SelectedMenuItem="{Binding SelectedItem, Mode=TwoWay}"/>
            </i:Interaction.Behaviors>
            <ContentControl 
                prismRegions:RegionManager.RegionName="ContentRegion" 
				HorizontalContentAlignment="Stretch"
				VerticalContentAlignment="Stretch"
                not_ios:Padding="10,0,0,0"
                ios:Padding="10,20,0,0"/>
        </NavigationView>
  • x:Bind
    • Android iOS 앱의 성능 향상을 위해서 x:Bind 주로 사용했습니다.
    • x:Bind 사용하기 위해서 code behind에서ViewModel이라는 프로퍼티를 추가합니다. (Code2-1)
    • x:Bind 기본 mode OneTime입니다. 그래서, 프로퍼티의 데이터가 변경되는 곳이라면 mode=OneWay 반드시 추가해야 합니다.
    • 컨트롤의 이벤트와 뷰모델의 메소드를 x:Bind 직접 연결하는 방법은 사용할 없습니다.
    • IValueConverter 이용하는 경우 Android에서  x:Bind 사용할 없기 때문에, Binding 사용합니다. (Code2-2)
//Code2-1
public CustomerListViewModel ViewModel
{
    get { return DataContext as CustomerListViewModel; }
}
<!--Code2-2-->
                <TextBlock
                    Grid.Column="0"
                    Margin="0" Padding="0"
                    Text="{x:Bind Product.Name}" />
                <TextBlock
                    Grid.Column="2"
                    Margin="0" Padding="0"
                    HorizontalAlignment="Right"
                    Text="{Binding Product.ListPrice,
                        Converter={StaticResource StringFormatConverter},
                        ConverterParameter='{}{0:n}'}" />
  • Prism
    • View ViewModel 자동으로 연결해 줍니다. prismMvvm:ViewModelLocator.AutowireViewModel="True" 코드를 참고 합니다. 자세한 사항은 여기를 참고 합니다.(Code3-1)
    • RegionNavigation 사용하기 위해서는 App.xaml.cs → void RegisterTypes() 메소드에 RegisterForNavigation 이용해서 등록해야 합니다. (Code3-2)
    • DialogService 사용하는 화면은 View ViewModel 수동으로 연결 합니다. App.xaml.cs -} void RegisterTypes() 메소드에 있는 코드를 참고 합니다.   자세한 사항은 여기 참고 합니다. (Code3-3)
    • DelegateCommand ObservesProperty 이용하면, Command 사용여부를 쉽게 변경할 있습니다. 자세한 사항은 여기 참고 합니다. (Code3-4)
    • EventAggregator 이용하면 뷰모델과 뷰모델 사이에 커뮤니케이션을 있습니다. 이는 Loosely Coupled 연결입니다. 자세한 사항은 여기 참고 합니다. (Code3-5)
<!--Code3-1-->
<UserControl
    x:Class="UnoContoso.Views.OrderDetailView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:UnoContoso.Views"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:i="using:Microsoft.Xaml.Interactivity" 
    xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
    xmlns:toolkit="using:Microsoft.Toolkit.Uwp.UI.Controls"
    xmlns:prismMvvm="using:Prism.Mvvm" 
    prismMvvm:ViewModelLocator.AutowireViewModel="True"
    xmlns:uc="using:UnoContoso.UserControls" 
    xmlns:stateTriggers="using:UnoContoso.StateTriggers" 
    xmlns:models="using:UnoContoso.Models" 
    x:Name="Root"
    mc:Ignorable="d">
//Code3-2
containerRegistry.RegisterForNavigation<CustomerListView>();
containerRegistry.RegisterForNavigation<CustomerDetailView>();
containerRegistry.RegisterForNavigation<HomeView>();
containerRegistry.RegisterForNavigation<OrderListView>();
containerRegistry.RegisterForNavigation<OrderDetailView>();
//Code3-3
containerRegistry.RegisterDialog<MessageControl, MessageViewModel>();
containerRegistry.RegisterDialog<ConfirmControl, ConfirmViewModel>();
//Code3-4
            ViewDetailCommand = new DelegateCommand(OnViewDetail,
                () => SelectedCustomer != null)
                .ObservesProperty(() => SelectedCustomer);
//Code3-5
Step 1. CustomerListViewModel.cs
            EventAggregator.GetEvent<CustomerEvent>()
                .Subscribe(ReceivedCustomerEvnet, false);

Step 2. CustomerDetailViewModel.cs
            EventAggregator.GetEvent<CustomerEvent>()
                .Publish(new EventArgs.CustomerEventArgs 
                { 
                    Changes = change,
                    Customer = Customer.Model
                });
                
Step 3. CustomerListViewModel.cs
        private void ReceivedCustomerEvnet(CustomerEventArgs obj)
        {
            switch (obj.Changes)
            {
                case Enums.EntityChanges.None:
                    break;
                case Enums.EntityChanges.Changed:
                    {
                        var customer = _allCustomers
                            .FirstOrDefault(c => c.Model.Id == obj.Customer.Id);
                        if (customer == null) return;
                        customer.Model = obj.Customer;
                        customer.UpdateProperty();
                    }
                    break;
                case Enums.EntityChanges.Added:
                    {
                        var customer = new CustomerWrapper(_contosoRepository, obj.Customer);
                        _allCustomers.Add(customer);
                    }
                    break;
                case Enums.EntityChanges.Deleted:
                    {
                        var customer = _allCustomers
                            .FirstOrDefault(c => c.Model.Id == obj.Customer.Id);
                        if (customer == null) return;
                        _allCustomers.Remove(customer);
                    }
                    break;
            }
        }
  • RelativePanel
    • 컨트롤을 관계에 의해 배치 합니다. 자세한 사항은 여기 참고 하시기 바랍니다.
    • VisualState 이용해서 상단에 위치한 CommandBar 위치를 하단으로 변경할 CommandBar 컨트롤에 RelativePanel.LeftOf RelativePanel.RightOf 입력되어있는 이름을 지워주어야 하단으로 이동이 가능합니다. 부분은 UWP에서의 동작과는 다르게 동작합니다.
<!--Code4-->
<VisualState>
  <VisualState.StateTriggers>
    <stateTriggers:MobileScreenTrigger />
  </VisualState.StateTriggers>
  <VisualState.Setters>
    <Setter Target="mainCommandBar.(RelativePanel.AlignBottomWithPanel)" Value="True" />
    <Setter Target="mainCommandBar.(RelativePanel.AlignLeftWithPanel)" Value="True" />
    <Setter Target="mainCommandBar.(RelativePanel.AlignRightWithPanel)" Value="True" />
    <Setter Target="mainCommandBar.(RelativePanel.LeftOf)" Value="" />
    <Setter Target="mainCommandBar.(RelativePanel.RightOf)" Value="" />
    <Setter Target="mainCommandBar.HorizontalAlignment" Value="Stretch" />
    <Setter Target="PageTitle.Margin" Value="30,4,0,0"/>
    <Setter Target="CustomerSearchBox.Width" Value="240" />
    <Setter Target="RootDataGrid.Margin" Value="0,10,0,40" />
    <Setter Target="CustomerListMobileView.Visibility" Value="Visible"/>
    <Setter Target="CustomerDataGrid.Visibility" Value="Collapsed"/>
  </VisualState.Setters>
</VisualState>
  • CommandBar
    • 커맨드 버튼을 배치하는 컨트롤 입니다. 기본적인 사항은 여기 참고하시기 바랍니다.
    • CommandBarBehavior 크기가 변하면 DefaultLabelPosition Right에서 Bottom으로 이동 시키기 위해서 추가한 Behavior입니다.
    • DefaultLabelPosition 프로퍼티가 Uno에서 미구현 프로퍼티이기 때문에, 대부분의 플랫폼에서는 기본값 Bottm 가지고 있습니다.
<!--Code5-->
            <CommandBar 
                x:Name="mainCommandBar"
                Background="White"
                HorizontalAlignment="Right"
                DefaultLabelPosition="Right"
                RelativePanel.LeftOf="CustomerSearchBox"
                RelativePanel.RightOf="PageTitle">
                <i:Interaction.Behaviors>
                    <behaviors:CommandBarBehavior/>
                </i:Interaction.Behaviors>
                <AppBarButton
                    Icon="Contact"
                    Label="View details"
                    ToolTipService.ToolTip="View details" 
                    Command="{x:Bind ViewModel.ViewDetailCommand}"/>
                <!--skip lines-->
                <AppBarButton
                    Icon="Refresh"
                    Label="Sync"
                    ToolTipService.ToolTip="Sync with server" 
                    Command="{x:Bind ViewModel.SyncCommand}"/>
            </CommandBar>
  • CollapsibleSearchBox
    • UserControl 이용해서 만든 검색용 컨트롤입니다.
    • Uno에서 그래픽 아이콘은 SymbolIcon 컨트롤을 이용해야, 플랫폼에서도 정상적으로 아이콘이 출력됩니다.
<!--Code6-->
        <ToggleButton
            x:Name="searchButton"
            HorizontalAlignment="Right"
            VerticalAlignment="Top"
            Background="Transparent"
            Checked="SearchButton_Checked"
            Visibility="Collapsed"
            Padding="4">
            <SymbolIcon Symbol="Find" />
        </ToggleButton>
  • ListView
    • 모바일 디바이스에서는 화면에 출력되는 항목의 갯수와 가로 스크롤바의 유무에 따라서 세로 스크롤 성능에 영향을 미치기 때문에 DataGrid보다는 ListView 이용하는 것이 좋습니다. 자세한 사항은 여기 참고 합니다.
    • macOS에서는 아직 DataGrid 사용할 없기 때문에 ListView 사용합니다. 하지만, macOS ListView 컨트롤 내부에 ScrollView 없기 때문에 세로 스크롤이 불가능한 것으로 보입니다. macOS 지원은 점점 추가될 것으로 생각합니다.
  • DataGrid
    • Data Grid 형태로 보여주며, 수정도 가능한 컨트롤이며, Windows Community Toolkit 설치해야 사용할 있습니다. 자세한 사항은 여기 참고 합니다.
    • DataGridBehavior Sort기능과 마우스 오른쪽 버튼을 지원하기 위해서 만들었습니다.
    • 컬럼에 프로퍼티를 바인딩 할때 x:Bind 사용할 없습니다.
<!--Code7-->
<toolkit:DataGrid
    x:Name="OrderListDataGrid" BorderThickness="0" 
    CanUserReorderColumns="False" CanUserResizeColumns="False"
    GridLinesVisibility="None" IsReadOnly="True"
    AutoGenerateColumns="False" Margin="0,10,0,0"
    ItemsSource="{x:Bind ViewModel.Orders, Mode=OneWay}"
    SelectedItem="{x:Bind ViewModel.SelectedOrder, Mode=TwoWay}"
    ContextFlyout="{StaticResource DataGridContextMenu}">
	<i:Interaction.Behaviors>
	  <behaviors:DataGridBehavior/>
	</i:Interaction.Behaviors>
	<toolkit:DataGrid.Columns>
	  <toolkit:DataGridTextColumn
	    Header="Invoice" Tag="InvoiceNumber" Binding="{Binding InvoiceNumber}"/>
	  <toolkit:DataGridTextColumn
	    Header="Customer" Tag="CustomerName" Binding="{Binding CustomerName}"/>
	  <toolkit:DataGridTemplateColumn
	    Header="Date" Tag="DatePlaced">
	    <toolkit:DataGridTemplateColumn.CellTemplate>
	      <DataTemplate>
	        <TextBlock
	          VerticalAlignment="Center" Margin="12,0"
		   Text="{Binding DatePlaced, Mode=OneWay,
                     Converter={StaticResource StringFormatConverter},
                     ConverterParameter='{}{0:d}'}" />
	      </DataTemplate>
	    </toolkit:DataGridTemplateColumn.CellTemplate>
	  </toolkit:DataGridTemplateColumn>
         <!-- Skip lines -->
	  <toolkit:DataGridTextColumn
	    Header="Status" Binding="{Binding Status}"/>
	</toolkit:DataGrid.Columns>
</toolkit:DataGrid>
  • VisualState
    • 특정 상태일 UI 요소의 시각적 모양을 지정할 있는 기능입니다. 자세한 사항은 여기 참고 합니다.
    • AdaptiveTrigger : 윈도우 속성을 기반으로 시각적 상태를 선언하는 트리거 입니다. 자세한 사항은 여기 참고 합니다.  
    • VisualState 이용해서 디자인 작업을 할 , 기본 크기에 대한 디자인은 화면에 왼쪽 상단에서8” Tablet(1280x800) 선택하고, 최소 크기에 대한 디자인은 6”Phone(1920x1080) 선택해서 작업하면 약간 편하게 작업할 있습니다.
    • 최소 크기인 경우 PageTitle 컨트롤의 왼쪽에 30 Margin 추가해서 햄버거 버튼과 겹치는 현상을 방지 합니다.
    • MobileScreenTrigger 윈도우 크기가 변경될 실행 중인 디바이스의 이름을 가지고 오고, Mobile이라는 이름을 포함하면 SetActive() 이용해서 VisualState 변경합니다. UIViewSettings.GetForCurrentView().UserInteractionMode Uno에서  미구현 상태라 주석 처리를 했습니다.
<!--Code8-->
<VisualStateManager.VisualStateGroups>
  <VisualStateGroup>
    <VisualState>
      <VisualState.StateTriggers>
        <AdaptiveTrigger MinWindowWidth="{StaticResource LargeWindowSnapPoint}" />
      </VisualState.StateTriggers>
    </VisualState>
  <VisualState>
    <VisualState.StateTriggers>
      <AdaptiveTrigger MinWindowWidth="{StaticResource MediumWindowSnapPoint}" />
    </VisualState.StateTriggers>
  </VisualState>
  <VisualState>
    <VisualState.StateTriggers>
      <AdaptiveTrigger MinWindowWidth="{StaticResource MinWindowSnapPoint}" />
    </VisualState.StateTriggers>
    <VisualState.Setters>
      <Setter Target="PageTitle.Margin" Value="30,4,0,0"/>
    </VisualState.Setters>
  </VisualState>
  <VisualState>
    <VisualState.StateTriggers>
      <stateTriggers:MobileScreenTrigger />
    </VisualState.StateTriggers>
    <VisualState.Setters>
    <!-- Skip lines -->
    </VisualState.Setters>
  </VisualState>
  </VisualStateGroup>
</VisualStateManager.VisualStateGroups>
  • BackButton
    • 뒤로가기 버튼입니다. GoBackCommand 커맨드는 ViewModelBase 선언되어 있습니다.
<!--Code9-->
            <Button 
                x:Name="BackButton"
                Style="{StaticResource NavigationBackButtonNormalStyle}"
                Command="{x:Bind ViewModel.GoBackCommand}"/>
  • TextBox
    • 일반 텍스트를 표시하고 편집하는 사용하는 컨트롤 입니다. 자세한 사항은 여기 참고 합니다.
    • Text 프로퍼티에 TwoWay바인딩을 때는 UpdateSourceTrigger=PropertyChanged 이용하는 것이 좋습니다. 왜냐하면, 내용을 수정하면 바로 바인딩된 프로퍼티가 수정되기 때문입니다. 기본값은 LostFocus입니다. 
<!--Code10-->
<TextBox
    x:Name="FirstName"
    MinWidth="120"
    Margin="0,8,16,8"
    Header="First name"
    IsReadOnly="{x:Bind ViewModel.Customer.IsInEdit, 
	    Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
    RelativePanel.AlignLeftWithPanel="True"
    Text="{x:Bind ViewModel.Customer.FirstName, Mode=TwoWay, 
	    UpdateSourceTrigger=PropertyChanged}" />
  • InvoiceTemplate (DataTemplate)
    • 데이터 개체의 시각적 구조를 만드는데 사용합니다. 자세한 사항은 여기 참고 합니다.
    • HyperlinkButton 1개가 존재하며 Command win not_win으로 나누어져 있습니다. 각 플랫폼별 xaml 코드를 적용하는 방법은 여기를 참고 합니다.
    • Windows에서는 win:Command="{Binding Source={StaticResource ViewModelElement}, Path=ViewModel.ViewInvoiceCommand}" 사용해야 Command 실행됩니다.
    • Windows 아닌 경우에는 not_win:Command="{Binding ElementName=DataGrid,                     Path=DataContext.ViewInvoiceCommand}" 사용해야 Command 실행됩니다.
    • Windows에서 ElementName=DataGrid 이용하는 방법이 않되는 이유는 모릅니다.
<!--Code11-->
<DataTemplate x:Key="InvoiceTemplate">
    <HyperlinkButton
        Content="{Binding InvoiceNumber}"
        Margin="12,0"
        win:Command="{Binding Source={StaticResource ViewModelElement}, 
            Path=ViewModel.ViewInvoiceCommand}"
        not_win:Command="{Binding ElementName=DataGrid, 
            Path=DataContext.ViewInvoiceCommand}"
        CommandParameter="{Binding}"/>
</DataTemplate>
  • Etc
    • 만약 솔루션에 .Net Standard 프로젝트를 포함하고, 사용한다면, Wasm 프로젝트의 LinkerConfig.xml 파일에 해당 내용을 추가해야 합니다.
<!—LinkerConfig.xml -->
<linker>
  <assembly fullname="UnoContoso.Wasm" />
  <assembly fullname="Uno.UI" />
  <assembly fullname="System.Core">
	<!-- This is required by JSon.NET and any expression.Compile caller -->
	<type fullname="System.Linq.Expressions*" />
  </assembly>
  <assembly fullname="UnoContoso.Models"/>
  <assembly fullname="UnoContoso.Repository"/>
</linker>

이상으로 작업을 하면서 알게된 몇가지 팁들을 정리했습니다. 앞으로도 좋은 정보가 있으면 꾸준히 올리도록 하겠습니다.

Facebook : https://www.facebook.com/kaki104

Twitter : https://twitter.com/kaki104

Youtube : http://youtube.com/FutureOfDotNet

 

블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요

마이크로소프트의 Contoso UWP앱을 UnoContoso 앱으로 포팅한 결과를 다루는 것으로, Uno Platform으로 비지니스 앱을 만들 수 있는지 여러분들이 판단해 보시기 바랍니다.

 

My troubles

  • Does the UI output the same for each platform?
  • I haven't made any Android or iOS apps before. Is it okay?
  • Can it run on Windows 7?
  • It's nice if it runs on macOS too...(Even a simple screen...)
  • Are there cross-platforms running on IoT devices?
  • Will there be enough performance to use for each platform without any problems?

Contoso UWP app

UnoContoso app

 

 

Difficulties in porting

Can I make business apps with the Uno Platform.pdf
1.14MB

youtu.be/ANPVsLc5Hoo

 

블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요

Register Desktop Bridge app and UWP app as Startup program

Future Of DotNet
https://youtube.com/FutureOfDotNet

UWP앱을 시작프로그램으로 등록/삭제하는 방법입니다.

Youtube : https://youtu.be/5cI6oS0HLOQ
Blog : https://kaki104.tistory.com/664
Git : https://github.com/kaki104/StartupSample

Reference

Desktop Bridge vs UWP

  • How
  • Namespace
  • EntryPoint
  • Enabled
  • Multiple startupTask
  • Diabled/Enabled

Constrained in UWP apps

  • The default is Disable
  • Show a user-prompt dialog for UWP apps
  • StartupTask includes a Disable method
  • If the user disables, then the prompt is not shown again
  • If the feature is disabled by local admin or group policy, then the user prompt is not shown, and startup cannot be enabled
  • Platforms other than Desktop that don’t support startup tasks also report DisabledByPolicy

Package.appxmanifest

<Application>
    <Extensions>
        <uap5:Extension Category="windows.startupTask“ Executable="StartupXXX.exe“ EntryPoint="StartupXXX.App">
            <uap5:StartupTask TaskId="StartupXXX“ Enabled="false“ DisplayName="StartupXXX“/>
        </uap5:Extension>
    </Extensions>
</Application>

MainPage.xaml.cs

var startupTask = await StartupTask.GetAsync("StartupXXX");
StartupTaskState newState = await startupTask.RequestEnableAsync();

App.xaml.cs

protected override void OnActivated(IActivatedEventArgs args)

var staea = args as StartupTaskActivatedEventArgs;
rootFrame.Navigate(typeof(MainPage), staea.TaskId);
Window.Current.Activate();

Register startup program.pdf
190.9 kB

블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요

Face Detection API

. Real-time face recognition with Microsoft Cognitive Services
. Google

  • Vision API
    • Facial Detection
      • Free : First 1000 units/month
      • $1.5 for 1000 unit : 1001 – 5,000,000 / month
        . Microsoft Azure
  • Face API
    • Face Detection ~ Face Identification
      • Free : 20 transactions for minute
      • $1.0 for 1000 transactions : 0 – 1M transactions
        . OpenCV
        . Dlib C++ Library

OpenCV

. 오픈 소스 컴퓨터 비전 라이브러리 중 하나로 크로스플랫폼과 실시간 이미지 프로세싱에 중점을 둔 라이브러리.
. Windows, Linux, OS X(macOS), iOS, Android 등 다양한 플랫폼을 지원
. OpenCvSharp

  • C# : OpenCvSharp4 nuget package
  • UWP : OpenCvSharp4.runtime.uwp nuget package
  • haarcascade_frontalface_alt.xml

OpenCVSharp

. Mat class

  • Matrix의 약자로 행렬을 표현하기 위한 데이터 형식
    . Haar Cascade
  • 이미지 또는 비디오에서 객체를 식별하는데 사용되는 기계 학습 객체 감지 알고리즘
  • haarcascade_frontalface_alt.xml : 얼굴 전면 식별
  • DetectMultiScale
    • 입력된 이미지에서 크기가 다른 물체를 감지합니다. 감지 된 객체는 사각형 목록으로 반환

Dlib C++ Library

  • 기계 학습 알고리즘 및 도구를 포함하는 C++ 툴킷으로 로봇 공학, 임베디드 장치, 휴대 전화 및 대형 컴퓨팅 환경을 포함한 광범위한 산업 영역 및 학계에서 사용

  • DlibDotNet

    • DlibDotNet for UWP nuget package
  • Dlib Models

    • shape_predictor_5_face_landmarks.dat
      • 눈의 모서리와 코의 바닥을 식별하는 5포인트 랜드 마크 모델
    • shape_predictor_68_face_landmarks.dat
      • 얼굴 전체를 감싸는 68개의 포인트 랜드 마크 모델
      • 상업적 사용을 위해서는 담당자와 별도의 협의를 진행해야 함

Part1

https://youtu.be/wxIFGmG6JCo

Part2

https://youtu.be/QQimCeWIdps

PDF

Face detecting in UWP app.pdf
226.6 kB

Github

https://github.com/kaki104/FaceDetectionSample

블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요

  • UWP이 로컬 파일 시스템을 직접 접근해서 파일이나 폴더의 정보를 가지고 오는 방법에 대한 설명입니다.

  • This is how UWP directly accesses the local file system and fetches information from files or folders.

  • BroadFileSystemAccess

    • All Files that the user has access to
    • Settings } Privacy | File system | Allow access UWP app
    • Version 1803 - default is On
    • Version 1809 - default is Off
    • This capability is not supported on Xbox
  • Key Point

    • Package.appxmanifest } Mouse Right Click } Open With… } XML (Text) Editor
    • Add rescap namespace
    • Add rescap:Capability to th Capabilities section
      • {rescap:Capability Name="broadFileSystemAccess" /}
    • Code
      • var folder = await StorageFolder.GetFolderFromPathAsync(path);
      • try-catch(UnauthorizedAccessException)
  • Completed sample app

  - youtu.be/TJ5wDDgty6A

 

'Windows App(Universal App) > Beginner' 카테고리의 다른 글

Microsoft Edge(Chromium) WebView2 Control  (0) 2020.08.17
Face detecting in UWP app  (0) 2020.08.06
Create a UWP app with File System Access  (0) 2020.07.24
Install and update UWP apps from the Web  (0) 2020.04.25
LINQ - Join Operations - part5/5  (0) 2020.04.15
LINQ part 4  (0) 2020.02.11
블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요

Simple RSS Reader creation is complete.

블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요

  • Uno Platform을 이용해서 간단한 RSS Reader를 만드는 강좌입니다. Part1과 Part2로 나누어 짐니다.
  • This is a course to create a simple RSS reader using the Uno Platform. It is divided into Part1 and Part2.
  • Setting up your development environment

  • What is the nuget package for using MVVM

  • Refractored.MvvmHelpers

  • RSS Reader Step1

    • Goal

      • Creating an RSS Reader app with one page
    • Create Uno project
    • Nuget packages
  • RSS Reader Step2

    • Settings

    • Controls

  • 추가사항
    • Wasm 프로젝트는 실행해도 결과가 출력되지 않습니다. 이유는 크로스도메인 정책으로 인해 RSS 데이터를 가지고 올 수 없기 때문입니다. 이 부분은 해결을하는 데로 추가하도록 하겠습니다.
  • source
    . https://github.com/kaki104/SimpleRSS.UNO

 

kaki104/SimpleRSS.UNO

Creating a simple RSS app using the Uno Platform. Contribute to kaki104/SimpleRSS.UNO development by creating an account on GitHub.

github.com

  * Youtube : youtu.be/CQBfyTSV5uc

 

블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요

Getting started Uno

Uno Platform 2020. 5. 24. 14:21

  • Setting up your development environment

    • Prerequisites
      • Windows 10 1809 or later
      • Windows SDK 1809 or later
      • Visual Studio 2019 16.3 or later
      • Universal Windows Platform workload
      • Mobile development with .NET (Xamarin) workload
        • The iOS Remote Simulator
        • Mac with Visual Studio for Mac, Xcode 8.2 or later installed
        • Google’s Android x86 emulators or physical Android device
        • ASP .NET and web workload
      • .NET Core 2.2
    • Install Uno Platform Solution Templates with Visual Studio
      • Extension -> Manage Extensions -> Uno search -> install
      • Version 2.4
  • Create a Single Page App with Uno

    • Learn how to
      • Add the Uno Platform Project Templates to Visual Studio
      • Create a new Project with Uno Platform
      • Learn basic on Model Binding
    • Install Android Emulator
  • Step 1

    • Create Project
    • Check NuGet Packages and Install
      • Uno.Core, Uno.UI, Uno.Wasm.Bootstrap : latest stable version
      • Refractored.MvvmHelpers NuGet Packages install
    • Build
  • Step 2

    • Models
      • Create Models folder
      • Add IssueItem class
      • Add broken references
    • Converters
      • Create Converters folder
      • Add StringFormatConverter class
  • Step 3

    • MainPage.xaml.cs

      • Add code
      • Add broken references
    • MainPage.xaml

      • Add xaml code
      • View XAML design
        • Change startup project to UWP project
        • Solution platform to choose x86
        • Close and reopen MainPage.xaml
      • MainPage.xaml.cs
      • Add event handlers code
      Getting started Uno.pdf
      585.0 kB
    •  

youtu.be/j4iR3FnREhk

 

블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

Tag Android, IOS, uno, UWP

댓글을 달아 주세요

How to deploy UWP apps
- Microsoft Store
- App Installer
  . After Windows 10 version 1803
  . Can be installed Local, Shared Folder, or on the Web

For developers
- Settings -> Update & Security -> For developers -> Sideload apps
- Sideload apps must be selected in order to install apps outside of the Microsoft Store.

Install Windows 10 apps with App Installer

Create an App Installer file with Visual Studio
- Doc
  . Windows 10 version 1803 or higher
  . Visual Studio 2017 version 15.7 or higher
  . Create sideload apps that can be automatically updated using .appinstaller files
  . UWP TargetPlatformMinVersion version 1803 or higher
- Work
  . Windows 10 version 1909
  . Visual Studio 2019 version 16.5.4

Demo
- Create UWP app

Package
- UWP app project -> Right-click -> Publish -> Create App Packages…
- Click the Create button to create a test certificate
- Enter additional simple information
- Enter additional simple information

Select and configure packages
- Choose the platform you want to support
- For release of the full version, please select a Release

Configure update settings
- Installer location
  . Enter the location to copy the installation files
  . You can enter the web path, shared folder path, and local folder path.
  . Copy the completed distribution package to the folder you just entered.
  Ex) Web https://hellobotstorage.z12.web.core.windows.net/apps
  Ex) Local c:\install
  Ex) Shared Folder \\kakiserver\home\apps

Finished creating package
- Output location
  . This is where the package was created.
  . Click the link to open the folder with File Explorer.
  . Copy files to the installer location

Install apps from web
- I use Static Web in Azure
https://hellobotstorage.z12.web.core.windows.net/apps

Installation failed
- Either you need a new certificate installed for this app package…
- If you buy a signed certificate and use it, this is not necessary.
- Certificate Sales Site I Know

Install Certificate
- Additional Links -> Publisher Certificate
- Install Certificate… -> Local Machine -> Place all certificates in the following store -> Trusted Root Certification Authorities -> OK
- Next -> Finish

Update app on the web
- Create an updated version and copy it to the installation location
- Run the installed apps (check for update version existence)
- App exit
- Re-run the app(update progress)

 

https://youtu.be/uedWhxNSs3Y

 

'Windows App(Universal App) > Beginner' 카테고리의 다른 글

Face detecting in UWP app  (0) 2020.08.06
Create a UWP app with File System Access  (0) 2020.07.24
Install and update UWP apps from the Web  (0) 2020.04.25
LINQ - Join Operations - part5/5  (0) 2020.04.15
LINQ part 4  (0) 2020.02.11
LINQ part 3  (0) 2020.02.04
블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요

What is UNO Platform?

Uno Platform 2020. 1. 29. 00:02

UNO Platform에 대해서 알아보도록 하겠습니다.

원본 동영상 https://m.youtube.com/watch?v=NHFbPItDaDc

 

1. 크로스 플랫폼 개발용

 

2. Xamarin.Forms와 차이점

 

3. Uno Platform

- Port of Universal Windows Platform(UWP) API and XAML to iOS/Android/WASM/macOS

- Written in C#(with bits of Java and JavaScript)

- 1:1 compatibility with UWP XAML, existing skills consistent UI

- Free and open source - https://platform.uno/

 

4. Uno Platform UI comparison

 

5. Supported platforms

 

6. Uno UI

 

7. Uno - UI? Not only!

 

8. Uno Platform Prerequisites

- Visual Studio 2019 for Windows

. Universal Windows Platform

. Mobile development with .NET

. ASP.NET and Web

- macOS for iOS build host

- Uno Platform Solution Templates Visual Studio Extension

 

9. DEMO

 

10. Call to action

 

https://youtu.be/li47OqE0tNI

 

블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요