Google is committed to advancing racial equity for Black communities. See how.

Cloud Anchors Developer Guide for iOS

Explore how the iOS sample app uses the ARCore Cloud Anchor API and learn about working with the API in your own apps.

If you are new to the ARCore Cloud Anchor API:


To use Cloud Anchors, you'll need:

  • Xcode version 10.1 or later

  • Cocoapods 1.4.0 or later

  • An ARKit-compatible Apple device running iOS 11.0 or later (deployment target of iOS 9.0 or later required)

Explore the sample app

Walk through the sample app to learn about critical tasks for working with Cloud Anchors.

Session setup

The sample app performs the following important tasks as part of setting up the session:

Passing ARFrames to the GARSession

Make sure that your app passes ARFrames continuously to theGARSession.

To do this, use the following push pattern:

-(void)someSetupMethod {
        arSession.delegate = self;
        garSession.delegate = self;

-(void)session:(ARSession *)arSession didUpdateFrame:(ARFrame *)arFrame {
        GARFrame *garFrame = [garSession update:arFrame];
        // … process the frame (optional)

You should pass at least one ARFrame to the GARSession before you try to host or resolve anchors. This allows time for the GARSession to be synced with the ARSession.

To learn more about best practices for world tracking in ARKit, see About Augmented Reality and ARKit in Apple's developer documentation.

If you are using Metal or otherwise need a polling solution, see the Optional polling pattern in this guide.

Hosting and resolving anchors

The ARCore Cloud Anchor API provides methods for cloud anchor hosting and resolving. The API also includes delegate methods to provide the result of completed host and resolve requests.

Hosting anchors

Hosting an ARAnchor maps it in a common coordinate system for a given physical space.

A host request sends visual mapping data to a Google server to map the ARAnchor’s position in a coordinate system representing the current physical space, and also returns a GARAnchor without an ID. A successful host request assigns the GARAnchor a unique Cloud Anchor ID in a later GARFrame.

- (void)addAnchorWithTransform:(matrix_float4x4)transform {
  self.arAnchor = [[ARAnchor alloc] initWithTransform:transform];
  [self.sceneView.session addAnchor:self.arAnchor];
  self.garAnchor = [self.gSession hostCloudAnchor:self.arAnchor error:nil];
  [self enterState:HelloARStateHosting];

Resolving anchors

Resolving a cloud anchor lets Android and iOS devices in a given physical space add its previously hosted anchors to their scene.

An anchor resolve request sends a cloud anchor ID with visual data from the current frame to a Google server, and also returns a GARAnchor without a valid transform and cloud anchor ID. The server attempts to match this visual data against the imagery of where currently hosted Cloud Anchors are mapped.

A successful resolve request assigns the GARAnchor a valid transform and Cloud Anchor ID in a later GARFrame.

- (void)resolveAnchorWithIdentifier:(NSString *)identifier {
  self.garAnchor = [self.gSession resolveCloudAnchorWithIdentifier:identifier error:nil];

// Every time there's a frame update, pass the ARFrame to the ARCore session.
// This returns a GARFrame, which contains a list of updated anchors. If the pose
// or the tracking state of your anchor has changed, it will be in the list.
- (void)cloudAnchorManager:(CloudAnchorManager *)manager didUpdateFrame:(GARFrame *)garFrame {
  for (GARAnchor *garAnchor in garFrame.updatedAnchors) {
    if ([garAnchor isEqual:self.garAnchor] && self.resolvedAnchorNode) {
      self.resolvedAnchorNode.simdTransform = garAnchor.transform;
      self.resolvedAnchorNode.hidden = !garAnchor.hasValidTransform;

Delegate methods for host and resolve requests

Host and resolve methods have GARSessionDelegate methods to provide callbacks on request success and failure.


  • session:didHostAnchor:
  • session:didFailToHostAnchor:


  • session:didResolveAnchor:
  • session:didFailToResolveAnchor:

-(void)session:(ARSession *)arSession didUpdateFrame:(ARFrame *)arFrame {

-(void)session:(GARSession *)garSession didHostAnchor:(GARAnchor *)garAnchor {
        // successful host

-(void)session:(GARSession *)garSession didFailToHostAnchor:(GARAnchor *)garAnchor {
        // failed host

-(void)session:(GARSession *)garSession didResolveAnchor:(GARAnchor *)garAnchor {
        // successful resolve

-(void)session:(GARSession *)garSession didFailToResolveAnchor:(GARAnchor *)garAnchor {
        // failed resolve

API quotas

The ARCore Cloud Anchor API has the following quotas for request bandwidth:

Quota type Maximum Duration Applies to
Number of anchors Unlimited N/A Project
Anchor host requests 30 minute IP address and project
Anchor resolve requests 300 minute IP address and project

Known issues and workarounds

Default scheme settings cause intermittent app crash

GPU Frame Capture and Metal API Validation scheme settings are enabled by default. This can sometimes cause the app to crash within the SDK.

How to diagnose

  1. Take a look at your stack trace if a crash occurs.
  2. If you see MTLDebugComputeCommandEncoder in the stack trace, it is likely due to the default scheme settings. Try the following workaround.


  1. Go to Product > Scheme > Edit scheme…
  2. Open the Run tab.
  3. Click Options to view current settings.
  4. Make sure that GPU Frame Capture and Metal API Validation are disabled.
  5. Close the scheme configuration menu.
  6. Build and run the app again.

For additional known issues, see the CHANGELOG in Cocoapods.


Optional GARSession polling pattern

Use the following pattern to pass ARFrames to the GARSession if both of the following apply to your project:

  • You are using Metal or need a polling option for another reason
  • Your app runs at a minimum 30 fps (required)
-(void)myOwnPersonalUpdateMethod {
        ARFrame *arFrame = arSession.currentFrame;
        GARFrame *garFrame = [garSession update:arFrame];
        // your update code here

Next steps