The introduction

Launched at WWDC 2019, SwiftUI is based on the declarative framework built by Swift. The framework can be used to develop applications for watchOS, tvOS, macOS, iOS and other platforms, which is equivalent to unifying the development tools of the Apple ecosystem.

When I first started iOS development, I chose OC (Objective-C programming language), which not only had a variety of well-known third-party libraries and great community support, but Swift itself was constantly being transformed. However, after I read a series of courses about SwiftUI at WWDC 2020, I started from the learning of Swift language, gradually understood and mastered SwiftUI, and decisively abandoned OC and migrated all new projects to SwiftUI framework.

Is SwiftUI as idealistic as Apple claims? Do veteran iOS developers need to make the transition, and how? What is the real experience of Using SwiftUI? These questions are what this article hopes to discuss.

In the end, I will share some of my learning experience and material order, and make progress with you in the spirit of open source.

What is a SwiftUI

For Swift UI, the official definition is easy to find and clearly written:

SwiftUI is a user interface toolkit that lets us design apps in a declarative way. Think of SwiftUI as a descriptive way of building uIs.

It’s hard for most people to get an intuitive sense of the abstract approach to programming and the improvements that come with it. This article also hopes to reduce the reading threshold by making the narration as colloquial as possible and reducing the appearance of professional vocabulary and code, so that more people can understand computer science and the world of programs.

Here’s a project I’m working on right now, Location is a native full-platform e-reading app, building the user interface with SwiftUI.

Why Did Apple launch SwiftUI

The two components of SwiftUI, Swift + UI, are the answer to this question.

Swift: Consistency of programming language and experience

Swift stands for apple’s introduction of a modern programming language

One of the reasons many Apple users love apple’s products is the sense of unity and harmony between the different products from the inside out. This is most evident at the hardware level, where apple’s hardware has been fruity since the early days. Even if it is a new iteration or the development of a new category, there will be a deep brand of “fruity” industrial design.

It’s not enough to unify the look. What Apple really wants is to unify the inside and the outside, which is to unify the experience.

Whereas industrial designs can be handed over to their own elite teams, systems can be copied from each other, but the software used by users is freely created by the vast number of developers. Surprisingly, Apple has done a good job of this, too. Superior quality is what many people think of apple’s software, compared to others.

To achieve this, Apple has done a lot of work that is not perceived by the average consumer.

In terms of design, Apple offers a set of constantly updated Human Interface Guidelines that detail all aspects of visual design. Before the App is developed and ready for distribution, Apple’s Review team reviews every App and determines whether or not it is allowed to be published in the App Store according to the App Store Review Guidelines. Even well-known apps that violate the Guidelines are removed from the App Store. For non-jailbroken mobile devices, the App Store is the only way to install apps, and controlling access to it filters the entire platform.

In addition to controlling the terminal, Apple is also looking at ways to increase the number of developers and improve the quality of individual apps. The approach is also very consistent with the principle of first thought — making development easier. So Swift came first, followed by SwiftUI. Apple wants to directly optimize the language itself and unify the development experience across all devices, making it easier for developers to pick up and turn ideas into running applications.

Swift2.0 was open source when it was launched in 2015. But Swift hasn’t been very successful on the back end or across platforms over the years. Swift is still referred to by default as the programming language used within the Apple platform, somewhat like OC’s successor. In fact, Apple itself has done a lot of work to promote the language, like SwiftUI, which is basically a milestone in apple’s promotion of the new language.

SwiftUI makes use of many of the Swift language features, especially those that have been added since 5.0. Many of the features in Swift 5.1, like Opaque Return Types, Property Delegate, and Function Builder, are almost customized for SwiftUI.

UI: The development dilemma

Prior to SwiftUI, Apple’s development frameworks for different devices were not interchangeable, and there was a significant difference in the knowledge that a mobile engineer needed to master from a desktop engineer.

Since iOS SDK2.0, mobile developers have been using UIKit for page development. The idea of UIKit inherits from the mature AppKit and MVC (Model-View-Controller) pattern, making some improvements, but not much change in essence. The UI includes everything the user can see, including static displays and dynamic animations.

