SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一)

版本记录

版本号 时间
V1.0 2021.01.12 星期二

前言

今天翻阅苹果的API文档,发现多了一个框架SwiftUI,这里我们就一起来看一下这个框架。感兴趣的看下面几篇文章。
1. SwiftUI框架详细解析 (一) —— 基本概览(一)
2. SwiftUI框架详细解析 (二) —— 基于SwiftUI的闪屏页的创建(一)
3. SwiftUI框架详细解析 (三) —— 基于SwiftUI的闪屏页的创建(二)
4. SwiftUI框架详细解析 (四) —— 使用SwiftUI进行苹果登录(一)
5. SwiftUI框架详细解析 (五) —— 使用SwiftUI进行苹果登录(二)
6. SwiftUI框架详细解析 (六) —— 基于SwiftUI的导航的实现(一)
7. SwiftUI框架详细解析 (七) —— 基于SwiftUI的导航的实现(二)
8. SwiftUI框架详细解析 (八) —— 基于SwiftUI的动画的实现(一)
9. SwiftUI框架详细解析 (九) —— 基于SwiftUI的动画的实现(二)
10. SwiftUI框架详细解析 (十) —— 基于SwiftUI构建各种自定义图表(一)
11. SwiftUI框架详细解析 (十一) —— 基于SwiftUI构建各种自定义图表(二)
12. SwiftUI框架详细解析 (十二) —— 基于SwiftUI创建Mind-Map UI(一)
13. SwiftUI框架详细解析 (十三) —— 基于SwiftUI创建Mind-Map UI(二)
14. SwiftUI框架详细解析 (十四) —— 基于Firebase Cloud Firestore的SwiftUI iOS程序的持久性添加(一)
15. SwiftUI框架详细解析 (十五) —— 基于Firebase Cloud Firestore的SwiftUI iOS程序的持久性添加(二)
16. SwiftUI框架详细解析 (十六) —— 基于SwiftUI简单App的Dependency Injection应用(一)
17. SwiftUI框架详细解析 (十七) —— 基于SwiftUI简单App的Dependency Injection应用(二)
18. SwiftUI框架详细解析 (十八) —— Firebase Remote Config教程(一)
19. SwiftUI框架详细解析 (十九) —— Firebase Remote Config教程(二)
20. SwiftUI框架详细解析 (二十) —— 基于SwiftUI的Document-Based App的创建(一)
21. SwiftUI框架详细解析 (二十一) —— 基于SwiftUI的Document-Based App的创建(二)

开始

首先看下主要内容:

了解如何使用AWS AppSync框架以简单且类型安全的方式在SwiftUIiOS应用中使用GraphQL API。内容来自翻译。

接着看下写作环境:

Swift 5, iOS 14, Xcode 12

最后看正文。

如今,大多数应用程序都需要后端才能工作。需要用户帐户吗?为此,您需要一个后端。要跨设备同步数据吗?猜猜是什么,您需要一个后端。有针对性的推送通知?后端……您明白了。

您可能之前曾听说过缩写BaaS (Back end as a service)BaaS工具通过使用简单的API与云存储服务集成。配置完成后,这些BaaS服务将以与其他任何API相同的方式运行,而几乎不需要或不需要任何前端知识。

在本教程中,您将使用Amazon的名为AppSyncBaaS产品以及Amplify框架向iOS应用添加后端组件。您将学习如何:

  • 安装AWS Amplify及其依赖项
  • 使用GraphQL实现模型并使用Amplify生成本地文件
  • 对数据执行CRUD操作
  • 将您的应用程序数据保存到AWS AppSync

您将通过使用SwiftUI实现待办事项应用程序来学习所有这些内容。该应用程序将允许您创建,删除和完成待办事项,同时保持应用程序的数据与AppSync云服务同步。该应用程序无论有没有互联网连接都可以使用!

打开启动文件夹中的RazeList.xcodeproj

RazeList可以帮助您在所有iOS设备上保持同步。这是您所有工作的真相之一,更重要的是,您所有的dones!学完本教程后,无论使用哪种设备,您都将永远知道自己在哪里工作。

