All Demo running environment dependencies in this article

  • 10.15 Beta macOS Catalina
  • Xcode 11 Beta5

preface

In recent years, Android and iOS development has been trying to reinvent itself, driven by two upstream business companies:

  • Google released the Dart in 2011 and the Flutter in 2017. In the same year, Google I/O 2017 announced official Android support for Kotlin, and Google I/O 2019 announced Kotlin-First. Launch Kotlin Jetpack Compose simultaneously.
  • Apple released Swift at WWDC 2014 and SwiftUI at WWDC 2019.

Many of these ideas are going in the same direction as the front-end community, for example:

  • Declarative UI
  • Responsive data

This article will briefly share the above two concepts of SwiftUI and introduce some of the latest tool designs of Xcode.


The first impression

If you don’t know what ‘SwiftUI’ is, that’s fine, I’m not going to start with ‘SwiftUI’ anyway…


In order to arouse the interest of front-end engineers, I would like to introduce SwiftWebUI, which is an open source experimental project on Github to run SwiftUI on the Web.

Check out the official simple counter 🌰 :

  • Create an empty MacOS Command Line application
  • Use Swift Package Manager to pull SwiftUIWeb dependencies from github

Swift’s package management is based on source + profile and also follows semver rules.


  • inmain.swiftPaste the following code and add a line at the end to start the serviceSwiftWebUI.serve(MainPage())

  • Click On Xcode Build and open it in your browserhttp://localhost:1337


Effect:


From this small example, you can see some of the key concepts behind SwiftUI:

  • Declarative UI (analogous to React JSX, Flutter)
  • Responsive data (analogy mobx, VUE)
  • “CSS In JS”
  • Chain calls (officially called ViewModifier, similar to the HOC concept in React)

More complex demos can experience:
Github.com/swiftwebui/…



Declarative UI


Demo

The Demo reference:
Developer.apple.com/tutorials/s…


The SwiftUI documentation has beautifully designed interactive tutorials that can be followed step by step.



  • All view component types areViewIt only needs to implement one interfacebodyCan be analogous to the React Componentrender
  • VStackIt’s a vertical container,HStackIt’s a horizontal container,ZStackIs a container for separate layers, similar to the front-end ZIndex
  • Components can have properties (parameters of Text), or components can apply ViewModifier (chain calls)


For an in-depth analysis of the SwiftUI view syntax, you can read:



DSL



WWDC-2019 Session 216:
SwiftUI Essentials


The UI syntax of SwiftUI and Flutter can be seen in React JSX as they both use their own declarative DSL to describe the UI. However, this is a bit different from the common front-end template languages (Nunjucks/Vue), which reuse the language’s own logic control statements (conditions, loops), plus a special data structure (eg: React Virtual DOM) to express the UI. After all, for Google and Apple, the whole link of language, compiler, development tool, developer and platform is under their control, so they can do some more integrated design.

I see some drawbacks to using a template language like Nunjucks:

  • There is a gap between the programming language and the business logic, where the association occurs, the editor intelligent prompt, jump and other context information will be lost (it can also be achieved through the development of editor plug-ins, but the cost is high)
  • Template internal property binding, loop, variable interpolation some scenes will appear in the form of string logic code
  • Template languages still require a pre-compilation, such as vue templates: vuejs-tips.github. IO /compiler/#v…



Take a closer look at some of SwiftUI’s view syntax:

Condition: Use condition control statements directly


Loop: Use loop control statements directly


The List:


For dynamic List scenarios, SwiftUI also requires developers to provide an Identifiable: React key or ANTD table.props. RowKey, which enables the framework to accurately locate and update a row element in the List


Use child elements to express structure:


The Form:

In addition, according to the analysis of SwiftUI on declarative UI and type system, because SwiftUI is strongly typed, several possible view structures of a component can be statically analyzed, and the view update algorithm can even be optimized based on the statically analyzed type information at runtime. Provides better update performance than React Vitual DOM.


ViewModifier

The official document describes ViewModifier as follows: A modifier that you apply to a view or another view modifier, producing a different version of the original value.



It is used somewhat like HOC (High Order Component) in React, attaching it to a view to change its original structure or style. In addition to the built-in modifier, SwiftUI also allows developers to customize their own modifier, such as the following is a custom example:



The modifier applies to the entire subtree. For example, you can disable the entire form using either of the following methods:





Stack & layout

