七爪源码:如何使用 Apollo iOS 和 GraphQL 进行突变

iOS 中与 Apollo 的 GraphQL 集成的第 2 部分

七爪源码:如何使用 Apollo iOS 和 GraphQL 进行突变

什么是突变?

由于任何完整的数据平台都需要一种修改服务器端数据的方法,这就是突变的来源。 例如,突变可以是用户的注册、登录/退出或编辑他们的昵称。

因此,查询和变异之间的区别很简单:

查询是一种获取数据、变异——改变的方式。

提示:两种突变都可以返回对象类型,也可以返回查询。 这对于在突变后获得对象的新状态可能很有用。


步骤 1. 在 Playground 中创建突变

我们将继续使用我们在上一篇文章中设置的 API 客户端。 所以你可以继续使用相同的代码或克隆这个 git repo 并切换到 apollo-setup-and-first-query 分支。

打开 Fruits API Playground 的文档部分。 在这里,您可以看到 API 提供的突变列表:

七爪源码:如何使用 Apollo iOS 和 GraphQL 进行突变

假设我们要添加水果列表中未提及的水果。 我们可以为此使用 addFruit 突变。

在 Playground 中打开一个新选项卡并开始使用变异进行编写,然后添加一个描述您变异的数据的名称(通常,使用与 API 文档中相同的名称)。

提示:不要在查询名称的末尾使用突变,因为 Apollo 会在生成 API.swift 文件时自动添加它。

突变也返回一个 Fruit 对象,所以让我们获取我们添加的水果的名称(如果突变返回一个对象,则需要至少查询一个字段):

mutation AddFruit($addFruitId: ID!, $scientificName: String!, $treeName: String!, $fruitName: String!, $family: String!, $origin: String!, $description: String!, $bloom: String!, $maturationFruit: String!, $lifeCycle: String!, $climaticZone: String!) {
  addFruit(id: $addFruitId, scientific_name: $scientificName, tree_name: $treeName, fruit_name: $fruitName, family: $family, origin: $origin, description: $description, bloom: $bloom, maturation_fruit: $maturationFruit, life_cycle: $lifeCycle, climatic_zone: $climaticZone) {
    id
    scientific_name
    tree_name
    fruit_name
    family
    origin
    description
    bloom
    maturation_fruit
    life_cycle
    climatic_zone
  }
}

所以我们查询被删除的水果的名字。 此外,我为突变参数添加了一个 id,因为 API 应该以某种方式知道要删除哪个水果。 文档选项卡中提到了突变所需的参数:

七爪源码:如何使用 Apollo iOS 和 GraphQL 进行突变

提示:您可以按照我们在 Swift 中习惯的方式设置参数的默认值:

七爪源码:如何使用 Apollo iOS 和 GraphQL 进行突变


步骤 2. 将 Created Mutation 添加到 Xcode

正如我们对查询所做的那样,添加一个空文件,为其命名(我建议您使用与突变名称相同的名称),然后添加 .graphql 扩展名:

七爪源码:如何使用 Apollo iOS 和 GraphQL 进行突变

从操场复制并粘贴突变并构建项目。

项目构建完成后,Apollo 在 API.swift 中生成 AddFruitMutation 类:

七爪源码:如何使用 Apollo iOS 和 GraphQL 进行突变


步骤 3. 执行突变并检查结果

现在我们可以使用 addFruit() 函数更新我们的 ViewController,它将使用 Apollo 客户端执行 AddFruit 突变并处理结果:

import UIKit
import Apollo

class ViewController: UIViewController {
    
    private let apollo = ApolloClient(url: URL(string: "https://fruits-api.netlify.app/graphql")!)

    override func viewDidLoad() {
        super.viewDidLoad()
        getFruits { [weak self] fruits in
            guard let safeSelf = self else { return }
            if let fruits = fruits {
                print("Fruits API knows \(fruits.count) types of fruits:")
                for (index, element) in fruits.enumerated() {
                    print("\(index+1). \(element.fruitName ?? "Unknown name")")
                }
                
                // Pay attention that id is of String type, so need to convert it
                let fruitId = String(Int.random(in: 1_000..<10_000))
                let fruitName = "Apple"
                
                safeSelf.addFruit(with: fruitId, fruitName: fruitName) { addedFruitName in
                    guard let addedFruitName = addedFruitName else { return }
                    print("You have added \(addedFruitName)")
                }
            }
        }
    }
    
    private func getFruits(completion: @escaping ([GetAllFruitsQuery.Data.Fruit]?) -> Void) {
        apollo.fetch(query: GetAllFruitsQuery()) { result in
            switch result {
            case .success(let graphqlResult):
                if let data = graphqlResult.data,
                   let fruits = data.fruits {
                    completion(fruits.compactMap { $0 })
                }
                if let errors = graphqlResult.errors, !errors.isEmpty {
                    print("GraphQL errors:")
                    errors.forEach {
                        print($0.localizedDescription)
                    }
                }
            case .failure(let error):
                completion(nil)
                print(error.localizedDescription)
            }
        }
    }
    
    private func addFruit(with id: String, fruitName: String, completion: @escaping (_ addedFruitName: String?) -> Void) {
        apollo.perform(mutation: AddFruitMutation(addFruitId: id, scientificName: "", treeName: "", fruitName: fruitName, family: "", origin: "", description: "", bloom: "", maturationFruit: "", lifeCycle: "", climaticZone: "")) { result in
            switch result {
            case .success(let graphqlResult):
                if let data = graphqlResult.data,
                   let fruitName = data.addFruit.fruitName{
                    completion(fruitName)
                }
                if let errors = graphqlResult.errors, !errors.isEmpty {
                    print("GraphQL errors:")
                    errors.forEach {
                        print($0.localizedDescription)
                    }
                }
            case .failure(let error):
                completion(nil)
                print(error.localizedDescription)
            }
        }
    }

}

粘贴此代码,使用您喜欢的任何水果对其进行更新,然后运行该应用程序。 您可以运行 GetAllFruits 查询来检查您的水果是否已添加到数据库中。

七爪源码:如何使用 Apollo iOS 和 GraphQL 进行突变

七爪源码:如何使用 Apollo iOS 和 GraphQL 进行突变

如您所见,Apollo 很容易与突变以及查询一起使用。

它将参数、突变和数据类型转换为可以使用的 Swift 代码。 更改数据和处理结果非常简单。


更多APP/小程序/网站源码资源,请搜索"七爪网源码交易平台"!

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章