Xcode中,构建并运行项目。

SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一)_第1张图片

目前,该项目不仅仅是问候。您将对此进行更改,但是首先需要满足一些先决条件。


About GraphQL and AppSync

在编写任何代码之前,您首先需要了解GraphQL是什么以及它如何与AppSync一起使用。

1. What is GraphQL?

GraphQLFacebook2012年开发;它是一种查询语言和服务器端运行时,用于执行旨在与服务器端API配合使用的查询。

如果您以前使用过服务器端API,则可能已经熟悉RESTREST API通过为应用程序公开多个终结点来工作,每个终结点均针对特定的数据类型而设计。如今,大多数API都被认为是RESTful的。但是,REST标准的解释较为宽松,因此您可能会在多个REST API上有不同的经验。

REST相反,GraphQL仅公开一个端点,您可以通过查询与之交互。使用这种方法,客户端仅访问他们需要的数据,并最小化通过网络发送的数据量。查看GraphQL如何运行的最佳方法是一个示例。

type Todo {
  id: ID!
  name: String!
  description: String
  completed: Boolean!
}

上面是GraphQL模式的示例,描述了Todo类型,这是构建RazeList时将使用的基本结构。 服务器定义此类型,以便您可以获取它。 假设您的应用程序中有一个屏幕,其中列出了所有待办事项,但只需要namecompleted字段。 这是使用GraphQL查询获取该屏幕数据的方式:

query TodoQuery {
  listTodos {
    items {
      name
      completed
    }
  }
}

GraphQL查询仅通过指定其关注的字段来访问所需的数据。 您将此查询发送到服务器,并且服务器使用与您的查询匹配的数据结构进行响应。 以这种方式添加和删除字段将需要在使用REST时对API进行更改,而在这里,您只需在应用程序内部更改查询,而无需完全修改服务器。

2. GraphQL with AWS AppSync

AWS AppSync可以完成后端Web服务的所有繁重工作。 它充当GraphQL和其他AWS服务(例如数据存储,缓存和实时更新)之间的桥梁。

AppSync为您的项目提供了一个仪表板,您可以在其中查看和查询数据,以及通过自定义功能添加自定义功能。

您的应用将在后台通过GraphQLAppSync进行通信; 但是,您将使用AppSync iOS框架来消除很多这种复杂性。 完成一些配置后,您只会以一种类型安全的方式谈论您的后端。


Installing the Amplify Framework

您将从安装项目依赖项开始。 您可能已经安装了其中的一些(或全部)。 在这种情况下,您可以跳到相关部分。

1. Installing npm

Node Package Manager (npm)是一个软件包管理器和CLI (command line interface),用于管理Node.js软件包。 在此项目中,您将使用npm安装Amplify CLI

如果不确定是否已安装npm,请打开“终端”并键入npm -v,然后按Enter。 如果已安装,则应该在“终端”窗口中看到打印的版本号。

npmNode.js一起安装。 要同时安装Node.jsnpm,请导航到node.js website网站,然后单击标有LTS的下载链接。 在撰写本文时,当前的LTS版本是14.15.1 LTS

下载完成后,打开.pkg文件,您应该看到以下内容:

SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一)_第2张图片

单击继续,然后按照步骤进行。 安装完成后,重新启动Terminal并键入npm -v并按Enter。 现在,您应该看到版本号。

2. Installing Amplify CLI

通过命令行安装Amplify。 在终端内,键入以下内容,然后按Enter。

sudo npm install -g @aws-amplify/cli

根据需要输入系统密码。 npm会在终端窗口中看到很多活动。 安装Amplify后,您应该会看到类似以下的内容:

----------------------------------------
Successfully installed the Amplify CLI
----------------------------------------

此过程完成后,输入以下命令,然后按Enter

amplify configure

该命令将在新的浏览器窗口中打开AWS登录页面。 如果您还没有AWS帐户,则需要先注册一个帐户,然后才能完成此步骤。 注册非常容易。 有关如何执行此操作的说明,请参阅 at the AWS knowledge center。 完成后,请务必从此开始继续本教程。

