GraphQL-Swift 1.0.36

GraphQL-Swift 1.0.36

Nomad-Labs维护。



安装

pod 'GraphQL-Swift'

概念

这个库旨在保持简单。它受到了一个名为 graphql-client 的简单 NPM 模块的影响。

这个库不使用任何其他依赖项,并专注于面向协议的架构。目前,您只能执行查询和变体。希望很快能添加订阅功能。

连接

要连接到您的 GraphQL 端点,您需要初始化一个 GQLNetworkController。初始化器接受符合 GQLAPIDefinition 协议的对象。默认情况下,GQLNetworkController 使用配置为短暂的 URLSession

构建您的 GQLAPIDefinition 对象时,您可以可选地添加一个符合 GQLAuthorization 的对象。从那里您可以配置您的“授权”头。例如...

struct MockGQLAuthorization: GQLAuthorization {
    //MARK: Properties
    var clientID: String?
    
    var apiKey: String?
    
    var jwt: String?
    
    var authorizationHeader: [String : String] {
        return ["Authorization": "Bearer \(self.jwt ?? self.apiKey ?? self.clientID ?? "")"]
    }
    
    //MARK: init
    init() {
        
    }
}

struct MockAPIDefinition: GQLAPIDefinition {
    //MARK: Properties
    var authorization: GQLAuthorization?
    
    var rootRESTURLString: String = "https://mockgraphqlapi.com"
    
    var rootWebsocketURLString: String = "wss://mockgraphqlapi.com"
    
    //MARK: init
    init(authorization: GQLAuthorization? = nil) {
        self.authorization = authorization
    }
}

let mockAuth = MockGQLAuthorization()

let mockAPI =  MockAPIDefinition(authorization: mockAuth)

let networkController = GQLNetworkController(apiDefinition: mockAPI)

查询

要执行查询或变体,您必须创建一个符合 GQLRequest 的对象。GQLQueryGQLMutation 协议都继承自 GQLRequest。以下是一个基本的查询对象。

struct UserQuery: GQLQuery {

    var graphQLLiteral: String = """
    query {
        user {
            id
            email
            name
        }
    }
    """
    
    var fragments: [GQLFragment]?
    
    var variables: [String : Any]?
    
    init() {
        
    }
    
}

您将像这样执行请求。

let userQuery = UserQuery()

do {
    let dataTask = try networkController.makeGraphQLRequest(userQuery, completion: { (p_results, p_error) in
            if let error = p_error {
                //Any networking error
            }else if let results = p_results {
                do {
                    let users = try results.parseArrayResults(fieldKey: "user")
                    print(users)
                }catch{
                    //Any parsing errors
                }
            }
        })
}catch{
    //Any errors that were thrown before the request was made.
}

片段

您可以通过遵循 GQLFragment 协议来定义一个片段。

在这里,我们可以重构我们的原始 UserQuery 来包含一个片段。

struct UserDetails: GQLFragment {
     let fragmentLiteral = """
     fragment UserDetails on user {
        id
        name
        email
     }
     """
}

struct UserQuery: GQLQuery {

    var graphQLLiteral: String = """
    query {
        user {
            ...UserDetails
        }
    }
    """
    
    var fragments: [GQLFragment]? = [UserDetails()]
    
    var variables: [String : Any]?
    
    init() {
        
    }
    
}

变量

最后,我们可以这样将变量传递到查询中。

struct UserQuery: GQLQuery {

    var graphQLLiteral: String = """
    query UserByEmail($email: String!){
        user(where: {email: {_eq: $email}}, limit: 1) {
            ...UserDetails
        }
    }
    """
    
    var fragments: [GQLFragment]? = [UserDetails()]
    
    var variables: [String : Any]?
    
    init(email: String) {
        self.variables = ["email": email]
    }
    
}

GraphQL JSON 解析

有关从 GraphQL 请求返回的 JSON 的一般格式,请参阅此处

.makeGraphQLRequest 函数的响应将包含未过滤或解析的请求 JSON。由于来自 GraphQL 请求的 JSON 有一定的规律,因此该库包含一些 Swift 字典扩展以帮助您开始。

  1. 传入数据键。

所有请求都返回一个包含数据键的字典。解析方式如下

do {
    let dataTask = try networkController.makeGraphQLRequest(userQuery, completion: { (p_results, p_error) in
            if let error = p_error {
                //Any networking error
            }else if let results = p_results {
                do {
                    let dataResults = try results.parseDataKey()
                    print(dataResults)
                }catch{
                    //Any parsing errors
                }
            }
        })
}catch{
    //Any errors that were thrown before the request was made.
}
  1. 从高级字段解析选择集。

如果您知道从查询中的任何顶级字段返回的对象的形状,您可以按如下方式获取它们。

do {
    let dataTask = try networkController.makeGraphQLRequest(userQuery, completion: { (p_results, p_error) in
            if let error = p_error {
                //Any networking error
            }else if let results = p_results {
                do {
                    //If your selection set is a dictionary
                    let users = try results.parseDictionaryResults(fieldKey: "user")
                    print(users)
                    //If your selection set is an array
                    let users = try results.parseArrayResults(fieldKey: "user")
                    print(users)
                }catch{
                    //Any parsing errors
                }
            }
        })
}catch{
    //Any errors that were thrown before the request was made.
}