본문으로 건너뛰기
cccskills
무료GitHub에 공개

uno-platform

Build cross-platform .NET applications with Uno Platform targeting WebAssembly, iOS, Android, macOS, Linux, and Windows from a single XAML/C# codebase. USE FOR: building cross-platform apps from a single C# and XAML codebase; targeting WebAssembly, iOS, Android, macOS, Linux, and Windows simultaneously; migrating WPF or UWP. DO NOT USE FOR: unrelated stacks; generic tasks that do not need this specific guidance. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(3)

  • SKILL.md7.8 KB
  • manifest.json93 B
  • references/patterns.md10.5 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Uno Platform

Trigger On

  • building cross-platform apps from a single C# and XAML codebase
  • targeting WebAssembly, iOS, Android, macOS, Linux, and Windows simultaneously
  • migrating WPF or UWP applications to cross-platform
  • implementing pixel-perfect UI across all platforms
  • using WinUI/UWP APIs on non-Windows platforms

Documentation

References

See detailed examples in the references/ folder:

  • patterns.md — MVUX, XAML, navigation, and performance patterns

Platform Support

PlatformRenderingNotes
WindowsWinUI 3Native Windows App SDK
WebAssemblySkia/CanvasRuns in browser
iOSSkia/MetalNative iOS app
AndroidSkia/OpenGLNative Android app
macOSSkia/MetalMac Catalyst or AppKit
LinuxSkia/X11GTK or Framebuffer

Workflow

  1. Choose the right template — Uno Platform offers various templates for different scenarios
  2. Understand rendering modes — Skia vs native rendering affects performance and fidelity
  3. Apply MVVM or MVUX patterns — keep views dumb, logic in ViewModels
  4. Handle platform differences — use conditional XAML or partial classes
  5. Test on all target platforms — behavior varies across platforms

Project Structure

MyApp/
├── MyApp/                    # Shared code
│   ├── App.xaml              # Application entry
│   ├── MainPage.xaml         # Main page
│   ├── Presentation/         # ViewModels (MVUX/MVVM)
│   ├── Business/             # Business logic
│   └── Services/             # Platform services
├── MyApp.Wasm/               # WebAssembly head
├── MyApp.Mobile/             # iOS and Android head
├── MyApp.Skia.Gtk/           # Linux head
├── MyApp.Skia.WPF/           # Windows Skia head
└── MyApp.Windows/            # Native WinUI head

MVUX Pattern (Uno Extensions)

Model Definition

public partial record MainModel
{
    public IListFeed<TodoItem> Items => ListFeed.Async(LoadItems);

    private async ValueTask<IImmutableList<TodoItem>> LoadItems(CancellationToken ct)
    {
        var items = await _todoService.GetAllAsync(ct);
        return items.ToImmutableList();
    }
}

View Binding with FeedView

<Page xmlns:uen="using:Uno.Extensions.Navigation.UI">
    <utu:FeedView Source="{Binding Items}">
        <utu:FeedView.ValueTemplate>
            <DataTemplate>
                <ListView ItemsSource="{Binding}">
                    <ListView.ItemTemplate>
                        <DataTemplate x:DataType="local:TodoItem">
                            <TextBlock Text="{Binding Title}" />
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </DataTemplate>
        </utu:FeedView.ValueTemplate>
        <utu:FeedView.ProgressTemplate>
            <DataTemplate>
                <ProgressRing IsActive="True" />
            </DataTemplate>
        </utu:FeedView.ProgressTemplate>
    </utu:FeedView>
</Page>

Classic MVVM with MVVM Toolkit

ViewModel

public partial class MainViewModel(ITodoService todoService) : ObservableObject
{
    [ObservableProperty]
    private ObservableCollection<TodoItem> _items = [];

    [ObservableProperty]
    private bool _isLoading;

    [RelayCommand]
    private async Task LoadItemsAsync()
    {
        IsLoading = true;
        try
        {
            var items = await todoService.GetAllAsync();
            Items = new ObservableCollection<TodoItem>(items);
        }
        finally
        {
            IsLoading = false;
        }
    }
}

Platform-Specific Code

Conditional XAML

<TextBlock Text="Welcome"
           xmlns:win="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:android="http://uno.ui/android"
           xmlns:ios="http://uno.ui/ios"
           xmlns:wasm="http://uno.ui/wasm">

    <win:TextBlock.Foreground>
        <SolidColorBrush Color="Blue" />
    </win:TextBlock.Foreground>

    <android:TextBlock.Foreground>
        <SolidColorBrush Color="Green" />
    </android:TextBlock.Foreground>
</TextBlock>

Partial Classes

// Services/DeviceService.cs (shared)
public partial class DeviceService
{
    public partial string GetDeviceInfo();
}

// Services/DeviceService.wasm.cs
public partial class DeviceService
{
    public partial string GetDeviceInfo() => "WebAssembly";
}

// Services/DeviceService.Android.cs
public partial class DeviceService
{
    public partial string GetDeviceInfo() =>
        $"Android {Android.OS.Build.VERSION.Release}";
}

Hot Reload and Development

// Enable Hot Reload in App.xaml.cs
public App()
{
    this.InitializeComponent();

#if DEBUG
    // Enable Hot Reload
    this.EnableHotReload();
#endif
}

