dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.45k stars 4.76k forks source link

Use-cases for Swift interop in .NET 10 #95636

Open kotlarmilos opened 11 months ago

kotlarmilos commented 11 months ago

Overview

This issue presents use-cases we want to support. They are required to define and limit the scope of Swift interop effort in .NET 10. While it's difficult to clearly specify the exact Swift language features that will be supported in the next release, we can establish our definition of done, with focus on two key areas: functionality and performance.

Hiking app

We want to develop an experimental .NET iOS app which will serve as a base for implementing use-cases that showcase the capabilities of Swift interop. Selected functionalities from the app will be calling into Swift-only frameworks to demonstrate capabilities of the Swift interop. The app and corresponding bindings will not be officially supported.

Users of the app will be able to explore trails, authenticate using Apple ID, purchase a trail, and record a hike.

In-app purchase example

This example demonstrates in-app purchases and reviews using StoreKit2 framework. On the "Explore" page, items will be available for purchase via the products method. When the purchase button is clicked, it triggers the purchase method. Target APIs: - [ ] PaymentMethodBinding ```swift struct PaymentMethodBinding : Swift.Sendable, Swift.Hashable, Swift.Identifiable {} ``` - [ ] Transaction ```swift struct Transaction : Swift.Identifiable {} ``` - [ ] Reason ```swift struct Reason : Swift.RawRepresentable, Swift.Equatable, Swift.Hashable, Swift.Sendable {} ``` - [ ] RevocationReason ```swift struct RevocationReason : Swift.RawRepresentable, Swift.Equatable, Swift.Hashable {} ``` - [ ] OfferType ```swift struct OfferType : Swift.RawRepresentable, Swift.Equatable, Swift.Hashable {} ``` - [ ] OwnershipType ```swift struct OwnershipType : Swift.RawRepresentable, Swift.Equatable, Swift.Hashable {} ``` - [ ] Offer ```swift struct Offer : Swift.Equatable, Swift.Hashable, Swift.Sendable {} ``` - [ ] PaymentMode ```swift struct PaymentMode : Swift.RawRepresentable, Swift.Equatable, Swift.Hashable, Swift.Sendable {} ``` - [ ] Transactions ```swift struct Transactions : _Concurrency.AsyncSequence {} ``` - [ ] AsyncIterator ```swift struct AsyncIterator : _Concurrency.AsyncIteratorProtocol {} ``` - [ ] Environment ```swift struct Environment : Swift.RawRepresentable, Swift.Equatable, Swift.Hashable, Swift.Sendable {} ``` - [ ] PurchaseIntent ```swift struct PurchaseIntent : Swift.Equatable, Swift.Identifiable, Swift.Sendable {} ``` - [ ] PurchaseIntents ```swift struct PurchaseIntents : _Concurrency.AsyncSequence {} ``` - [ ] Storefront ```swift struct Storefront : Swift.Identifiable, Swift.Sendable {} ``` - [ ] Storefronts ```swift struct Storefronts : _Concurrency.AsyncSequence, Swift.Sendable {} ``` - [ ] SubscriptionPeriod ```swift struct SubscriptionPeriod : Swift.Equatable, Swift.Hashable {} ``` - [ ] FormatStyle ```swift struct FormatStyle : Foundation.FormatStyle {} ``` - [ ] SubscriptionOffer ```swift struct SubscriptionOffer : Swift.Equatable, Swift.Hashable {} ``` - [ ] Signature ```swift struct Signature : Swift.Equatable, Swift.Hashable, Swift.Sendable {} ``` - [ ] Token ```swift struct Token : Swift.Hashable, Swift.Sendable {} ``` - [ ] RenewalState ```swift struct RenewalState : Swift.RawRepresentable, Swift.Equatable, Swift.Hashable {} ``` - [ ] RenewalInfo ```swift struct RenewalInfo {} ``` - [ ] ExpirationReason ```swift struct ExpirationReason : Swift.RawRepresentable, Swift.Equatable, Swift.Hashable {} ``` - [ ] Status ```swift struct Status : Swift.Equatable, Swift.Hashable {} ``` - [ ] Statuses ```swift struct Statuses : _Concurrency.AsyncSequence {} ``` - [ ] PromotionInfo ```swift struct PromotionInfo : Swift.Equatable {} ``` - [ ] AppTransaction ```swift struct AppTransaction : Swift.Sendable {} ``` - [ ] SubscriptionInfo ```swift struct SubscriptionInfo : Swift.Equatable, Swift.Hashable {} ``` - [ ] Message ```swift struct Message : Swift.Sendable {} ``` - [ ] Messages ```swift struct Messages : _Concurrency.AsyncSequence, Swift.Sendable {} ``` - [ ] PurchaseOption ```swift struct PurchaseOption : Swift.Equatable, Swift.Hashable {} ``` - [ ] Product ```swift struct Product : Swift.Identifiable {} ``` - [ ] ProductType ```swift struct ProductType : Swift.RawRepresentable, Swift.Equatable, Swift.Hashable {} ``` - [ ] PaymentMethodBindingError ```swift enum PaymentMethodBindingError : Foundation.LocalizedError {} ``` - [ ] RefundRequestError ```swift enum RefundRequestError : Swift.Error {} ``` - [ ] RefundRequestStatus ```swift enum RefundRequestStatus {} ``` - [ ] AppStore ```swift enum AppStore {} ``` - [ ] Unit ```swift enum Unit : Swift.Equatable, Swift.Hashable {} ``` - [ ] ExternalPurchase ```swift enum ExternalPurchase : Swift.Sendable {} ``` - [ ] NoticeResult ```swift enum NoticeResult : Swift.Hashable, Swift.Sendable {} ``` - [ ] ExternalPurchaseLink ```swift enum ExternalPurchaseLink : Swift.Sendable {} ``` - [ ] ExternalLinkAccount ```swift enum ExternalLinkAccount : Swift.Sendable {} ``` - [ ] ExternalPurchaseCustomLink ```swift enum ExternalPurchaseCustomLink : Swift.Sendable {} ``` - [ ] NoticeType ```swift enum NoticeType : Swift.Int, Swift.Hashable, Swift.Sendable {} ``` - [ ] PriceIncreaseStatus ```swift enum PriceIncreaseStatus : Swift.Equatable, Swift.Hashable {} ``` - [ ] VerificationResult ```swift enum VerificationResult {} ``` - [ ] VerificationError ```swift enum VerificationError : Swift.Error {} ``` - [ ] Visibility ```swift enum Visibility : Swift.Int, Swift.Equatable, Swift.Hashable {} ``` - [ ] StoreKitError ```swift enum StoreKitError : Swift.Error {} ``` - [ ] BackingValue ```swift enum BackingValue : Swift.Equatable, Swift.Hashable {} ``` - [ ] PurchaseResult ```swift enum PurchaseResult {} ``` - [ ] PrchaseError ```swift enum PurchaseError : Swift.Error {} ```

