All Projects → gonzalezreal → Adaptivecardui

gonzalezreal / Adaptivecardui

Licence: mit
Snippets of UI, authored in JSON and rendered with SwiftUI

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Adaptivecardui

Ladybug
A powerful model framework for Swift 4
Stars: ✭ 147 (+101.37%)
Mutual labels:  json, codable
Generic Json Swift
A simple Swift library for working with generic JSON structures
Stars: ✭ 95 (+30.14%)
Mutual labels:  json, codable
Swiftai
SwiftAI, write Swift code smart. SwiftAI can generate Model class from JSON now. Codable and HandyJSON is supported. More features will be add.
Stars: ✭ 470 (+543.84%)
Mutual labels:  json, codable
Codability
Useful helpers for working with Codable types in Swift
Stars: ✭ 125 (+71.23%)
Mutual labels:  json, codable
Cleanjson
Swift JSON decoder for Codable
Stars: ✭ 178 (+143.84%)
Mutual labels:  json, codable
Keyedcodable
Easy nested key mappings for swift Codable
Stars: ✭ 248 (+239.73%)
Mutual labels:  json, codable
Jsontocodable
A generating tool from Raw JSON to Codable (Swift4) text written in Swift4.
Stars: ✭ 33 (-54.79%)
Mutual labels:  json, codable
Rest
☕ REST: Yoctoframework — https://rest.n2o.dev
Stars: ✭ 71 (-2.74%)
Mutual labels:  json
Guile Json
JSON module for Guile
Stars: ✭ 72 (-1.37%)
Mutual labels:  json
Metajson
Non-intrusive, high performance C++17 lightweight JSON de/serializer
Stars: ✭ 71 (-2.74%)
Mutual labels:  json
Jokeapi
A REST API that serves uniformly and well formatted jokes in JSON, XML, YAML or plain text format that also offers a great variety of filtering methods
Stars: ✭ 71 (-2.74%)
Mutual labels:  json
Ducky
Duck-Typed Value Handling for JavaScript
Stars: ✭ 71 (-2.74%)
Mutual labels:  json
Jp
dead simple terminal plots from JSON data. single binary, no dependencies. linux, osx, windows.
Stars: ✭ 1,184 (+1521.92%)
Mutual labels:  json
React Json Graph
React component for rendering graphs
Stars: ✭ 71 (-2.74%)
Mutual labels:  json
Electron Json Storage
📦 Easily write and read user settings in Electron apps
Stars: ✭ 1,193 (+1534.25%)
Mutual labels:  json
Fipe Json
🚘 FIPE API - Listagem com preço médio de veículos: carro, moto e caminhão.
Stars: ✭ 71 (-2.74%)
Mutual labels:  json
Sec Edgar Financials
Extract financial data from the SEC's EDGAR database
Stars: ✭ 73 (+0%)
Mutual labels:  json
Msgpack Unity3d
MessagePack and JSON serializer for Unity3D
Stars: ✭ 74 (+1.37%)
Mutual labels:  json
Accord
Data validation library for Rust
Stars: ✭ 72 (-1.37%)
Mutual labels:  json
Colorjson
Fast Color JSON Marshaller + Pretty Printer for Golang
Stars: ✭ 71 (-2.74%)
Mutual labels:  json

AdaptiveCardUI

CI Twitter: @gonzalezreal

AdaptiveCardUI is a library for rendering Adaptive Cards in SwiftUI.

Adaptive Cards are snippets of UI, authored in JSON, that apps and services can openly exchange. AdaptiveCardUI transforms this JSON into a native SwiftUI view tree, allowing the integration of lightweight UI into your SwiftUI app.

Motivation

Microsoft builds and maintains the Adaptive Card schema. They have SDKs available for several platforms, including a UIKit Objective-C++ based implementation for iOS.

AdaptiveCardUI aims to provide a more natural experience for Swift developers:

  • It uses Swift Codable for decoding and encoding Adaptive Cards
  • Allows appearance customization through view modifiers and the SwiftUI Environment
  • Supports extensibility through Custom Elements
  • Supports Dark Mode and Dynamic Type
  • Works on all the platforms where SwiftUI is present

Adaptive Card Basics

Adaptive Cards are a great way to display and interact with data, clearly and consistently. You can use them to display rich text alongside images, allow users to interact with buttons, or even collect form data.

Here is a simple card that includes a text, followed by an image and a button.

{
  "type": "AdaptiveCard",
  "version": "1.3",
  "body": [
    {
      "type": "TextBlock",
      "text": "Here is very cute dog"
    },
    {
      "type": "Image",
      "url": "https://picsum.photos/id/237/300"
    }
  ],
  "actions": [
    {
      "type": "Action.OpenUrl",
      "url": "https://picsum.photos",
      "title": "Lorem Picsum Photos"
    }
  ]
}

The root object is the Adaptive Card itself and specifies the version required to display it. The body is composed of building blocks known as elements. You can arrange them in different ways to create many types of cards. Additionally, Adaptive Cards may include actions on which the user can act.

The most fundamental elements of an Adaptive Card are:

  • TextBlock - a block of text and its appearance
  • RichTextBlock - allows for inline text formatting
  • Image - an image located in a URL and its appearance

