swiftui_生产中的SwiftUI

swiftui

It’s been a month (at the time of writing) since my app Soccer Puzzles has been live on the App Store and a day since its basketball sibling Basketball Puzzles made it there too. They are both developed in SwiftUI. A month of being live on the App Store can give some input on how Apple’s new UI framework is performing on the App Store.

我的应用程序《 足球拼图》已经在App Store上线了一个月(在撰写本文时),距篮球兄弟版《 篮球拼图》也在那里发布了一天。 它们都是在SwiftUI中开发的。 在App Store上直播一个月可以为Apple新的UI框架在App Store上的表现提供一些输入。

TL; DR (TL;DR)

Yes, SwiftUI can be used in production apps and it works pretty well most of the time. However, there are some glitches. For more details, please read on.

是的,SwiftUI可以在生产应用程序中使用,并且在大多数情况下效果都很好。 但是,存在一些故障。 有关更多详细信息,请继续阅读。

应用程式 (The App)

Although it’s a trivia/quiz game, the app itself is not trivial. It has around 10K lines of code, with a sync mechanism, in-app purchasing, game logic (unlocking levels, achievements), and a lot of data passing through it. It also has a drawing engine that can draw different football (and basketball) formations based on their positions.

尽管这是一个琐事/测验游戏,但该应用程序本身并不简单。 它有大约1万行代码,并带有同步机制,应用内购买,游戏逻辑(解锁级别,成就)以及大量数据通过。 它还具有绘图引擎,可以根据其位置绘制不同的足球(和篮球)队形。

Image for post

足球(足球)101 (Football (Soccer) 101)

For those who don’t watch football much, a formation is similar to the architecture of an app — how the team is structured and organized together. There’s a separation of concerns. For example, the goalkeeper and the defence’s main goal is to stop the opposition from scoring goals. They are behind (data model), they usually give the team their identity and strength, and the captain frequently comes from that part of the pitch. The strikers (views) are in charge of scoring goals. Everyone sees them and they’re usually the heroes, but they can’t do much without the support of the team. The midfielders (controllers) connect everything together and bring the dynamics to the game.

对于那些不太看足球的人来说,其组成类似于应用程序的架构-团队的结构和组织方式。 有分离的关注点。 例如,守门员和防守方的主要目标是阻止对方得分。 他们落后(数据模型),他们通常赋予球队身份和实力,而队长经常来自球场的那一部分。 前锋(意见)负责进球。 每个人都看到他们,他们通常是英雄,但没有团队的支持,他们将无济于事。 中场(控制器)将一切联系在一起,为比赛带来动力。

There are many ways to organize these parts, like the classic 4-4-2 (MVC?), the most popular 4-3-3 (MVVM?), and the more complicated ones with many layers like 4-1-2-1-2 (VIPER?). Here are some visual examples, but there can be many different combinations:

有许多方法可以组织这些部分,例如经典的4-4-2(MVC?),最受欢迎的4-3-3(MVVM?)以及具有4-1-2-多层的更复杂的部分1-2(VIPER?)。 这是一些直观的示例,但是可以有许多不同的组合:

Image for post
Image for post
Image for post

优点 (The Pros)

SwiftUI is perfect for this task. If you split the area into different parts (and sub-parts) for the goalkeeper, defence, midfield, and attack and just use spacers and offsets, you can achieve a very nice representation of a football formation without doing too many calculations. If I had to do this in UIKit, it was going to be a lot of work.

SwiftUI非常适合此任务。 如果将区域分为守门员,防守,中场和进攻的不同部分(和子部分),并且仅使用间隔和偏移量,则无需进行过多的计算就可以很好地表示足球阵型。 如果我必须在UIKit中执行此操作,这将需要大量工作。

As a bonus, while you go through the questions, there are some nice animations for which you just have to call the animate modifier. Again, doing this in UIKit would’ve been a lot more work. The questions themselves have many different representations depending on the question type. Using SwiftUI’s composition approach, it was very easy to reuse components, move them around, and so on.

另外,当您浏览问题时,您只需调用animate修改器即可获得一些漂亮的动画。 同样,在UIKit中执行此操作会做更多工作。 根据问题类型,问题本身具有许多不同的表示形式。 使用SwiftUI的组合方法,重用组件,移动组件等等非常容易。

Another point is the design and UX that was prototyped and created along the way. At one point, one view was at the top, then it was moved to the bottom. In SwiftUI, that’s a very fast change, while you would have to mess with constraints the whole time in UIKit.

另一点是在此过程中原型和创建的设计和UX。 在某一时刻,一个视图位于顶部,然后移至底部。 在SwiftUI中,这是一个非常快速的更改,而在UIKit中,您将不得不一直困扰着约束。