Authentication example

This example demonstrates the authentication feature using the built-in [SignInWithAppleButton](https://developer.apple.com/documentation/authenticationservices/signinwithapplebutton) on the “Login” page. Users can authenticate using their Apple ID, providing a seamless login experience. Target APIs: - [ ] SignInWithAppleButton ```swift @_Concurrency.MainActor @preconcurrency struct SignInWithAppleButton : SwiftUICore.View {} ``` - [ ] SignInWithAppleButton.Label ```swift struct Label { public static let signIn: _AuthenticationServices_SwiftUI.SignInWithAppleButton.Label public static let `continue`: _AuthenticationServices_SwiftUI.SignInWithAppleButton.Label public static let signUp: _AuthenticationServices_SwiftUI.SignInWithAppleButton.Label } ``` - [ ] SignInWithAppleButton.Style ```swift struct Label { public static let black: _AuthenticationServices_SwiftUI.SignInWithAppleButton.Style public static let white: _AuthenticationServices_SwiftUI.SignInWithAppleButton.Style public static let whiteOutline: _AuthenticationServices_SwiftUI.SignInWithAppleButton.Style } ```

SwiftUI views example

This example demonstrates how .NET developers can integrate native SwiftUI controls into MAUI-based applications, leveraging native UI controls for a seamless user experience. This example implements SwiftUI views and serves as a foundation for the next examples. The “Login” page includes a login button and text. The main menu contains "Explore" and "My Trails" pages. The "Explore" page displays a list of available trails for purchase. Each item includes an image, text, and a "Buy" button. “Trail details” page displays an image and description. If the trail is not purchased, there is a "Purchase" button and an image; if it is purchased, there is a "Start/Stop" button and a map with start and end pins. Views and controls should be sourced from the SwiftUI framework. Target APIs: - [ ] [Button](https://developer.apple.com/documentation/swiftui/button) - [ ] [Label](https://developer.apple.com/documentation/swiftui/label) - [ ] [Image](https://developer.apple.com/documentation/swiftui/image)

[!NOTE]
The .NET iOS app with generated bindings will be experimental in .NET 10 and will not be officially supported.

ghost commented 11 months ago

Tagging subscribers to this area: @dotnet/area-meta See info in area-owners.md if you want to be subscribed.

Issue Details
# Description This issue tracks the top-level scenarios for end-users regarding .NET Swift interop. The goal is to demonstrate the practical application of .NET Swift interop within Maui scenarios. One possible approach is to select an existing Maui sample from https://github.com/dotnet/maui-samples and improve it by incorporating native libraries and widgets, such as UIKit or SwiftUI. There are some other ideas, which may be desirable but not required, and will be added later. Below is a list of tasks that needs to be implemented. Please note that the breakdown of the issues does not impose hard deadlines. If some of the functionality does not get upstreamed for a particular preview version, this issue will be updated accordingly. ## Tasks ### .NET9 Preview 1 - [ ] Compile a list of libraries and features to support in .NET 9 - [ ] Select Maui applications to showcase the .NET Swift interop - [ ] Propose design for VSCode extension ### .NET9 Preview 2 - [ ] Update Maui applications to utilize the .NET Swift interop - [ ] Implement and deploy the VSCode extension ### .NET9 Preview 3 - [ ] Implement telemetry for BTfS usage - [ ] Write a blog post that showcases the usage of .NET Swift interop ### .NET9 Preview 4 TBD
Author: kotlarmilos
Assignees: kotlarmilos
Labels: `area-Meta`, `User Story`
Milestone: 9.0.0