In order to work on Hyperdeck, you need to install Rust and compile the parseval package.
The first requirement is to install Rust via the offocial Rustup tool.
Next, you need to install the required architectures for Catalyst
# iOS device support
rustup target add aarch64-apple-ios
# iOS simulator support
rustup target add aarch64-apple-ios-sim
# Catalyst on intel macs
rustup target add x86_64-apple-ios-macabi
# Catalyst on apple silicon macs
rustup target add aarch64-apple-ios-macabiWith that out of the way, the parseval package can be compiled:
cd parseval-rs
make apple BUILD_TYPE=releaseOnce the Rust package has been compiled, the project can be opened in Xcode.
Note that I stopped integrating parseval into the Xcode build process as that led to more issues than it solved.
There're two blog posts that explain the architecture of Hyperdeck:
Here's additional information about the architecture not covered in those posts:
- Hyperdeck still uses Frameworks instead of Swift Packages, mostly because that worked much better in 2020 and I didn't want to change this setup yet.
- There's method swizzling and other hacks in order to improve Catalyst support.
- Switching to a all SwiftUI flow is probably difficult because there're so many
UIKitbased views and controllers that would need to be rewritten or moved below a sharedCrossPlatformControllerclass that is either UIViewController or NSViewController and handles UIKit / Cocoa differences such as colors, fonts or method names.
The app target. Which also includes containers for the visible UI, e.g.
- New Document Flow
- Scene Delegates
- Presenter / Moderator
- Editor
- Assistant
containers in this regard means that while the HyperDeck target contains the actual, say, editor view controller, most of the logic is in a separate framework.
Effectively, the HyperDeck targets puts all the components together (and adds a lot of mess)
Basically a UIDocument like class that stores the state of the current document. I ran into issues with UIDocument and Catalyst which is why this is based on
LSDocument. I had nothing but trouble with UIDocument and Catalyst. This is the entry point into the Rust parseval-rs package to parse markdown and modify markdown.
SwiftUI code responsible for rendering parsed slides. This code was written in 2019 with a target of 2016 iPad Pro. Hence, there're many performance optimizations (e.g. using EquatableView everywhere and custom Equatable implementations). I don't think these are needed anymore with modern Macs.
In addition, this was written for SwiftUI 1.0 and contains a ton of hacks to make the layout somehow work within the limitations of SwiftUI 1.0.
Basic facilities for full screen presenting presentations. Includes code for animated backgrounds.
A huge amount of code to have a working NSTextView based editor with syntax highliting and keyboard shortcut support. Once again, many Catalyst issues forced the code into implementing some weird hacks. It would probably be better to use a TextKit2 based editor, such as [https://github.com/krzyzanowskim/STTextView]https://github.com/krzyzanowskim/STTextView
Re-Exports all the Model-Layer types from parseval-rs and adds additional extensions. Also has a couple of other types required.
The inspectors that appear when editing a slide or a block level element (e.g. a paragraph or a list item). This is abhorrent SwiftUI code and I think it would be beneficial to redo it with current SwiftUI and Swift Macros (to automatically have inspector fields based on datatypes)
parseval-rs also contains a CSS parser into CSS rules. ThemeKit takes a CSS stylesheet and gives it to parseval to return a list of CSS rules. These are then
converted into SwiftUI styles and cached. SlideKit then queries these styles based on the selector of the element, e.g.
This selector slide title1 right quote italic
This is just an example, the actual selector names are slightly different
Would get the style for a slide with the master set to title1 and the layout set to right and a quote element which contains italic text.
Here's a concrete example
title2 li1,
title2 li2,
title2 li3,
title2 li4,
title2 li5,
title2 li6 {
-hyper-list-style-bulletcolor: var(--color2-dark);
color: var(--color1);
-hyper-list-bullet-font: var(--list-text-size) var(--heavy);
}HyperDeck only supports a subset of CSS (2.1) with additional hacks and some custom properties. There's a _Docs.md in the theme folder that explains this.
Apart from that, ThemeKit style types (e.g. Border, Shadow), editor theming code, images, colors, fonts.
Just a bunch of type extension (e.g. UIColor+Hex.swift) to make life easier.
This was meant to be a shared place for SwiftUI Views and UIViews that were needed in multiple places. However, right now its mostly a unsorted list of UI things.
Includes UIView transitions for animated backgrounds and transitions. The whole transition system is based on transitioning between two UIViews and not in the realm of SwiftUI which - again - worked way better in 2019.
Since Catalyst was so limited, this contains hacks to inject into AppKit in order to make the app look and feel like an AppKit app and not a Catalyst UIKit Frankenstein.
AppKitUIKitSharedTypes are types that are written in Such a way that they can compile in UIKit and AppKit. They're being used across the bridge when communicating
between the AppKit and UIKit sides.
- Text Ranges are a complicated thing. Cocoa uses
NSRange(UTF16 based), Swift usesRange<String.Index>(UTF8 based), and Rust usesRange<usize>(byte based). There're facilities to convert back and forth between these types. In particular the conversion from Rust's bytes to Swift'sRange<String.Index>is expensive which is why Rust precalculatesNSRangevalues. - Implementing Undo / Redo was really difficult and I don't think its working very well.
- When cleaning up HyperDeck I only tested the macOS build. I haven't tried
- It builds for iPad, but there's currently a Document error that I haven't investigated further.