Adaptive Cards can also have containers, which arrange a collection of child elements.

  • Container - a collection of elements stacked vertically
  • ColumnSet - divides a region into Columns, allowing elements to sit side-by-side
  • ActionSet - displays a set of actions
  • FactSet - displays a series of name/value pairs in a tabular form

With just these few elements, you can design Adaptive Cards with quite complex layouts.

iOSScreenshot MacOS Screenshot

Adaptive Cards can collect form data using Input elements. AdaptiveCardUI can't render Input elements yet, but we plan to support them soon.

Learn More

Displaying Adaptive Cards

You can create an adaptive card view by providing the URL where the adaptive card is located.

AdaptiveCardView(url: URL(string: "https://adaptivecards.io/payloads/ActivityUpdate.json")!)

Or by providing an adaptive card fetched previously.

let adaptiveCard = try JSONDecoder().decode(AdaptiveCard.self, from: jsonData)
...
AdaptiveCardView(adaptiveCard)

Before displaying the card, the view checks that its version is supported and downloads its content asynchronously.

Customizing Appearance

You can customize an adaptive card's appearance by providing a configuration. An AdaptiveCardConfiguration is a set of values that specify how the library renders the different elements. To set a specific configuration for all the adaptive cards within a view, use the adaptiveCardConfiguration(_:) modifier.

 VStack {
     AdaptiveCardView(url: URL(string: "https://adaptivecards.io/payloads/ActivityUpdate.json")!)
     AdaptiveCardView(response.adaptiveCard)
 }
 .adaptiveCardConfiguration(AdaptiveCardConfiguration(...))

Alternatively, you can customize only a specific aspect of an adaptive card's appearance, like the actions or the different spacing values. Use one of the following modifiers to customize a specific aspect of all the adaptive cards within a view:

  • actionSetConfiguration(_:) to customize the appearance of the adaptive card actions.
  • containerStyleConfiguration(_:) to customize the colors of the different container styles.
  • factSetConfiguration(_:) to customize the appearance of the fact set elements.
  • imageSizeConfiguration(_:) to provide custom values for the different image size cases.
  • spacingConfiguration(_:) to provide custom values for the different spacing cases.
  • fontTypeConfiguration(_:) to provide custom fonts for the different font types and sizes.

Adding Custom Elements

Adaptive cards are extensible, so you can add your own elements and the views that display them.

As an example, imagine that we are designing a card to present the summary of a GitHub repo. One of the elements is the repo language, which GitHub represents with a circle filled with a given color, next to the language name. The JSON representation of the element could look like this:

{
  "type": "RepoLanguage",
  "horizontalAlignment": "center",
  "language": "Swift",
  "color": "#ffac45"
}

We have omitted inherited optional properties like "id", "isVisible", "spacing", "separator", etc. But you will need to support them, nevertheless.

To add this new element, you need to create a type that conforms to CustomCardElement, Codable, and Equatable.

struct RepoLanguage: CustomCardElement, Codable, Equatable {
    // CustomCardElement

    @ItemIdentifier var id: String
    @Default<True> var isVisible: Bool
    @Default<False> var separator: Bool
    @Default<FirstCase> var spacing: Spacing
    @Default<Fallback.None> var fallback: Fallback<CardElement>
    @Default<EmptyDictionary> var requires: [String: SemanticVersion]

    // RepoLanguage

    @Default<FirstCase> var horizontalAlignment: HAlignment
    var language: String
    var color: String
}

In case you are wondering, the Default property wrapper lets you provide default values for JSON properties that are not required, removing much of the boilerplate. See DefaultCodable for more information.

As the new element conforms to CustomCardElement, you can add it to the body of an adaptive card, a container, or a column in a column set. It will have a spacing relative to the previous element and an optional separator. Besides that, you can provide a fallback element for those clients that still don't support it.

Notice that you will need to register the new element before any adaptive card decoding happens:

CardElement.register(RepoLanguage.self)

You can create the view that renders the new element as any other SwiftUI view:

struct RepoLanguageView: View {
    var repoLanguage: RepoLanguage

    var body: some View {
        HAlign(repoLanguage.horizontalAlignment) {
            Label {
                Text(repoLanguage.language)
            } icon: {
                Image(systemName: "circle.fill")
                    .imageScale(.small)
                    .foregroundColor(Color(argbHex: repoLanguage.color))
            }
        }
    }
}

Finally, to associate the new element and its view to all the adaptive card views within a view hierarchy, use the customCardElement(_:, content:) modifier:

VStack {
    AdaptiveCardView(url: URL(string: "https://adaptivecards.io/payloads/ActivityUpdate.json")!)
    AdaptiveCardView(response.adaptiveCard)
}
.customCardElement(RepoLanguage.self) {
    RepoLanguageView($0)
}

Compatibility

AdaptiveCardUI requires Xcode 12 and Swift 5.3. It works on iOS 14.0 and later. If you want to try the macOS support, you will need to install macOS Big Sur 11 and Xcode 12.2.

Installation

You can add AdaptiveCardUI to an Xcode project by adding it as a package dependency.

  1. From the File menu, select Swift Packages › Add Package Dependency…
  2. Enter https://github.com/gonzalezreal/AdaptiveCardUI into the package repository URL text field
  3. Link AdaptiveCardUI to your application target

Other Libraries

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].