Anti-Patterns to Avoid

Anti-PatternWhy It's BadBetter Approach
Platform code in sharedBreaks compilationUse partial classes or #if
Ignoring Skia differencesVisual bugsTest on all renderers
WPF assumptionsNot all APIs existCheck Uno API coverage
Heavy XAMLSlow on WASMVirtualize, simplify
Synchronous loadingUI freezesAlways use async

Performance Best Practices

  1. Use virtualized lists:

    <ListView ItemsSource="{Binding Items}"
              VirtualizingPanel.VirtualizationMode="Recycling" />
    
  2. Lazy load resources:

    // Load images on demand
    var image = await ImageSource.LoadFromUriAsync(uri);
    
  3. Minimize XAML complexity:

    • Avoid deep nesting
    • Use compiled bindings (x:Bind where supported)
    • Consider Skia-specific optimizations
  4. WebAssembly specific:

    • Minimize interop calls
    • Use InvokeAsync for JS interop
    • Consider AOT compilation for performance

Uno Extensions

// Use Uno.Extensions for enhanced patterns
var builder = this.CreateBuilder(args)
    .Configure(host => host
        .UseConfiguration()
        .UseLocalization()
        .UseNavigation()
        .UseMvux()
        .ConfigureServices(services =>
        {
            services.AddSingleton<ITodoService, TodoService>();
        }));

Deliver

  • single codebase running on web, mobile, and desktop
  • consistent UI/UX across all platforms
  • platform-specific optimizations where needed
  • MVVM or MVUX patterns for testability

Validate

  • app builds and runs on all target platforms
  • platform-specific features work correctly
  • performance is acceptable on WebAssembly
  • Hot Reload works during development
  • no WPF/UWP-only APIs are used without fallbacks

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Route gh-aw workflow design/create/debug/upgrade requests to the right prompts.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

managedcode/dotnet-skills4902026년 10월 17일 업데이트

Use a repo-root `.editorconfig` to configure free .NET analyzer and style rules. Use when a .NET repo needs rule severity, code-style options, section layout, or analyzer ownership made explicit. USE FOR: the repo needs a root .editorconfig; analyzer severity and style ownership are unclear; the team wants one source of truth for rule configuration. DO NOT USE FOR: choosing analyzers with no config change; formatting-only execution with no config ownership question. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

managedcode/dotnet-skills4902026년 10월 17일 업데이트

Scans .NET code for ~50 performance anti-patterns across async, memory, strings, collections, LINQ, regex, serialization, and I/O with tiered severity classification. Use when analyzing .NET code for optimization opportunities, reviewing hot paths, or auditing allocation-heavy patterns.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

managedcode/dotnet-skills4902026년 10월 17일 업데이트

Symbolicate the .NET runtime frames in an Android tombstone file. Extracts BuildIds and PC offsets from the native backtrace, downloads debug symbols from the Microsoft symbol server, and runs llvm-symbolizer to produce function names with source file and line numbers. USE FOR triaging a .NET MAUI or Mono Android app crash from a tombstone, resolving native backtrace frames in libmonosgen-2.0.so or libcoreclr.so to .NET runtime source code, or investigating SIGABRT, SIGSEGV, or other native signals originating from the .NET runtime on Android. DO NOT USE FOR pure Java/Kotlin crashes, managed .NET exceptions that are already captured in logcat, or iOS crash logs. INVOKES Symbolicate-Tombstone.ps1 script, llvm-symbolizer, Microsoft symbol server.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

managedcode/dotnet-skills4902026년 10월 17일 업데이트

Symbolicate .NET runtime frames in Apple platform .ips crash logs (iOS, tvOS, Mac Catalyst, macOS). Extracts UUIDs and addresses from the native backtrace, locates dSYM debug symbols, and runs atos to produce function names with source file and line numbers. Automatically downloads .dwarf symbols from the Microsoft symbol server using Mach-O UUIDs. USE FOR triaging a .NET MAUI or Mono app crash from an .ips file on any Apple platform, resolving native backtrace frames in libcoreclr or libmonosgen-2.0 to .NET runtime source code, retrieving .ips crash logs from a connected iOS device or iPhone, or investigating EXC_CRASH, EXC_BAD_ACCESS, SIGABRT, or SIGSEGV originating from the .NET runtime. DO NOT USE FOR pure Swift/Objective-C crashes with no .NET components, or Android tombstone files. INVOKES Symbolicate-Crash.ps1 script, atos, dwarfdump, idevicecrashreport.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

managedcode/dotnet-skills4902026년 10월 17일 업데이트

Design or review .NET solution architecture across modular monoliths, clean architecture, vertical slices, microservices, DDD, CQRS, and cloud-native boundaries without over-engineering. USE FOR: .NET architecture choices; layer and domain boundary review; service decomposition; clean architecture, vertical slice, DDD, CQRS, and modular monolith decisions. DO NOT USE FOR: unrelated stacks; generic tasks that do not need this specific guidance. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

managedcode/dotnet-skills4902026년 10월 17일 업데이트

managedcode의 스킬 모두 보기

이 스킬의 문제 신고