A Stack, described earlier, is a set of built-in layout containers

  • HStack: A container view that arranges its children horizontally.
  • VStack: A container view that vertically arranges its children.
  • ZStack: A container view that stacks its children.
  • Spacer: An elastic, space-spaced element that fills the main axis of the container element
  • Divider: A complete list of virtual Divider elements can be found in View Layout and Presentation




Although I have never developed an ios App, I can see from the design style of the App in the App Store that ios has a small screen size, few levels of elements inside a single page, not too complicated layout, and NavigationView is often used. Navigation-like components such as TabView continue to make fine-grained cuts to the view. And because Apple has a strong grip on design specifications, SwiftUI has a much simpler layout than the Web, similar to a simplified version of Flex.

Series depth interpretation | SwiftUI behind those thingsThis article has a partial explanation of SwifUI layout algorithm




Cross-platform?

The built-in components have different implementations across platforms, similar to what React Native did:






However, Apple officially said that for the sake of user experience, it is not recommended to adopt a set of interface design for devices of different sizes such as Mac, iPhone, Apple Watch and Apple TV. Therefore, they do not recommend Write once, Run anywhere. Instead, it claims to Learn once, apply Anywhere.





Responsive data

There are many implementations of responsive data on the front end, but here’s a quick overview:


What?

Assuming abstractly that a Component is a logical wrapper that consumes some data to generate a particular block View, components are wrapper that satisfies the State => View protocol. The most important effect of reactive data is that the component View updates automatically when the dependent data State changes.



According to?

So why adopt this development model? The picture below is from WWDC 2019-Session 204: Introducing SwiftUI: Building Your First App.





GUI programs are typically used to deal with a long period of user interaction involving a lot of user input and the storage of temporary state of the view. In addition, the entire page tree may have hundreds of elements to communicate and interact with each other. If the traditional event-driven programming model relies on the programmer’s brain to control all the data to view and the derivative dependence between data and data, the mental burden is very large. Once the complexity exceeds the calculation power of the human brain, the incorrect correlation will result in the generation of bugs.

Reactive leaves the maintenance of this dependency to the framework, and the developer only needs to “declare” the dependency, and this “declaration” means that the dependency is described in a descriptive language of the business logic, such as:

  • State => ViewState to the view, what data is consumed in the getter for the production view, you can basically think of the view as having a dependency on that data



  • State => Drived StateDerived states, such as calculating the intermediate data on which the final value of an attribute depends during the definition of an attribute, can be regarded as the dependency of the attribute on other attributes

Under this theoretical system, State is always a single source of truth, and view is only a Derived Value of data.



SwiftUI with reactive state management and data binding to avoid a lot of command and control logic, allowing developers to use “data driven” or “model-driven” alternatives to traditional event driven, developers in mind always thinking now my view state data is how to control, and the view behind the derivative of how to update, don’t pay any attention.

Of course, this model also has some disadvantages, see:
Could Vue.js be the silver bullet?


How?

Observable (@nx-js/observer-util);



You can see that there are several parts to this:

  • Define responsive data: Find ways to use language features to intercept getters and setters of objects
  • vue@2 is using the JS defineProperty feature
  • Observer-util and Vue@3 both make use of the JS Proxy feature
  • SwiftUI uses the Property Wrapper feature of Swift language, and @state-@binding belongs to the implementation of Property Wrapper in Swift language standard



  • Establish dependencies: Observer-util records the dependency key-value map of the whole method execution process by marking the flag bit before and after the function execution. The key is the JS data object that generates the getter, and the value is the function itself

Once the framework listens for a setter for an object, it finds the list of dependent functions for the current object from the dependency key-value Map and executes one by one.

For more information, see WWDC 2019-Session 226:
Data Flow Through SwiftUI


SwiftUI status Management API:

  • @state: Defines a reactive State whose change causes dependent views to update automatically (one-way)
  • Binding: Bidirectional Binding of view and data
  • @objectBinding: the effect is equivalent to @binding, but an external object is supported
  • BindableObject, Combine: Apple officially released the Combine, which is said to handle external events or server push scenarios. Actually, I don’t know what it is, but as long as it is the Swift version of RxJS implementation, everyone should be happy to 🚗
  • @enviromemntobject: Data shared down the View tree to look like Scoped Data
  • @Enviroment: Data that can be shared globally, and changes to it will cause the UI to refresh automatically, similar to the Provider in React