在浏览器窗口中登录到您的AWS账户。 登录后,返回“终端”窗口,然后按Enter

接下来,您需要指定您的区域。 使用箭头键选择最能代表您的位置的区域,然后按Enter。

接下来输入新用户的用户名,然后按Enter。 这可以是您想要的任何东西。

这会将您定向到AWS控制台以完成设置。 使用底部的按钮单击整个设置过程,并确保在权限屏幕上选中了AdministratorAccess

SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一)_第3张图片

在用户设置成功屏幕上,将Access key IDSecret access key复制到安全位置-以后将需要它们。 复制Secret access key时,请确保单击Show

SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一)_第4张图片

返回“终端”窗口,然后按Enter

当终端提示时,输入您的Access Key IDSecret Access Key

最后,在要求输入Profile Name时,最后一次按Enter键。 这会将您的配置文件设置为default

3. Installing CocoaPods

您将使用CocoaPodsAppSync框架添加到您的项目中。 如果您不熟悉CocoaPods,可以在我们的 CocoaPods Tutorial for Swift教程中了解

CocoaPods通过Ruby安装,而Ruby已经安装在Mac上。 打开终端,键入以下命令,然后按Enter。

sudo gem install cocoapods

短暂的延迟后,您应该在终端窗口中看到Successfully installed cocoapods-VERSION


Adding Amplify to the Project

现在你已经设置好了依赖项,你可以继续在Xcode中设置项目了。确保你在下一步关闭Xcode,是的,你没听错!

打开一个终端屏幕,并使用cd导航到starter项目目录。然后,在终端窗口中输入以下内容:

pod init

命令执行完毕后,您将注意到项目目录中出现了一个名为Podfile的新文件。在一个文本编辑器中打开Podfile,添加如下# Pods for RazeList:

pod 'Amplify'
pod 'Amplify/Tools'
pod 'AmplifyPlugins/AWSAPIPlugin'
pod 'AmplifyPlugins/AWSDataStorePlugin'

回到终端窗口并输入以下命令:

pod install

几秒钟后,您应该看到以下消息:

Pod installation complete! There are 4 dependencies from the Podfile and 12 total pods installed.

瞧!就像这样,您的包已经安装并包含在您的项目中。

Finder中打开项目目录,您将注意到现在有一个CocoaPods创建的名为RazeList.xcworkspace的工作空间文件。双击这个文件,你的项目就会在Xcode中打开。从现在开始使用这个文件来打开你的项目,而不是RazeList.xcodeproj,因为它包含所有需要的依赖项。

1. Adding AppSync Script

你快过终点线了。在编写任何代码之前,你需要做的最后一件事是在Xcode的Build Phases选项卡中添加一个Run Script。这个脚本执行一些需要在项目中使用AppSync的任务。

Xcode中选择RazeList项目。在project explorer中,单击Build Phases。单击+按钮并选择New Run Script Phase

SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一)_第5张图片

您将注意到列表底部有一个新的Run Script条目。单击箭头以展开它。

SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一)_第6张图片

在顶部的代码编辑器中,添加以下代码:

"${PODS_ROOT}/AmplifyTools/amplify-tools.sh"

现在构建并运行项目。这次的构建时间会稍长一些,因为Xcode将运行脚本(Run Script)作为构建过程的一部分执行。当构建完成时,你的项目中会有更多的文件;您将在下一节中使用这些。在进入下一阶段之前等待项目构建是很重要的。

2. Initializing Amplify

一旦构建过程完成,您将需要在项目中初始化amplify。当您在项目导航器中看到一个名为AmplifyConfig的新文件夹时,您就会知道构建已经完成了它的工作。

确保您在终端的项目目录中,并输入以下命令:

amplify init

根据界面提示输入如下信息:

? Enter a name for the environment
    Press Enter

? Choose your default editor
    None

? Do you want to use an AWS profile?
    Y

? Please choose the profile you want to use
    Press Enter for default

在同一个终端窗口中,输入以下命令,然后按Enter

