安装
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
的对象。GQLQuery
和 GQLMutation
协议都继承自 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 字典扩展以帮助您开始。
- 传入数据键。
所有请求都返回一个包含数据键的字典。解析方式如下
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.
}
- 从高级字段解析选择集。
如果您知道从查询中的任何顶级字段返回的对象的形状,您可以按如下方式获取它们。
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.
}