Apollo Client Devtools bridge for Apollo iOS.
ApolloDeveloperKit is an iOS library which works as a bridge between Apollo iOS client and Apollo Client Developer tools.
This library adds an ability to watch the sent queries or mutations simultaneously, and also has the feature to request arbitrary operations from embedded GraphiQL console.
- Xcode
>= 10.1
- Google Chrome
- Apollo iOS
>= 0.9.1
,< 0.19.0
- Apollo Client Devtools
Add the following lines to your Podfile.
pod 'Apollo'
pod 'ApolloDeveloperKit', '~> 0.4.0'
Then run pod install
.
Add the following lines to your Cartfile.
github "apollographql/apollo-ios"
github "manicmaniac/ApolloDeveloperKit"
Then run carthage update --platform iOS
.
If you are using Xcode 10.1, where Swift 5 is not available, the install step could be a bit tricky though Cartfile can be as it is. Contrary to CocoaPods, Carthage doesn't select the compiler by itself so the only way to force it to use Swift 4.2 is to inject a Xcode configuration file.
echo APOLLO_DEVELOPER_KIT_SWIFT_VERSION=4.2 >ApolloDeveloperKit.xcconfig
XCODE_XCCONFIG_FILE=$PWD/ApolloDeveloperKit.xcconfig carthage update --platform iOS
rm ApolloDeveloperKit.xcconfig
Note XCODE_XCCONFIG_FILE
should be an absolute path somehow.
Not recommended but as plan B, you can use ApolloDeveloperKit ~> 0.3.3
which only supports Swift 4.2 as well.
First, in order to hook Apollo's cache and network layer, you need to use DebuggableNetworkTransport
and DebuggableInMemoryNormalizedCache
instead of usual ones.
let networkTransport = DebuggableNetworkTransport(networkTransport: HTTPNetworkTransport(url: url))
let cache = DebuggableInMemoryNormalizedCache()
Second, instantiate ApolloStore
and ApolloClient
with debuggable ingredients.
let store = ApolloStore(cache: cache)
let client = ApolloClient(networkTransport: networkTransport: store: store)
Finally, create ApolloDebugServer
and run.
let debugServer = ApolloDebugServer(cache: cache, networkTransport: networkTransport)
self.debugServer = debugServer // Note: you need to retain debugServer's reference
debugServer.start(port: 8081)
Full example:
import Apollo
import ApolloDeveloperKit
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
private var client: ApolloClient!
private var debugServer: ApolloDebugServer?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let url = URL(string: "https://example.com/graphql")!
#if DEBUG
let networkTransport = DebuggableNetworkTransport(networkTransport: HTTPNetworkTransport(url: url))
let cache = DebuggableNormalizedCache(cache: InMemoryNormalizedCache())
let store = ApolloStore(cache: cache)
client = ApolloClient(networkTransport: networkTransport, store: store)
debugServer = ApolloDebugServer(networkTransport: networkTransport, cache: cache)
do {
try debugServer.start(port: 8081)
} catch let error {
print(error)
}
#else
client = ApolloClient(url: url)
#endif
return true
}
}
If you don't have Google Chrome and Apollo Client Developer Tools, install them before proceeding the following steps.
- Launch your app on your device or simulator.
- Open Google Chrome and jump to the server's URL (in case your app runs the above example on a simulator, the URL would be
http://localhost:8081
).- You will see
ApolloDebugServer is running!
on your browser's tab. - If not, make sure the server runs and the specified URL is correct.
- On a real device, the host would be other than
localhost
but you can check what it is withApolloDebugServer.serverURL
.
- You will see
- Open Google Chrome DevTools.
- Select
Apollo
tab.- You will see tabs like
GraphiQL
,Queries
,Mutations
on the left pane. - If not, reload the tab and wait until it's connected again.
- You will see tabs like
All instructions in this section are written based on Flipboard/FLEX's way.
Since ApolloDeveloperKit is originally designed for debug use only, it should not be exposed to end-users.
Fortunately, it is easy to exclude ApolloDeveloperKit framework from Release builds. The strategies differ depending on how you integrated it in your project, and are described below.
Please make sure your code is properly excluding ApolloDeveloperKit with #if DEBUG
statements before starting these instructions.
Otherwise it will be linked to your app unexpectedly.
See Example/AppDelegate.swift
to see how to do it.
CocoaPods automatically excludes ApolloDeveloperKit from release builds if you only specify the Debug configuration for CocoaPods in your Podfile.
- Do NOT add
ApolloDeveloperKit.framework
to the embedded binaries of your target, as it would otherwise be included in all builds (therefore also in release ones). - Instead, add
$(PROJECT_DIR)/Carthage/Build/iOS
to your target Framework Search Paths (this setting might already be present if you already included other frameworks with Carthage). This makes it possible to import the ApolloDeveloperKit framework from your source files. It does not harm if this setting is added for all configurations, but it should at least be added for the debug one. - Add a Run Script Phase to your target (inserting it alter the existing
Link Binary with Libraries
phase, for example), and which will embedApolloDeveloperKit.framework
in debug builds only:
if [ "$CONFIGURATION" == "Debug" ]; then
/usr/local/bin/carthage copy-frameworks
fi
Finally, add $(SRCROOT)/Carthage/Build/iOS/ApolloDeveloperKit.framework
as input file of this script phase.
Now there's no easy way but you can exclude ApolloDeveloperKit by setting user defined build variable named EXCLUDED_SOURCE_FILE_NAMES
.
The value for the variable is a space-separated list of each filenames in ApolloDeveloperKit.
Sorry for the inconvenience.
Auto-generated API documentation is here.
Since Example app is slightly modified version of apollographql/frontpage-ios-app, you need to start apollographql/frontpage-server before runnning the app.
- Open Xcode and select ApolloDeveloperKitExample scheme.
- Run and open
http://localhost:8081
in Google Chrome.
This software is distributed under the MIT license. See LICENSE for more detail.