Then came the Apple Watch, which introduced a new layout on its tiny screen. This stack-like logic, to some extent, can be seen as the unfinished business of SwiftUI.

Up to now, macOS development needs to use AppKit, iOS development needs to use UIKit, and WatchOS development needs to use stack. Such fragmented development experience will undoubtedly greatly increase the time and energy required by developers, and is not conducive to building cross-platform software experience.

Even on iOS, UIKit is not a perfect development solution.

The basic idea behind UIKit is that the ViewController does most of the work, coordinating the Model, the view, and the user interaction. This leads to huge sideeffects and a lot of states that, if not properly placed, can be mixed up in the ViewController, acting on views or logic at the same time, making state management more complex and, ultimately, unmaintainable and crashing the project. In other words, as new features and pages are added, the same ViewControlle r becomes more and more complex, easily creating bugs in unexpected places. Tangled code also greatly reduces readability and hurts maintenance and collaboration.

The characteristics of SwiftUI

SwiftUI’s solutions to existing problems can be found in many places, and current programming thinking has evolved over time to find answers to various software engineering problems in the development process.

In recent years, with the development of programming techniques and ideas, the use of declarative or functional approach to interface development has become more and more accepted and gradually become the mainstream. SwiftUI isn’t the first and won’t be the last framework to use declarative interfaces for development.

Declarative interface development

Abstract is an important concept in the world of computer science. There are many layers of abstraction that link them from the underlying binary logic gates to a programming language that humans can read and understand. By abstraction, the simple explanation is to reduce the complexity of explicit logic by encapsulating components, packaging and hiding the underlying details. Just like packaging transistors into logic gates, and functional objects in software engineering. In software development, engineers are responsible for implementing a specific feature, while others use it through open apis.

Declarative page development certainly adds another layer of abstraction to the layout that was used.

In THE UIKit framework, every element of the interface needs to be laid out by the developer, which involves a lot of calculation, such as changing the width and length of the interface or changing the visible area of the screen. This linear approach is called imperative programming. Take a line of text for example. What coordinates to place it in, how wide it is, where to break lines, how to break lines, how much font size it should be, how high it should be, and whether it needs to be reduced to make it fully visible are all questions that developers should consider and calculate when creating an interface. In the second year, users may be moving to larger screens and new features such as dynamic font adjustment, and the original application may have display problems without adaptation, requiring developers to go back and re-debug the application.

With SwiftUI, many of these variables are taken over by the system. All the developer has to do is intuitively tell the system to place an image, add a line of text on top of it, and add a button to the right. The system automatically renders the interface based on screen size, orientation, etc., and developers no longer need to do pixel-level calculations. This is called declarative programming.

Compare implementations of the same scenario interface

As a common List view, it’s called a TableView in UIKit and a List or Form in SwiftUI. To implement a List, SwiftUI simply declares that there is a List and the contents of each cell. In UIKit, you need to customize the content of each unit in a principal-agent way, and you need to set the number of rows and groups, the response to touches, the click process, and so on.

As you can see in Amos, another of my early projects, thousands of lines of code were needed to draw the home page.

Smart for different screen sizes

In addition to different screen sizes, SwiftUI can render buttons, dialog boxes, Settings, and more to match depending on the platform you’re running on. Because of the large amount of white space in statements, the system has more room to operate when developers don’t need to arrange every detail.

You can imagine if Apple came out with something new like glasses, maybe the same interface code would be displayed in a completely different way than it is on the iPhone.

Raising the level at which problems need to be addressed allows developers to focus more on the more important creative aspects.

Chaining calls modify properties

Chained calls, a feature of the Swift language, are used as a way to use functional methods. Functions can be called continuously like a chain, without breaking in between. This way developers can add attributes to the interface elements and arrange the details of the page elements in great detail if they wish.

In addition to the system prefab properties can be adjusted, developers can also customize. For example, combining different attributes such as font, size, line spacing, color, etc., can be combined into a text attribute called “heading”. Any time you want to set a line of text as a header, you can simply add this custom property.