amplify add api

根据界面提示输入如下信息。其他步骤按enter,使用默认设置。

? Please select from one of the below mentioned services:
    GraphQL

? Provide API name:
    Press Enter to set this to your directory name.

接下来输入以下命令。

amplify push

根据界面提示输入如下信息。

? Are you sure you want to continue? 
    Y

? Do you want to generate code for your newly created GraphQL API
    N

这可能看起来有很多设置,但Amplify已经为您做了很多。您已经创建了一个用户,设置了一个应用程序并将其添加到AWS仪表板,创建了一个GraphQL API并将其发布到AWS。一切都准备好了!


Creating Models Using GraphQL

在处理后端服务时,您可能希望将数据类型表示为模型。Amplify让你省去了自己打印它们的麻烦。那不是很好吗?

但是,您仍然需要告诉Amplify要生成什么,这将使用GraphQL完成!

打开AmplifyConfig组内的schema.graphql

替换该文件的内容如下:

type Todo @model {
  id: ID!
  name: String!
  description: String
  completed: Boolean!
}

接下来,打开同一个目录中的amplifytools.xcconfig。将pushmodelgen更改为true

构建并运行项目。构建完成后,项目导航器中会有一个名为AmplifyModels的新目录。在配置中更改上面的行告诉AmplifyGraphQL schema模式为您生成模型文件,并更新AWS上的配置。扩大AmplifyModels,看看周围。您将看到Todo.swift包含您的模型和一些帮助文件。

1. Using Amplify in the App

在左侧的项目导航器中,打开AppMain.swift并添加以下导入:

import Amplify
import AmplifyPlugins

AppDelegate类中,在application(_:didFinishLaunchingWithOptions:)函数返回true之前添加以下代码:

let apiPlugin = AWSAPIPlugin(modelRegistration: AmplifyModels())
let dataStorePlugin = AWSDataStorePlugin(modelRegistration: AmplifyModels())
do {
  try Amplify.add(plugin: apiPlugin)
  try Amplify.add(plugin: dataStorePlugin)
  try Amplify.configure()
  print("Initialized Amplify")
} catch {
  print("Could not initialize Amplify: \(error)")
}

构建并运行项目。

SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一)_第7张图片

没有任何视觉上的变化,但是您已经完全配置了项目以与AppSyncAmplify一起使用。


Building the To Do List UI

安装了库,设置了CocoaPods并生成了模型之后,就该使RazeList变得栩栩如生了。

本教程的某些SwiftUI编码已为您完成,但您仍需要构建主要任务清单。 这就是本节中要执行的操作。

1. Adding Rows to the To Do List

首先定义行。 右键单击Views组,然后选择New File选项。 选择SwiftUI View,然后单击Next。 将文件命名为TodoRowView.swift并创建它。

打开该文件,然后在TodoRowView声明下方添加以下内容。

// 1
let todoItem: Todo
// 2
let onToggleCompleted: (Todo) -> Void

待办事项行定义了两个要求。

  • 1) 用于渲染的Todo模型。
  • 2) 当用户切换完成状态时调用的闭包。

这将导致错误,因为预览没有传递这些依赖项。 用以下内容替换TodoRowView_Previews的全部内容:

struct TodoRowView_Previews: PreviewProvider {
  static var previews: some View {
    TodoRowView(
      todoItem: Todo(
      id: UUID().uuidString,
      name: "Build this cool app",
      description: "I need to finish building this awesome todo list app :]",
      completed: false)) { _ in }
  }
}

接下来,您将定义一个方法,当用户切换待办事项时。 将以下方法添加到TodoRowView中:

func toggleCompleted() {
  withAnimation {
    onToggleCompleted(todoItem)
  }
}

此函数仅将onToggle Completed封装在动画块中,该动画块将使各节之间的行移动具有动画效果。

接下来,将整个body替换为以下内容:

