Bom Dia a todos. Meu nome é Anna Zharkova, sou uma desenvolvedora móvel líder da Usetech.Sobre a tecnologia SwiftUI, anunciada pela Apple no ano passado WWDC 2019, muito foi dito. Em princípio, já existe material suficiente sobre seus recursos, o que há sob o capô e como usá-lo para uma interface de usuário rápida e bonita.
Ofereço uma curta série de artigos sobre como usar essa estrutura na vida real e em aplicações reais, e não em construtores de sanduíche de abacate. E para tornar tudo sério e maduro, veremos como fazer com que nosso aplicativo SwiftUI esteja em conformidade com os princípios de arquitetura e código limpos.Mas vamos começar com o básico. Esta parte será apenas uma introdução e informações básicas. Portanto, se você já está familiarizado com esses recursos do SwiftUI, vá para as seguintes partes:parte 2 (como trabalhar com bibliotecas prontas no UIKit)parte 3 (aqui sobre arquitetura)parte 4 (aqui sobre navegação)Se você ainda não se conhece, continue lendo alguns minutos)Os principais recursos do desenvolvimento declarativo na nova estrutura são um afastamento do uso direto do UIViewController, UIView e substituição por estruturas que implementam o protocolo View. Todos os componentes da parte visual também são descritos usando sintaxe declarativa e estão localizados dentro da propriedade do corpo principal de cada Visualização. Configurações, estilização e customização de componentes, a navegação entre o modo de exibição na tela também é definida usando a sintaxe declarativa.Por exemplo, este código descreve uma exibição para uma lista de notícias, clicando no qual uma tela é aberta com uma exibição de notícias separada:struct NewsListView: View{
    @State var data: [NewsItemMock]
    
    var body: some View {
        NavigationView{
        List(data) { item in
            NavigationLink(destination:NewsItemView(item:item)) {
            NewsItemRow(data: item)
            }
        }
    }
}
O SwiftUI usa o ViewBuilder, um designer de interface declarativo baseado no Functional Builder. Esse mecanismo apareceu no Swift 5.1 e permite agrupar elementos em uma determinada matriz dentro de um bloco de fechamento, por exemplo, um objeto pai. Um exemplo do uso do ViewBuilder é apresentado no slide. Simplesmente colocamos os controles View na ordem em que precisamos, por exemplo, dentro de uma pilha vertical ou horizontal, sem usar addSubview, e ao compilar o SwiftUI, ele próprio adiciona e agrupa elementos em um contêiner pai mais complexo.E aqui está o código:
          VStack {
            HStack {
                VStack(alignment: .leading,spacing: 10) {
                    HeaderText(text: data.title ?? "")
                    SubheaderText(text: data.description ?? "")
                    SmallText(text: data.publishedAt?
                                   .formatToString("dd.MM.yyyy") ?? "")
                }
               ThumbImage(withURL: data.urlToImage ?? "")
             }
convertido em um item da lista de 3 campos de texto e uma imagem:Embora o SwiftUI negue o conceito de um UIViewController, o ponto de entrada para o aplicativo é o UIHostingController, no qual a exibição exibida é passada e incorporada. Na verdade, a nova tecnologia é um complemento do UIKit:
@available(iOS 13.0, tvOS 13.0, *)
open class UIHostingController<Content> : UIViewController where Content : View {
    public var rootView: Content
    public init(rootView: Content)
A propósito, todos os controles SwiftUI são análogos declarativos dos controles UIKit.Por exemplo, VStack, HStack são análogos do UIStackView vertical e horizontal usual, respectivamente. A lista é UITableView, o texto é UILabel, o botão é UIButton, a imagem é UIImage etc.A conexão e a configuração dos controles são feitas de forma declarativa, usando os modificadores disponíveis. Os elementos são agrupados dentro dos análogos do UIStackView com algumas propriedades predefinidas.Além de alterar a maneira como a parte visual é descrita, o controle do fluxo de dados e o mecanismo de reação da interface do usuário estão mudando. A interface do usuário Swift é uma estrutura não dependente de evento. Essa. A visão é o resultado de uma função de certos estados, e não de uma sequência de eventos. A ação executada pelo usuário não altera a interface do usuário diretamente, não é possível alterar diretamente essa ou aquela exibição, adicionar ou remover controles. Primeiro, as propriedades ou variáveis de estado conectadas à View por meio de um ou outro Wrapper de propriedade (wrapper de propriedade) são alteradas .
Os principais Wrappers de propriedades usados são:1.Estado - usado para variáveis locais.
struct NewsItemRow: View {
    @State var title: String
    @State var  description: String
    @State var dateFormatted: String 
    @State var imageUrl: String 
    
    var body: some View {
        VStack {
            HStack {
                VStack(alignment: .leading,spacing: 10) {
                    HeaderText(text: title)
                    SubheaderText(text: description)
                    SmallText(text: dateFormatted)
                }
              ThumbImage(withURL: imageUrl)
            }
         }
     }
2. @Binding - um análogo de fraco, usado ao passar uma referência a um valor.Usamos quando mais de uma visualização depende de qualquer propriedade. Por exemplo, se queremos passar o valor para a visualização original a partir da visualização do segundo nível.
struct FirstView: View {
    @State var isPresented: Bool = true
    
    var body: some View {
        NavigationView {
            NavigationLink(destination:
            SecondView(isPresented: self.$isPresented)) {
                Text("Some")
            }
        }
    }
}
struct SecondView: View {
    @Binding var isPresented: Bool
    
    var body: some View {
        Button("Dismiss") {
            self.$isPresented = false
        }
    }
}
3. @EnvironmentObject - transferindo objetos entre o View4. @ObjectBinding, @ObservableObject - usado para rastrear alterações nas propriedades do modelo usando as ferramentas da estrutura Combine.
class NewsItemModel: ObservableObject,IModel {
   @Published var title: String
   @Published var  description: String
   @Published var dateFormatted: String 
   @Published var imageUrl: String 
}
Falaremos sobre ele mais tarde.Assim. Se quisermos mudar nossa Visualização, alteramos a propriedade, um anúncio com um dos Wrappers de propriedades. Em seguida, a exibição declarativa é reconstruída com todos os controles internos.Quando qualquer uma das variáveis de estado muda, a Visualização é reconstruída como um todo.Considere um pequeno exemplo. Temos algum tipo de tela, na barra de navegação, onde existe um botão para adicionar conteúdo aos favoritos. Para alterar a imagem do indicador nesse botão, usaremos o PropertyWrappers. Por exemplo, nesse caso, crie uma variável local e declare-a comoEstado:
struct NewsItemView: View {
@State var isFavorite: Bool 
....
Atribuiremos a alteração do valor da propriedade ao evento acionador que ocorre quando o botão é pressionado:struct NewsItemView: View{
    @State var isFavorite: Bool 
   
    var body: some View {
    NavigationView {
    VStack {
        Text("Some content")
       }
    }
     .navigationBarItems(trailing: Button(action: {
            self.isFavorite = !self.isFavorite
        }){
            Image(self.isFavorite ? "favorite" : "unfavorite")
           .frame(width: 20, height: 20, alignment: .topTrailing)
        })
   }
        
Assim, nossa Visão mudará:
e, em princípio, estas são todas as coisas básicas que você precisa saber sobre o SwiftUI para começar.Mas isso é suficiente para funcionar?Para criar interfaces de usuário descomplicadas a partir de controles simples sem estar vinculado ao Xib e storyboards, completamente.E para algo mais, não.Em primeiro lugar, nem todos os controles têm análogos no SwiftUI. Isso se aplica ao UIKit UISearchView, UICollectionView padrão e aos elementos de bibliotecas de terceiros.Em segundo lugar, não há (ou quase nenhuma, talvez alguém esteja fazendo isso agora) soluções de terceiros para trabalhar com o Data Flow SwiftUI.Portanto, você precisa adaptar as soluções existentes para aplicativos iOS padrão.Por favor, clique no link.