Xcode tool design

First of all, Xcode has always been a very strong IDE, including project management, dependency management, version management, development test build and so on.

This article focuses on some of the new SwiftUI features highlighted in the new red box.



Live Preview

It’s great for UI development to be able to preview in real time instead of waiting for a cup of coffee to build. Flutter uses Hot Reload as an important selling point, and SwiftUI takes this experience to the extreme.

Click on the icon in the red box in the bottom right corner of the above image to switch between Live Preview and the traditional Build Preview. Apple has both of these previews in one position, just click to switch!

  • Live Preview: AST based analysis, no build flow, real-time refresh, no interaction (no clicking and jumping)
  • Traditional build process, real application running (same as traditional Preview, but without switching screen to Simulator)

Why is Live Preview extremely fast?

  • Perform AST analysis on the current file to find all the types that comply with the PreviewProvider protocol and preview rendering, showing only the static view structure
  • Listen for code or canvas changes, updating only the most fine-grained changes to the element part

How to handle Mock data and the difference between the preview and the real run? Each SwiftUI view file can implement a PreviewProvider method in this edit-time Code area. Inside this Code, Developers can use mock data to render developed view components, or even prepare multiple sets of mock data or environment parameters to display multiple states of the view on the right side.




Add the asset

Clicking on the upper right corner of the editor brings up a floating layer, which can even hold component documents because it does not occupy the editor controls:


There are also two levels of information architecture for this floating layer. The first Tab is View and the other tabs are:


Snippets:



Media:



Color:


The assets panel can be switched from List mode to Grid mode:


The Assets panel collapses the document area:



Inspect (Properties panel)



When you select an element in the canvas or code view, Command + click calls the Action pane. The first action pane is Inspect. Here’s what the Inspect pane looks like:

Basic attributes:

Layout of the padding:

High width:


In addition to this, the Action list also has some enhancement actions (essentially intelligent transformations to view code), such as on

  • Quick changes to the view hierarchy: Quickly wrap some common layout containers around elements
  • Repeat iteration: Converts a single element into a for loop wrap
  • Conditional conditions: Convert a single element to an if else package
  • Optional: Convert a single element to an IF package


Bidirectional synchronization of code and view

SwiftUI implements a closed loop and the actual experience is good.

  • Select code to locate views, and select views to locate code
  • Select the view and click to call out the properties panel, modify the properties can be automatically written back to the code
  • Asset panel drags can be dragged into code or into views


Code Lint & AutoFix

Real-time error prompts and autofixes during code writing



Extract SubView

  • The Action panel has a one-click Action to extract a view into its child components
  • After extraction, the Lint system will detect and report an error if external variables are used inside the child component

conclusion

Because the author is also working on the Web side of the background Low Code visual site building products, although SwiftUI is a Pro Code development mode tool, but just as the publicity of SwiftUI advocates:

  • “The shortest path to building great apps on every device” ,
  • “Better apps. Less code.”

Everyone’s efforts are in the same direction, how to use less and more concise code, more intuitive and efficient tools to speed up the research and development process, really liberate productivity. At the same time, SwiftUI’s direction is right in my opinion. It combines almost all the best ideas and designs in the current field:

  • Strongly typed languages make code more maintainable
  • Declarative UI makes view code simpler
  • Responsive state management keeps the developer’s mind simple
  • The bidirectional conversion of the two editing modes of visualization and code allows novice users to learn by observing the generated code while developing through the visual editor, while skilled users can fully edit the code and use the canvas for real-time auxiliary preview
  • Smart operations such as one-click extraction of custom components and one-click conversion of repeat, list, and condition will become more and more common if understanding of application code is ensured from the beginning of design

Moving in the right direction, combined with Apple’s powerful tool integration and experience polishing capabilities, and its complete link control, all-platform design specification, SwiftUI should become ubiquitous in iOS development as long as it continues to be polished.


The relevant data

  • Some preliminary explorations of SwiftUI (2)
  • The future is declarative programming
  • SwiftUI and Swift 5.1 new features (2) propertyDelegate @propertydelegate
  • SwiftUI: A genius move by Apple
  • SwiftUI DSL syntax analysis
  • Hello Jetpack Compose
  • Interface Builder Is Dead Long Live SwiftUI
  • Thoughts on SwiftUI vs. React, Vue, Flutter, etc.