swiftui
Saying welcome to Model View ViewModel (MVVM) pattern using SwiftUI.
对使用SwiftUI的模型视图ViewModel(MVVM)模式表示欢迎。
If you’ve heard of SwiftUI but you have never dealt with this framework, you’re in the right place.
如果您听说过SwiftUI,但从未使用过此框架,那么您来对地方了。
During the 2019 WWDC, Apple introduced SwiftUI, a new framework that, in the plans of the American company, will change the way applications are made. SwiftUI will eventually replace the existing UIKit. Actually SwiftUI is a wrapper of UIKit but despite this the differences between the two are many, just think that storyboards will no longer exist and that a new procedural paradigm is applied allowing you to make the code easily exportable on all Apple devices.
在2019年的WWDC期间,苹果推出了SwiftUI,这是美国公司计划的新框架,它将改变应用程序的制作方式。 SwiftUI最终将取代现有的UIKit。 实际上,SwiftUI是UIKit的包装,但是尽管两者之间存在很多差异,但请以为故事板将不复存在,并且应用了新的程序范式,使您可以轻松地在所有Apple设备上导出代码。
https://developer.apple.com/documentation/swiftui
https://developer.apple.com/documentation/swiftui
Precisely these novelties make SwiftUI to have a great potential and it is thought that in the coming years it can definitively replaces its ancestors , precisely for its ease in writing code, due to the imperative paradigm, like Python and Ruby, making the very same code to adapt to the various screens of the devices.
正是由于这些新颖性,SwiftUI才具有了巨大的潜力,而且由于Python和Ruby之类的命令式范式,使得SwiftUI可以在未来几年内最终取代其祖先,正是因为它易于编写代码。以适应设备的各种屏幕。
We would love to say it’s enough for the differences, but here comes the big one: when you use swiftUI you abandon the classic Model-View-Controller (MVC) design pattern in favour of the latest Model-View-ViewModel (MVVM)
我们很乐意说这足以满足不同需求,但是其中有一个重要意义:使用swiftUI时,您放弃了经典的Model-View-Controller(MVC)设计模式,而使用了最新的Model-View-ViewModel(MVVM)
设计模式: (The design pattern:)
This pattern, developed by Ken Cooper and Ted Peters of Microsoft, was designed to simplify event driven programming.
由Microsoft的Ken Cooper和Ted Peters开发的此模式旨在简化事件驱动的编程。
Its scheme, allows us to immediately notice its four fundamentals elements:
它的方案使我们可以立即注意到其四个基本要素:
Model: MVVM is an implementation of the Domain Model pattern. The Model will include our data structure and business logic and validation logic.
模型 :MVVM是域模型模式的实现。 该模型将包括我们的数据结构以及业务逻辑和验证逻辑。
View: View will be responsible for defining the structure, layout and appearance of what the user sees on the screen.
视图:视图将负责定义用户在屏幕上看到的内容的结构,布局和外观。
ViewModel : the ViewModel will be the intermediary between the view and the model. It is responsible for the management of the logic of the view. Generally, the view model interacts with the model by invoking methods in the model classes. The view model will then provide the model data in such a way that the view can use it easily.
ViewModel :ViewModel将成为视图和模型之间的中介。 它负责视图逻辑的管理。 通常,视图模型通过调用模型类中的方法与模型交互。 然后,视图模型将以一种视图可以轻松使用的方式提供模型数据。
DataBinding : Data binding is a fundamental mechanism for this pattern: with this operation the view model and the view are kept constantly synchronized, typically through a declarative syntax in the view itself. This implies that changes to the data made by the user through a view will be automatically reported in the view model, without giving this responsibility to the developer.
DataBinding :数据绑定是此模式的基本机制:通过此操作,通常通过视图本身中的声明性语法,使视图模型和视图保持恒定同步。 这意味着用户通过视图对数据所做的更改将自动在视图模型中报告,而无需将此责任交给开发人员。
The question that this article wants to answer is the following: Is SwiftUI ready to handle a complete application? Or is he still too young and needs more time to express his true potential?
本文要回答的问题如下:SwiftUI准备好处理完整的应用程序了吗? 还是他还太年轻,需要更多时间来表达自己的真正潜力?
我们在SwiftUI中的第一个应用程序: (Our first application in SwiftUI:)
To try to answer these questions we decided , as students of the Apple Developer Academy in Naples, to develop a full SwiftUI application to better understand its potential and the main differences with UIKit. This application is called Planooze: it is an app for tourists that will show you the shortest path to reach all the points of interest that you intend to visit. In addition to using SwiftUI, during this project we used other frameworks such as MapKit, CoreLocation, CoreData and CloudKit.
为了尝试回答这些问题,我们决定以那不勒斯苹果开发人员学院的学生身份,开发一个完整的SwiftUI应用程序,以更好地了解其潜力以及与UIKit的主要区别。 该应用程序称为Planooze:这是一款针对游客的应用程序,它将向您显示最短的路径,以达到您打算访问的所有景点。 除了使用SwiftUI,在此项目中,我们还使用了其他框架,例如MapKit,CoreLocation,CoreData和CloudKit。
We will focus in particular on the part of MapKit and CoreLocation, which manages the creation of the routes.
我们将特别关注MapKit和CoreLocation部分,它们管理路线的创建。
Taking in account what we previously discussed about the framework itself our project met these four components : Model, ViewModel, View and Data Binding.
考虑到我们之前讨论的有关框架本身的内容,我们的项目满足了以下四个组成部分:模型,ViewModel,视图和数据绑定。
Let’s examine them in more detail:
让我们更详细地研究它们:
Model: Our model is made of Itinerarymodel.swift, Searchinput.swift and Locationmanager.swift.
模型:我们的模型由Itinerarymodel.swift,Searchinput.swift和Locationmanager.swift组成。
Itinerarymodel.swift is a data structure that allows you to keep track of the points of interest that are chosen and then calculate the shortest path.
Itinerarymodel.swift是一个数据结构,可让您跟踪所选的兴趣点,然后计算最短路径。
SearchInput.swift, on the other hand, manages the search for points of interest. The search for points of interest can be done in two ways: the first way through the search by names, the second through filters by the category of points of interest (café, museum, ect.).
另一方面,SearchInput.swift管理搜索兴趣点。 搜索兴趣点的方法有两种:一种是通过名称进行搜索,另一种是通过按兴趣点类别(咖啡馆,博物馆等)进行过滤。
Locationmanager.swift finally, is the model that allows us to take our current position.
最后,Locationmanager.swift是允许我们采用当前位置的模型。
ViewModel: our Viewmodel is the Mapviewmodel.swift file .
ViewModel:我们的Viewmodel是Mapviewmodel.swift文件。
The Viewmodel will return an element of the view that in our case is a MKMapView.
Viewmodel将返回视图的元素,在本例中为MKMapView。
Here the Mapviewmodel can inherit the UIViewRepresentable or UIViewControllerRepresentable protocol and to do this we have to write some code.
在这里,Mapviewmodel可以继承UIViewRepresentable或UIViewControllerRepresentable协议,为此,我们必须编写一些代码。
No need to overthink about, just do it.
无需多想,就去做。
First we need to declare a coordinator. The coordinators in swiftUI are designed to act as the delegate for UIKit ViewControllers. In fact it will be a class that can extend the MKMapViewDelegate in our case .
首先,我们需要声明一个协调器。 swiftUI中的协调器旨在充当UIKit ViewController的委托。 实际上,在我们的案例中,它将是一个可以扩展MKMapViewDelegate的类。
A delegate is the protocol responsible for handling the data source of your model.
委托是负责处理模型数据源的协议。
In the coordinator we will have a reference to our ViewModel and we will define all the functions that will allow us to invalidate the view in order to update it in response to changes in the model. In addition we need to define a makeCoordinator() function that returns the coordinator creating a communication between the ViewModel and the Coordinator itself.
在协调器中,我们将引用我们的ViewModel,并将定义所有函数,这些函数将使我们能够使视图无效,以便根据模型的更改对其进行更新。 另外,我们需要定义一个makeCoordinator()函数,该函数返回协调器,从而在ViewModel和协调器本身之间建立通信。
The make(context: _ ) and update(view: _, context: _ ) functions are the functions that are called respectively when the view is created for the first time and when it needs to be updated.
make(context:_)和update(view:_,context:_)函数是在首次创建视图和需要更新视图时分别调用的函数。
View: In our project we have three views that are shown to a final user: ContentView.swift, PoiDetailsView.swift and PlaceListView.swift.
视图:在我们的项目中,我们向最终用户显示了三个视图:ContentView.swift,PoiDetailsView.swift和PlaceListView.swift。
The ContentView will be responsible for showing the MKMapView and the PlaceListView.swift. When you tap on a point of interest a modal called PoiDetailsView.swift will be showed giving you the chance to add a point of interest to your own path and to calculate the best itinerary.
ContentView将负责显示MKMapView和PlaceListView.swift。 当您点击一个兴趣点时,将显示一个名为PoiDetailsView.swift的模式,使您有机会在自己的路径中添加一个兴趣点并计算最佳行程。
Data Binding: As we have previously mentioned, data binding is a fundamental operation for this pattern. In order to communicate viewModel and view we need these binding.
数据绑定:如前所述,数据绑定是此模式的基本操作。 为了传达viewModel和view,我们需要这些绑定。
In swift the data binding can be expressed through various tags:
快速的数据绑定可以通过各种标签表示:
- @Binding: allows us to declare that a value actually comes from elsewhere and must be shared within these contexts; @Binding:允许我们声明一个值实际上来自其他地方,并且必须在这些上下文中共享;
- @ObservedObject and @EnvironmentObject: they are two properties similar to that of binding, only that they have a greater sharing scope , potentially making an object with one of these 2 tags to be shared between all the views of the application; @ObservedObject和@EnvironmentObject:它们是与绑定相似的两个属性,只是它们具有更大的共享范围,可能使具有这两个标记之一的对象在应用程序的所有视图之间共享;
- @Published and ObservableObject protocol: allows us to create observable objects that announce automatically when changes occur. All classes that are compliant with the Observableobject protocol can be used within SwiftUI and notify when its values have change so that you know when to update the view. @Published和ObservableObject协议:允许我们创建可观察对象,这些对象在发生更改时自动宣布。 可以在SwiftUI中使用所有与Observableobject协议兼容的类,并在其值更改时通知您,以便您知道何时更新视图。
- @State: it’s a tag that allows us to check the value of our Binding ,ObservedObject or EnvironmentObject. SwiftUI decides whether to invalidate the view or not if the value of the @State tag changes or not. @State:这是一个标签,允许我们检查Binding,ObservedObject或EnvironmentObject的值。 如果@State标记的值更改,SwiftUI决定是否使视图无效。
Through these tags we can make the ViewModel and the View communicate.
通过这些标签,我们可以使ViewModel和View进行通信。
During the development of our application, we realised that SwiftUI can already be a valid alternative to UIKit: it allows developers to focus more on the application’s implementation logic rather than “wasting” time caring about things like auto-layout. So while it’s still young as a framework, our advice is to try it out. Perhaps the only problem we encountered is the lack of examples of code, but with the time passing by , the available documentation will surely become wider.
在我们的应用程序开发过程中,我们意识到SwiftUI已经可以替代UIKit:它使开发人员可以将更多的精力放在应用程序的实现逻辑上,而不是“浪费时间”在意诸如自动布局之类的事情。 因此,尽管它还只是一个框架,但我们的建议是尝试一下。 也许我们遇到的唯一问题是缺少代码示例,但是随着时间的流逝,可用的文档肯定会越来越广泛。
We hope that this article will work in this direction.
我们希望本文能够朝这个方向努力。
将TestFlight链接到Planooze: (Link TestFlight to Planooze:)
链接到Planooze中等文章: (Link to Planooze medium article:)
https://medium.com/@antonellacirma/71f4da6b5388
https://medium.com/@antonellacirma/71f4da6b5388
组: (Group:)
Simone Punzo
西蒙妮·庞佐(Simone Punzo)
Mauro Zobel(https://www.linkedin.com/in/mauro-zobel-321120196/)
毛罗·佐伯(Mauro Zobel)( https://www.linkedin.com/in/mauro-zobel-321120196/ )
Giovanni Erpete(https://www.linkedin.com/in/giovanni-erpete-51035617b/)
乔瓦尼·埃尔佩特(Giovanni Erpete)( https://www.linkedin.com/in/giovanni-erpete-51035617b/ )
Giovanni Di Guida(https://www.linkedin.com/in/giovanni-di-guida-228287165/)
乔瓦尼·迪·吉达( https://www.linkedin.com/in/giovanni-di-guida-228287165/ )
Simone De Crescenzo(https://www.linkedin.com/in/simone-de-crescenzo-4081461b0/)
Simone De Crescenzo( https://www.linkedin.com/in/simone-de-crescenzo-4081461b0/ )
Mirella Cetronio(https://www.linkedin.com/in/mirellacetronio/)
Mirella Cetronio( https://www.linkedin.com/in/mirellacetronio/ )
Antonietta Cirma(https://www.linkedin.com/in/antonella-cirma-814295114/)
Antonietta Cirma( https://www.linkedin.com/in/antonella-cirma-814295114/ )
链接到该项目的GitHub存储库: (Link to GitHub repo for the project:)
swiftui