Using this way of development can undoubtedly greatly avoid meaningless duplication of work, faster to build the application interface framework.

Componentization of interface elements

In theory, every complex view is made up of a large number of simple unit views. But function methods can be wrapped up so that they can only be retrieved when needed. The decoupling of page elements in UIKit is not easy, and is usually specific to a particular situation, which makes it difficult to migrate. Sometimes a landscape screen on a phone can confuse page elements, let alone componentize them.

SwiftUI’s layout features, however, make it easy to split complex view components. A single component can not only be combined freely, but can also be used on any platform of Apple to achieve cross-platform implementation.

I personally distinguish view components into base components, layout components, and functional components. The reason for SwiftUI’s interface is that instead of hosting UIVew controls with a ViewController like UIKit, everything is a view. This way of view assembly improves the flexibility and reusability of interface development.

Reactive programming framework Combine

When building complex interfaces, the flow of data has always been one of the most frustrating parts of instruction programming.

When you use UIKit, you use target-action or protocol-delegate patterns to exchange information, Use key-value Observing (KVO) or key-value Coding (KVC) to monitor for changes and read/write attributes. But even if developers are adept at using these tools, there is a great chance that they will fall into the trap of increasing application complexity. There is a lot of data flow that needs to be handled properly, such as notifying relevant pages to refresh when data changes are made, or having associated data recalculated.

Mobile cross-platform solutions such as React Native and Flutter, with their declarative UI writing style and strict data flow direction, can significantly reduce the thought burden on developers.

SwiftUI has clearly absorbed these modern programming ideas as well, enabling the management of a single data source with the help of another heavyweight system framework, Combine.

The core of reactive programming is to transform all events into asynchronous data streams, which is precisely the main function of Combine. Combine adopts the observer model, which corresponds to multiple observers who can subscribe to the content of interest separately. In SwiftUI’s interface layout process, the different views are the observers, subscribing to the associated properties and automatically rerendering when the data changes.

Single data source

In WWDC’s introductory video, the word “Source of truth” appears repeatedly, which can be interpreted as a single data Source in Chinese.

Complex UI structures have always created more complex data and logical management requirements, and updating the relevant interface components each time user interactions or data sources change can cause display problems.

In SwiftUI, however, by adding a keyword like @state to a property declaration, you can associate that property with an interface element and have the opportunity to decide whether to update the view after each data change. This allows all properties to be managed and calculated in one place, and eliminates the need for handwritten refresh logic. Since in SwiftUI, the interface state described by the developer is stored as a structure before the page is rendered, updating the interface destroys the structure of the previous state and generates a new state. In the process of drawing the interface, it will automatically compare whether there is any change in each attribute of the view. If there is any change, it will update the corresponding view to avoid global drawing and resource waste.

With reading and writing in one place, developers can design data structures better, add and subtract types more easily, and troubleshoot problems. You don’t have to worry about threads, atomic states, finding the latest data, and so on, before you decide to refresh the notification related interface

Compatible with UIKit

One of the biggest barriers to learning new technology for developers is what to do with the original project. But SwiftUI does a pretty good job of this. Since this is a newly released framework, the UI components are not complete. When SwiftUI does not provide similar functionality, it is possible to encapsulate the existing parts of UIKit and provide SwiftUI with them. All you need to do is follow the UIViewRepresentable protocol. In contrast, in existing projects, you can use SwiftUI to create only part of the UI.

Of course, the styles of the two codes are very different, but there is almost no performance penalty in using them. By the end of the product, users will not be able to tell the difference between the two interface frameworks.

Look at SwiftUI from a developer’s perspective

Back to the original question: Is SwiftUI as idealistic as Apple claims?

When WWDC launched SwiftUI, I was struck by one sentence: “99% of the original layout, no matter how complex, can now be built with SwiftUI.” I saw this again from experienced developers when I was looking up whether SwiftUI could take on large projects.

In my experience for a period of time, and eventually a SwiftUI development app on the shelves, I think this sentence is not a problem, but the premise of programming this matter requires a more basic and in-depth understanding.

