-
Notifications
You must be signed in to change notification settings - Fork 65
[v2] [5/X] Client Awareness Refactor #651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,8 +36,6 @@ public class ApolloClient: ApolloClientProtocol, @unchecked Sendable { | |
|
||
public let store: ApolloStore | ||
|
||
private let sendEnhancedClientAwareness: Bool | ||
|
||
public enum ApolloClientError: Error, LocalizedError, Hashable { | ||
case noUploadTransport | ||
case noSubscriptionTransport | ||
|
@@ -62,33 +60,30 @@ public class ApolloClient: ApolloClientProtocol, @unchecked Sendable { | |
/// key. Client library metadata is the Apollo iOS library name and version. Defaults to `true`. | ||
public init( | ||
networkTransport: any NetworkTransport, | ||
store: ApolloStore, | ||
sendEnhancedClientAwareness: Bool = true | ||
store: ApolloStore | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't there be some form of initialization for the |
||
) { | ||
self.networkTransport = networkTransport | ||
self.store = store | ||
self.sendEnhancedClientAwareness = sendEnhancedClientAwareness | ||
} | ||
|
||
/// Creates a client with a `RequestChainNetworkTransport` connecting to the specified URL. | ||
/// | ||
/// - Parameter url: The URL of a GraphQL server to connect to. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to add inline documentation for |
||
public convenience init( | ||
url: URL, | ||
sendEnhancedClientAwareness: Bool = true | ||
clientAwarenessMetadata: ClientAwarenessMetadata = ClientAwarenessMetadata() | ||
) { | ||
let store = ApolloStore(cache: InMemoryNormalizedCache()) | ||
let provider = DefaultInterceptorProvider(store: store) | ||
let transport = RequestChainNetworkTransport( | ||
interceptorProvider: provider, | ||
endpointURL: url, | ||
sendEnhancedClientAwareness: sendEnhancedClientAwareness | ||
clientAwarenessMetadata: clientAwarenessMetadata | ||
) | ||
|
||
self.init( | ||
networkTransport: transport, | ||
store: store, | ||
sendEnhancedClientAwareness: sendEnhancedClientAwareness | ||
store: store | ||
) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
import Foundation | ||
#if !COCOAPODS | ||
import ApolloAPI | ||
#endif | ||
|
||
/// A data structure containing telemetry metadata about the client. This is used by GraphOS Studio's | ||
/// [client awareness](https://www.apollographql.com/docs/graphos/platform/insights/client-segmentation) | ||
/// feature. | ||
public struct ClientAwarenessMetadata: Sendable { | ||
|
||
/// The name of the application. This value is sent for the header "apollographql-client-name". | ||
/// | ||
/// Defaults to `nil`. | ||
public var clientApplicationName: String? | ||
|
||
/// The version of the application. This value is sent for the header "apollographql-client-version". | ||
/// | ||
/// Defaults to `nil`. | ||
public var clientApplicationVersion: String? | ||
|
||
/// Determines if the Apollo iOS library name and version should be sent with the telemetry data. | ||
/// | ||
/// If `true`, the JSON body of the request will include a "clientLibrary" extension containing | ||
/// the name of the Apollo iOS library and the version of Apollo iOS being used by the client | ||
/// application. | ||
/// | ||
/// Defaults to `true`. | ||
public var includeApolloLibraryAwareness: Bool = true | ||
|
||
public init( | ||
clientApplicationName: String? = nil, | ||
clientApplicationVersion: String? = nil, | ||
includeApolloLibraryAwareness: Bool = true | ||
) { | ||
self.clientApplicationName = clientApplicationName | ||
self.clientApplicationVersion = clientApplicationVersion | ||
self.includeApolloLibraryAwareness = includeApolloLibraryAwareness | ||
} | ||
|
||
/// Disables all client awareness metadata. | ||
public static var none: ClientAwarenessMetadata { | ||
.init( | ||
clientApplicationName: nil, | ||
clientApplicationVersion: nil, | ||
includeApolloLibraryAwareness: false | ||
) | ||
} | ||
|
||
/// Enables all client awareness metadata with the following default values: | ||
/// | ||
/// - `clientApplicationName`: The application's bundle identifier + "-apollo-ios". | ||
/// - `clientApplicationVersion`: The bundle's short version string if available, | ||
/// otherwise the build number. | ||
/// - `includeApolloiOSLibraryVersion`: `true` | ||
public static var enabledWithDefaults: ClientAwarenessMetadata { | ||
.init( | ||
clientApplicationName: defaultClientName, | ||
clientApplicationVersion: defaultClientVersion, | ||
includeApolloLibraryAwareness: true | ||
) | ||
} | ||
|
||
/// The default client name to use when setting up the `clientName` property | ||
public static var defaultClientName: String { | ||
guard let identifier = Bundle.main.bundleIdentifier else { | ||
return "apollo-ios-client" | ||
} | ||
|
||
return "\(identifier)-apollo-ios" | ||
} | ||
|
||
/// The default client version to use when setting up the `clientVersion` property. | ||
public static var defaultClientVersion: String { | ||
var version = String() | ||
if let shortVersion = Bundle.main.shortVersion { | ||
version.append(shortVersion) | ||
} | ||
|
||
if let buildNumber = Bundle.main.buildNumber { | ||
if version.isEmpty { | ||
version.append(buildNumber) | ||
} else { | ||
version.append("-\(buildNumber)") | ||
} | ||
} | ||
|
||
if version.isEmpty { | ||
version = "(unknown)" | ||
} | ||
|
||
return version | ||
} | ||
|
||
struct Constants { | ||
/// The field name for the Apollo Client Name header | ||
static let clientApplicationNameKey: StaticString = "apollographql-client-name" | ||
|
||
/// The field name for the Apollo Client Version header | ||
static let clientApplicationVersionKey: StaticString = "apollographql-client-version" | ||
} | ||
|
||
/// A helper method that adds the client awareness headers to the given request | ||
/// This is used by GraphOS Studio's | ||
/// [client awareness](https://www.apollographql.com/docs/graphos/platform/insights/client-segmentation) | ||
/// feature. | ||
/// | ||
/// - Parameters: | ||
/// - clientAwarenessMetadata: The client name. The telemetry metadata about the client. | ||
public func applyHeaders( | ||
to request: inout URLRequest | ||
) { | ||
if let clientApplicationName = self.clientApplicationName { | ||
request.addValue( | ||
clientApplicationName, | ||
forHTTPHeaderField: ClientAwarenessMetadata.Constants.clientApplicationNameKey.description | ||
) | ||
} | ||
|
||
if let clientApplicationVersion = self.clientApplicationVersion { | ||
request.addValue( | ||
clientApplicationVersion, | ||
forHTTPHeaderField: ClientAwarenessMetadata.Constants.clientApplicationVersionKey.description | ||
) | ||
} | ||
} | ||
|
||
/// Adds client metadata to the request body in the `extensions` key. | ||
/// | ||
/// - Parameter body: The previously generated JSON body. | ||
func applyExtension(to body: inout JSONEncodableDictionary) { | ||
if self.includeApolloLibraryAwareness { | ||
let clientLibraryMetadata: JSONEncodableDictionary = [ | ||
"name": Apollo.Constants.ApolloClientName, | ||
"version": Apollo.Constants.ApolloClientVersion | ||
] | ||
|
||
var extensions = body["extensions"] as? JSONEncodableDictionary ?? JSONEncodableDictionary() | ||
extensions["clientLibrary"] = clientLibraryMetadata | ||
|
||
body["extensions"] = extensions | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like inline documentation for
sendEnhancedClientAwareness
is still here