Working with Combine was also a very nice experience. It helped a lot in the sync mechanism, where I created custom publishers for my repositories. The repositories would first fetch and return some cached or bundled data and then sync with Firebase to get the latest changes. For a trivia app where there can’t be mistakes in the data, this was very helpful.

与Combine一起工作也是非常不错的经历。 它在同步机制中大有帮助,在同步机制中,我为存储库创建了自定义发布者。 存储库将首先获取并返回一些缓存或捆绑的数据,然后与Firebase同步以获取最新更改。 对于在数据中不会出现错误的琐事应用程序,这非常有帮助。

Here’s a glimpse of how I did the repo subscription:

这是我如何进行回购订阅的一瞥:

Image for post

I used the standard MVVM pattern in this app, and Combine fits in very nicely there. The view models were @ObservableObjects that were created from the outside and passed to the view. Therefore, I won’t do any changes for iOS 14 and there’s no need to use the new @StateObject.

我在此应用程序中使用了标准MVVM模式,并且Combine非常适合在那里。 视图模型是@ObservableObjects ,它们是从外部创建并传递给视图的。 因此,我不会对iOS 14进行任何更改,也不需要使用新的@StateObject

A nice way to do this is to use a hierarchy of dependency containers. Having containers that create the views and view models is also very useful while using the SwiftUI previews feature because views and view models can have complex initialisation methods. For example, if I want to create a FootballTeamView that has a FootballTeamViewModel that has a PlayersRepository, AnswersRepository, and UsersService, and those also have other dependencies, the previews can get very messy.

一个很好的方法是使用依赖容器的层次结构。 在使用SwiftUI预览功能时,拥有创建视图和视图模型的容器也非常有用,因为视图和视图模型可能具有复杂的初始化方法。 例如,如果我要创建一个包含FootballTeamView ,该FootballTeamViewModel包含一个PlayersRepositoryAnswersRepositoryUsersService ,并且它们还具有其他依赖项,则预览可能会变得非常混乱。

What I did first was use protocols for all the dependencies in the types mentioned above. Then, I created a PreviewsContainer that implements PreviewProvider. In this provider, I created mock repositories and data that is displayed in the previews. Therefore, creating dependencies in the SwiftUI previews was very easy. The good thing is that since the PreviewsContainer implements PreviewProvider, it will not go in the release version of your app. Another benefit is that you can use those same mock implementations in your unit tests.

我首先要做的是使用协议来处理上述类型中的所有依赖项。 然后,我创建了一个实现PreviewProviderPreviewsContainer 。 在此提供程序中,我创建了模拟存储库和在预览中显示的数据。 因此,在SwiftUI预览中创建依赖项非常容易。 好消息是,由于PreviewsContainer实现了PreviewProvider ,它将不会出现在应用程序的发行版中。 另一个好处是您可以在单元测试中使用那些相同的模拟实现。

These are some of the benefits of working with SwiftUI/Combine apart from the fun factor, which — for a pet project done after work hours — is what drives you.

除了有趣的因素以外,这些就是使用SwiftUI / Combine的一些好处,而有趣的因素(对于下班后完成的宠物项目而言)是驱动您的因素。

缺点 (The Cons)

Of course, SwiftUI is not perfect. The thing I don’t like the most is the minor version differences and bugs that can magically appear — especially in the 13.0/13.1 versions. Therefore, you should test on all minor versions and even on multiple devices.

当然,SwiftUI并不完美。 我最不喜欢的是次要的版本差异和可能神奇地出现的bug,尤其是在13.0 / 13.1版本中。 因此,您应该在所有次要版本上甚至在多个设备上进行测试。

Here’s one concrete example I found after going to production and looking at crash logs: There was a crash on a few iOS 13.1.2 devices. The crash logs were not very helpful. Some AttributeGraph crashed with no further details. However, if you pick that same iOS/iPhone combination, you can easily reproduce the crash in Xcode. Even then, it’s really hard to debug and figure out what’s the problem.

这是我在投入生产并查看崩溃日志后发现的一个具体示例:一些iOS 13.1.2设备发生了崩溃。 崩溃日志不是很有帮助。 一些AttributeGraph崩溃了,没有更多详细信息。 但是,如果选择相同的iOS / iPhone组合,则可以轻松地在Xcode中重现崩溃。 即使这样,调试和找出问题的根源还是非常困难的。

The brute-force approach was to comment out things until it stops crashing. It turned out that after I added an ID modifier to the list, the crash disappeared.

暴力手段是注释掉事物,直到它停止崩溃为止。 原来,在将ID修饰符添加到列表后,崩溃消失了。