This is a bit like how we feel when we study some good third-party libraries. When we write code in Xcode, some people write plain water, while others write dark magic. You learn the same language features, but you use them differently because of how deep you understand them. You can’t make a great app with just a few standard built-in components, even if you have as many components as UIKit. A lot of the time, it’s still a matter of business needs, or some unique imagination to make the best interface.

What does this mean for individual developers?

How high SwiftUI’s ceiling is will depend on future annual updates. But it is a fact of life that the lower limit is much lower than the previous UIKit. The lower limit here refers to the difficulty of learning. Since descriptive layouts are very close to our reading habits, telling the system to place a picture in the middle of the page is as intuitive as telling someone to place an apple in the middle of the table. Many UI designers I know have mastered SwiftUI through self-study in a short period of time and built demos that can be used directly on real machines.

It is very meaningful to reduce the learning cost. It can not only increase the number of developers and reduce the learning threshold, but also in terms of learning itself, it is more important for beginners to feel a sense of achievement and clear learning direction in the long run than the learning efficiency in a short time. Only by cultivating enough interest at the beginning, can we study deeper and more difficult problems on our own initiative at a later stage.

SwiftUI and Combine draw heavily on the Swift syntax, especially with the few updates since 5.0, which seem to be tailored to both systems and frameworks. Despite making Swift open source, Apple certainly has a firm grip on the language’s development. The synergy between the two frameworks and programming languages seems to give developers a sense of the potential of integrating hardware and software. Whatever Swift’s legacy may be, there is no doubt that Apple’s system will be able to integrate software experiences across the consumer spectrum.

As long as you use SwiftUI, the system will support automatic switching between day and night mode by default; Auto-adapts between screens of various sizes; Add Haptic Touch or animation to any control. A separate and complete experience on the Apple Watch; Converting an iOS app to a macOS native app will support first-party new features as quickly as possible. This deep support for Apple hardware is something that those cross-platform solutions can’t achieve anyway. You can see that some well-known applications using third-party frameworks, such as landscape, night mode, widgets, and other basic features, have been slow to adapt.

So SwiftUI is great for small studios and indie developers to get new ideas off the ground quickly and to the market, to really be agile. Gaining a foothold in a niche segment of the market in this way also allows more people to feel what it’s like to write programs, and even make money.

Open source my learning experience

In the last part, I will share some of my own learning process and related resources for those who are also interested in developing SwiftUI.

The first thing to learn is Swift programming language, it and OC between the difference is very big, there is no shortcut to learn, directly read the official tutorial, compared with the example to write it again. There are several very good Chinese websites, you can study together. Basically do not need to buy a book specially, instead as on direct computer read the convenience that knocks come.

  1. website
  2. SwiftGG
  3. Making localization libraries

Once you have a general understanding of the language, you can begin to learn SwiftUI, and if you run into problems, you can repeatedly go back to the previous material. Many neglected details, or at the first glance did not have the concept of the part, combined with specific cases can have a more thorough understanding.

  1. Stanford CS193P· spring 2020: this course strongly push, I was learning OC to see it, now to SwiftUI or first see this, system and detailed, combined with the case and programming process of small skills, is a good introduction course.
  2. Open Xcode and learn how to do a SwiftUI app from beginning to end.
  3. Hacking with Swift: This is a sharing website built by a foreign programmer in his spare time, with lots of articles to read and a course called “100 Days of SwiftUI” for beginners to follow.
  4. Official Apple documentation: The documentation is a must read, although many of them lack engineering details, they cover a lot of conceptual content, you can see how the official thinking, and have a lot of specific mechanism parameters. I have a habit of translating all relevant documents if a project involves a framework.
  5. Stack Overflow: This site is dedicated to problematic queries. Search for error codes or keywords in Google and you’ll get the answers.
  6. Read the source code for the SwiftUI library.

Basically, if you can complete it successfully, you can start your own project. The key to improving development is to write your own code and keep reading and learning. The key ability in the early stages is English, and in the later stages you need a real interest and some math ability.