var body: some View {
  // 1
  VStack(alignment: .leading, spacing: 8) {
    HStack(spacing: 10) {
      // 2
      Button(action: { onToggleCompleted(todoItem) }) {
        Image(systemName: todoItem.completed ? "checkmark.square" : "square")
          .imageScale(.large)
          .foregroundColor(todoItem.completed ? .pink : .primary)
      }
      // 3
      Text(todoItem.name)
        .font(.system(size: 18, weight: .semibold))
    }
    // 4
    if let description = todoItem.description {
      Text(description)
        .font(.system(size: 14, weight: .medium))
        .padding(.leading, 32)
        .padding(.trailing, 10)
        .foregroundColor(.gray)
    }
  }
}

上面的代码是这样的:

  • 1) 定义一个VStack容器。
  • 2) 定义一个HStack,其中包含带有复选框图像的按钮。 根据待执行模型的completed属性的状态来选择是否选中该图像。 点击按钮将调用onToggleCompleted(_ :)
  • 3) 堆栈stack中的第二项是包含要执行的操作的名称的Text视图。
  • 4) 如果待办事项包含描述,请在Text视图中呈现它。

2. Setting up Your Data

打开TodoListViewModel.swift。 在类实现内添加以下代码:

@Published var todos: [Todo] = []
@Published var completedTodos: [Todo] = []

TodoListViewModel符合ObservableObject。 遵循此协议,允许对象在状态更改时发布更新。 使用@Published属性包装器告诉对象通过其发布者将更改广播给正在收听的任何人。 当对象更新时,SwiftUI使用它来重绘UI。

如果您想了解有关ObservableObject的更多信息,请查看Combine: Asynchronous Programming with Swift。

接下来,打开TodoListView.swift并在视图实现中添加以下代码:

@ObservedObject var viewModel = TodoListViewModel()

在这里,您将使用@ObservedObject属性包装器创建对TodoListViewModel的引用。 以这种方式创建属性会告诉SwiftUI您关心该对象的状态,并且它应该响应更改。

3. Adding Sections

接下来,您将定义两个部分,一个用于待办事项,一个用于完成待办事项。 一般来说,您希望保持body轻点。 考虑到这一点,您将把这两个部分定义为计算属性。

将第一部分添加到TodoListView中:

var todoSection: some View {
  // 1
  Group {
    // 2
    if viewModel.todos.isEmpty {
      Text("Nothing to do!")
    } else {
      // 3
      ForEach(viewModel.todos, id: \.id) { todo in
        // 4
        TodoRowView(todoItem: todo) { todo in
          withAnimation {
            // Toggle complete
          }
        }
        .padding(.vertical, 6)
      }
      .onDelete(perform: viewModel.deleteTodos)
    }
  }
}

一点一点地:

  • 1) 您无法选择返回Text视图或ForEach视图,因此它们被包装在Group中。
  • 2) 如果列表中没有待办事项,请返回一个反映此情况的Text视图。
  • 3) 如果有待办事项,请遍历每个步骤以在ForEach中执行。
  • 4) 对于列表中的每个操作,生成一个TodoRowView并传递当前操作。

接下来,您将完成已完成的任务。 在todoSection属性下方,添加以下内容:

var completedTodoSection: some View {
  Group {
    if viewModel.completedTodos.isEmpty {
      Text("Completed Tasks Appear Here")
    } else {
      ForEach(viewModel.completedTodos, id: \.id) { todo in
        TodoRowView(todoItem: todo) { todo in
          withAnimation {
            // Toggle complete
          }
        }
        .padding(.vertical, 6)
      }
      .onDelete(perform: viewModel.deleteCompletedTodos)
    }
  }
}

唯一的区别是您已将对viewModel.todos的引用替换为viewModel.completedTodos

现在,您已经定义了两个列表部分,现在该看看它们的实际效果了!

body内容替换为以下内容:

// 1
List {
  // 2
  Section(header: Text("Todo")) {
    todoSection
  }
  // 3
  Section(header: Text("Completed")) {
    completedTodoSection
  }
}
// 4
.listStyle(GroupedListStyle())

