订阅
订阅是持久存在的GraphQL读取操作,可以在一段时间内更新其响应,使客户端能够在数据可用时接收新数据。
Apollo iOS支持以下协议上的订阅
您必须使用 GraphQL 终端的支持的协议。
启用支持
为了支持GraphQL订阅,您需要使用支持订阅的ApolloClient
实例初始化一个NetworkTransport
. 下面是每个订阅协议的相关类。
WebSocket
为了使用基于 WebSocket 的Apollo iOS订阅,您需要安装可选的ApolloWebSocket
库。此库包括两个符合NetworkTransport
协议的类:
WebSocketTransport
通过WebSocket发送所有操作(包括查询以及变体)。SplitNetworkTransport
维持一个WebSocketTransport
实例,以及 一个UploadingNetworkTransport
实例(通常是RequestChainNetworkTransport
)。这提供了一个使用HTTP进行查询和变体以及WebSocket进行订阅的单一网络传输。
SplitNetworkTransport
推荐用于大多数用例,因为它允许您保持一个单一 NetworkTransport
设置,从而避免了使用多个客户端对象引起的问题。
以下是一个使用 SplitNetworkTransport
支持所有 操作类型 的 ApolloClient
设置示例:
WebSocket子协议
Apollo iOS 支持以下WebSocket子协议用于订阅:
graphql-ws
,该协议已在subscriptions-transport-ws和AWS AppSync库中实现。(⚠️此协议正在维护中!)graphql-transport-ws
,该协议已在graphql-ws库中实现。
注意:这些协议不互操作。您需要使用由您的GraphQL端点支持的协议。所有WebSocket
初始化器都允许您指定要使用的协议(例如,展开上面的代码块查看示例)。
提供授权令牌
在标准HTTP操作中,如果需要身份验证,通常会在请求中发送Authorization
头。然而,在WebSocket中,由于需要持久连接,这不能随每个有效载荷发送。
对于WebSocket,connectingPayload
提供了您通常在请求头中指定的参数。
请注意,这必须在创建WebSocketTransport时设置。如果您需要更新connectingPayload
,您需要使用新的webSocketTransport
重新创建客户端。
let webSocketTransport: WebSocketTransport = {let url = URL(string: "ws://127.0.0.1:8080/websocket")!let webSocketClient = WebSocket(url: url, protocol: .graphql_transport_ws)let authPayload: JSONEncodableDictionary = ["authToken": myAuthToken]let config = WebSocketTransport.Configuration(connectingPayload: authPayload)return WebSocketTransport(websocket: webSocketClient, config: config)}()
HTTP
Apollo iOS的默认NetworkTransport
为RequestChainNetworkTransport
。在Apollo iOS1.1.0
及以后版本中,该传输支持HTTP上的订阅,无需额外配置。
有关创建客户端的说明,请参见创建客户端。
生成和执行
Apollo iOS支持通过代码生成进行订阅。与查询类似,订阅通过生成的类的实例表示,符合GraphQLSubscription
协议。
subscription ReviewAdded {reviewAdded {idstars}}
在生成这些类后,您可以使用订阅支持的NetworkTransport
执行通过ApolloClient.subscribe(subscription:)
。如果这样做,您的客户端将继续接收更新数据,直到订阅被取消。
let subscription = client.subscribe(subscription: ReviewAddedSubscription()) { result inguard let data = try? result.get().data else { return }print(data.reviews.map { $0.stars })}
注意: GraphQL 订阅与观察查询不同。查询观察者在本地缓存的写入(通常由另一个网络操作完成时)时才会更新。GraphQL订阅是一个持久请求,可能会从服务器持续接收更新数据。
取消订阅
在完成订阅连接时取消订阅是非常重要的。只要订阅处于活动状态,它就保持与服务器之间的连接,并保留其resultHandler
完成块。这可能会导致内存泄漏并降低应用程序的性能。
调用ApolloClient.subscribe(subscription:)
时,将返回一个不透明的Cancellable
。您可以通过在返回的Cancellable
上调用cancel()
来取消订阅。这终止了与服务器的连接并释放了resultHandler
完成块。
取消订阅的取消对象在其被释放时不会取消自己!请确保自行调用cancel()
。一个类
可以通过使用其析构函数来确保在释放时取消它管理的任何订阅:
class ReviewViewController {let client: ApolloClient!private var subscription: Cancellable?func subscribeToReviews() {// Keep a reference to the subscription's cancellation object.self.subscription = client.subscribe(subscription: ReviewAddedSubscription()) { [weak self] result in// Handle each update from the subscription.}}deinit {// Make sure the subscription is cancelled, if it exists, when this object is deallocated.self.subscription?.cancel()}}