Another issue was the present modifier, which also had problems in the iOS 13.1 version. I have a loading view that appears during in-app purchases or ad loading. However, on those devices, I’ve only seen a white screen, which was not very helpful for the users (not being able to earn more coins to play the game) or for me (I wasn’t able to monetize the app for those users).

另一个问题是present修改器,它在iOS 13.1版本中也有问题。 我在应用内购买或广告加载期间显示加载视图。 但是,在这些设备上,我只看到了白屏,这对用户(无法赚取更多金币来玩游戏)或对我(我无法通过该应用获利)这些用户)。

Again, it was very hard to debug this and the quick solution I came up with was very silly — not using the present modifier for those versions (if someone knows something better, please share). You can use a conditional modifier for such cases.

同样,调试起来非常困难,而我想出的快速解决方案非常愚蠢-不为这些版本使用present修饰符(如果有人知道更好的话,请分享)。 您可以在这种情况下使用条件修饰符。

Image for post

Other glitches I’ve seen involved the titles of the navigation bar. Sometimes, the previous title doesn’t disappear. It’s merged with the current title and you can’t read anything. Another thing is the animation of text views. Sometimes, there are ellipses that appear and never go away. To solve this, you would need to explicitly disable the animation of the text views.

我见过的其他故障还涉及导航栏的标题。 有时,上一个标题不会消失。 它与当前标题合并,您什么也看不懂。 另一件事是文本视图的动画。 有时,会出现椭圆形,并且永远不会消失。 要解决此问题,您需要显式禁用文本视图的动画。

At the moment, the app is more stable and there’s only a crash with no more details on how to fix it maybe once every few days. For example, just this: AttributeGraph: 0x1cb4e3000 + 205760. In the stack trace, there’s a call to main method of the app and crash in GraphicsServices.

目前,该应用程序更稳定,并且只有几次崩溃,没有关于如何修复它的更多详细信息,也许每隔几天一次。 例如,仅此: AttributeGraph: 0x1cb4e3000 + 205760 。 在堆栈跟踪中,有一个对应用程序main方法的调用,导致GraphicsServices崩溃。

Let’s hope such issues will not appear in newer SwiftUI versions.

我们希望这些问题不会出现在较新的SwiftUI版本中。

While reading online about why SwiftUI is not ready for production, there were other things mentioned, like missing some standard UI components and not having navigation stack info. For the first issue, you can easily wrap the UIKit equivalents or even build your own custom components. For the navigation stack, since Apple doesn’t provide it even in iOS 14, maybe it’s time to rethink how we design navigation in our apps.

在在线阅读有关SwiftUI为什么尚未准备好投入生产的信息时,还提到了其他事情,例如缺少一些标准的UI组件以及没有导航堆栈信息。 对于第一个问题,您可以轻松包装等效的UIKit甚至构建自己的自定义组件。 对于导航堆栈,由于Apple即使在iOS 14中也没有提供导航堆栈,也许是时候重新考虑我们如何在应用程序中设计导航了。

结论 (Conclusion)

SwiftUI can be used for production, but you need to keep in mind the glitches mentioned above. I’m pretty sure they will be solved over time. Maybe some of them are already fixed in iOS 14. Yes, you will have the occasional crash and a one-star rating, but that’s nothing compared to having constant crashes for a few hours because you’ve included a third-party SDK (you know which one).

SwiftUI可以用于生产,但是您需要记住上面提到的故障。 我很确定他们会随着时间的推移解决。 也许其中一些问题已在iOS 14中修复。是的,您会偶尔崩溃并获得一星评级,但这与连续几个小时连续崩溃相比没有什么意义,因为其中包含了第三方SDK(知道哪一个)。

Therefore, if you start a new project now — even a more complex one — I believe SwiftUI is the way to go. I did that for a bigger project at work that I started a month ago, and so far, so good.

因此,如果您现在开始一个新项目(甚至更复杂的项目),我相信SwiftUI是您的理想之选。 我这样做是为了一个月前开始的更大的工作项目,到目前为止,一切都非常好。

What are your thoughts on the topic? Is SwiftUI ready for production?

您对该主题有何看法? SwiftUI准备好投入生产了吗?

You can also check out my SwiftUI-powered puzzle apps, Soccer Puzzles and Basketball Puzzles, and find some more SwiftUI bugs.

您还可以查看由SwiftUI驱动的拼图应用, 足球拼图篮球拼图 ,并找到更多SwiftUI错误。

Thanks for reading!

谢谢阅读!

翻译自: https://medium.com/better-programming/swiftui-in-production-678af4db19c9

swiftui

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值