上面的代码执行以下操作:

  • 1) 创建一个列表以包含您先前创建的部分。
  • 2) 将“待办事项”部分嵌入Section视图中。
  • 3) 将完成的待办事项部分嵌入到Section视图中。
  • 4) 为列表提供分组样式。 这将分隔各节并应用一些默认样式。

构建并运行以查看结果。

SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一)_第8张图片

您终于摆脱了hello world应用! 真好

4. Adding a To Do

在本部分的最后部分,您将集成“添加待办事项”屏幕。 用户界面已经构建,因此这是一个相当简单的步骤。

转到TodoListView.swift并在视图实现内添加一个新属性:

@State var addNewTodoPresented: Bool = false

这将负责呈现和关闭添加视图。

body的底部,.listStyle(GroupedListStyle())之后的行上,添加以下视图修饰符:

// 1
.navigationBarItems(
  trailing: Button(action: { addNewTodoPresented.toggle() }) {
    Image(systemName: "plus")
      .imageScale(.large)
  }
)
// 2
.sheet(isPresented: $addNewTodoPresented) {
  AddTodoView { name, description in
    // add todo
    addNewTodoPresented.toggle()
  }
}

这看起来有点复杂,但实际上相当简单:

  • 1) navigationBarItems(trailing :)视图修饰符将导航项添加到封闭的NavigationView的导航栏中。 您在此处添加了一个按钮,点击该按钮即可切换addNewTodoPresented
  • 2) 当isPresented状态为true时,sheet(isPresented:content :)视图修饰符将显示一个模型。 闭包返回要显示的视图。 在这种情况下,您将返回AddTodoView

构建并运行以查看结果。

SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一)_第9张图片

您现在在导航栏中有一个添加按钮,并有一个屏幕来添加新的待办事项!


Creating and Editing To Dos

所有人都已设置完毕,并具有正常运行的用户界面。 您需要做的最后一件事就是将所有东西连接起来!

打开TodoListViewModel.swift并添加一个新的导入。

import Amplify

1. Adding To Dos

接下来,添加以下方法:

func createTodo(name: String, description: String?) {
  // 1
  let item = Todo(name: name, description: description, completed: false)
  // 2
  todos.append(item)
  // 3
  Amplify.DataStore.save(item) { result in
    switch result {
    case .success(let savedItem):
      print("Saved item: \(savedItem.name)")
    case .failure(let error):
      print("Could not save item with error: \(error)")
    }
  }
}

使用前面步骤中的所有配置,这就是将数据保存到本地和云数据存储中所需要的全部。 这是正在发生的事情:

  • 1) 使用传入的变量创建新的待办事项。
  • 2) 将其添加到本地待办事项todos数组。
  • 3) 使用Amplify框架,将to do添加到您的数据存储中。

接下来打开TodoListView.swift,然后向下滚动到body末尾的.sheet修改器。 在addNewTodoPresented.toggle()上方一行的闭包中,添加对createTodo(name:description :)函数的调用。

viewModel.createTodo(name: name, description: description)

您现在可以保存待办事项,但是除非您可以加载它们,否则这样做是没有用的!

返回TodoListViewModel.swift,将loadToDos()替换为以下内容。

func loadToDos() {
  Amplify.DataStore.query(Todo.self) { result in
    switch result {
    case .success(let todos):
      self.todos = todos.filter { !$0.completed }
      completedTodos = todos.filter { $0.completed }
    case .failure(let error):
      print("Could not query DataStore: \(error)")
    }
  }
}

现在,在TodoListView.swift中,在.sheet下添加一个新的视图修改器。

.onAppear {
  viewModel.loadToDos()
}

构建并运行项目以添加您的第一个待办事项!

SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一)_第10张图片

2. Completing To Dos

到目前为止,该应用程序非常适合向您显示您需要做的事情-但并不擅长让您完成这些任务。

打开TodoListViewModel。 滚动到底部,然后在loadTodos()之后添加以下新方法:

func toggleComplete(_ todo: Todo) {
  // 1
  var updatedTodo = todo
  updatedTodo.completed.toggle()
  
  // 2
  Amplify.DataStore.save(updatedTodo) { result in
    switch result {
    case .success(let savedTodo):
      print("Updated item: \(savedTodo.name )")
    case .failure(let error):
      print("Could not update data with error: \(error)")
    }
  }
  // 3
  if updatedTodo.completed {
    if let index = todos.firstIndex(where: { $0.id == todo.id }) {
      todos.remove(at: index)
      completedTodos.insert(updatedTodo, at: 0)
    }
  // 4
  } else {
    if let index = completedTodos.firstIndex(where: { $0.id == todo.id }) {
      completedTodos.remove(at: index)
      todos.insert(updatedTodo, at: 0)
    }
  }
}

好的,这是相当一部分代码。 它的作用是:

  • 1) 制作一个可变的副本即可进行修改,然后切换完成的值。
  • 2) 使用Amplify,将的操作保存回您的数据存储中。
  • 3) 如果待办事项已完成,请将其从待办事项todos中删除并将其添加到completedTodos
  • 4) 如果待办事项尚未完成,请将其从completedTodos中删除并将其添加到待办事项中。

打开TodoListView.swift并导航到顶部的两个属性。 在todoSectioncompletedTodoSection中,您会注意到两个占位符注释// Toggle complete。 用以下两个地方替换该注释:

viewModel.toggleComplete(todo)

构建并运行该应用程序。 现在,您可以轻按任一列表中的每个待办事项,并以很酷的动画更改完成状态!

SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一)_第11张图片

3. Deleting To Dos

您需要添加的最后一件事是删除行的方法。 UI中已经存在“滑动删除”功能,因此您只需将其连接起来即可。

打开TodoListViewModel.swift,您会在顶部注意到三种删除方法。 这些将充当帮助方法,以从其各自的列表中删除待办事项。

添加以下方法:

func delete(todo: Todo) {
  Amplify.DataStore.delete(todo) { result in
    switch result {
    case .success:
      print("Deleted item: \(todo.name)")
    case .failure(let error):
      print("Could not update data with error: \(error)")
    }
  }
}

此方法通过从Amplify框架调用delete(_ :)从数据存储中删除模型。

接下来,将以下三种删除方法替换为:

// 1
func deleteItems(at offsets: IndexSet, from todoList: inout [Todo]) {
  for index in offsets {
    let todo = todoList[index]
    delete(todo: todo)
  }

  todoList.remove(atOffsets: offsets)
}

// 2
func deleteTodos(at offsets: IndexSet) {
  deleteItems(at: offsets, from: &todos)
}

// 3
func deleteCompletedTodos(at offsets: IndexSet) {
  deleteItems(at: offsets, from: &completedTodos)
}

这是您所做的:

  • 1) 第一个删除方法调用刚添加的delete(at:from :)
  • 2) 此方法使用todos数组路由要删除的调用。
  • 3) 此方法使用completedTodos数组路由要删除的呼叫。

构建并运行项目。 您现在可以滑动以删除待办事项!

SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一)_第12张图片

现在,您有一个待办事项列表,可用于添加,编辑和删除待办事项。 它可以脱机工作,并与AWS后端保持同步。

现在,您已经知道在iOS应用中集成和使用AppSyncAmplify的基础知识-但是还有很多东西要学习! GraphQL可以做的比您在这里介绍的要多得多。

当您准备好使用AWSAmplify进行下一步时,请查看 Using AWS as a Back End: Authentication & API 和 Using AWS as a Back End: The Data Store API。

查看我们的教程GraphQL Using the Apollo Framework: Getting Started,以查看更多实际示例。 您也可以在GraphQL官方网站official GraphQL website.上了解有关GraphQL的更多信息。

您还应该查看亚马逊为进一步学习而制作的官方AWS AppSync教程official AWS AppSync tutorials。

后记

本篇主要讲述了基于基于SwiftUIAWS AppSync框架的使用,感兴趣的给个赞或者关注~~~

SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一)_第13张图片

你可能感兴趣的:(SwiftUI框架详细解析 (二十二) —— 基于SwiftUI的AWS AppSync框架的使用(一))