API ARCore Cloud Anchor cũ đã ngừng hoạt động và không được hỗ trợ sau ngày 31 tháng 8 năm 2023. Nếu ứng dụng của bạn đang sử dụng API này, thì bạn phải cập nhật API để sử dụng điểm cuối API ARCore mới càng sớm càng tốt.

Hướng dẫn dành cho nhà phát triển về Cloud Anchors cho iOS

SDK ARCore cho các giao diện iOS với ARKit để cung cấp các tính năng của Cloud Anchor, cho phép bạn chia sẻ các neo giữa các thiết bị iOS và Android trong cùng một môi trường.

Tìm hiểu cách sử dụng API ARCore hoặc dịch vụ ARCore Cloud Anchor trong các ứng dụng của riêng bạn. Nếu bạn mới sử dụng Cloud Anchors:

Bật Neo liên kết trong ứng dụng của bạn

Để sử dụng API Cloud Anchors, bạn phải tạo một GARSessionConfiguration và đặt thuộc tính cloudAnchorMode cho API đó, như mô tả trong phần Định cấu hình phiên ARCore trong iOS. Sử dụng setConfiguration:error: (GARSession) để đặt cấu hình.

Bạn cũng phải bật ARCore API cho dự án Google Cloud Platform.

Lưu trữ và phân giải các neo

Bạn có thể lưu trữ và phân giải các neo trên đám mây bằng API ARCore. API cũng bao gồm các phương thức uỷ quyền cung cấp lệnh gọi lại trên yêu cầu đã hoàn tất.

Lưu trữ liên kết

Việc lưu trữ một ARAnchor sẽ đặt liên kết vào một hệ thống toạ độ chung cho bất kỳ không gian thực tế nào.

Yêu cầu máy chủ lưu trữ sẽ gửi dữ liệu hình ảnh đến máy chủ của Google, máy chủ này ánh xạ vị trí của ARAnchor trong hệ thống toạ độ đại diện cho không gian thực hiện tại. Yêu cầu này trả về một GARAnchor không có mã nhận dạng. Yêu cầu máy chủ thành công sẽ gán GARAnchor duy nhất cho một mã nhận dạng duy nhất trong GARFrame sau này.

- (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];
}

Giải quyết neo

Việc phân giải một ARAnchor cho phép các thiết bị Android và iOS trong một không gian thực nhất định thêm các liên kết được lưu trữ trước đó vào các cảnh mới.

Yêu cầu phân giải sẽ gửi cho máy chủ của Google một mã nhận dạng liên kết đám mây cùng với dữ liệu hình ảnh từ khung hiện tại. Yêu cầu này trả về một GARAnchor không có mã nhận dạng cố định hoặc biến đổi hợp lệ. Máy chủ sẽ cố gắng khớp dữ liệu hình ảnh này với hình ảnh của vị trí lưu trữ đám mây hiện đang được lưu trữ. Yêu cầu máy chủ thành công sẽ gán cho GARanchor một biến đổi hợp lệ và một mã nhận dạng duy nhất trong GARFrame sau này.

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

// Pass the ARFRame to the ARCore session every time there is a frame update.
// This returns a GARFrame that contains a list of updated anchors. If your
// anchor's pose or tracking state changed, your anchor will be on 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;
    }
  }
}

Các phương thức uỷ quyền để lưu trữ và giải quyết yêu cầu

Máy chủ lưu trữ và giải quyết yêu cầu có các phương thức GARSessionDelegate cung cấp các lệnh gọi lại khi yêu cầu thành công và không thành công.

Máy chủ

  • session:didHostAnchor:
  • session:didFailToHostAnchor:

Giải quyết

  • 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
}

Mẫu thăm dò ý kiến GARSession không bắt buộc

Nếu bạn đang sử dụng Kim loại hoặc cần một tuỳ chọn thăm dò ý kiến ứng dụng của bạn chạy ở tốc độ tối thiểu là 30 khung hình/giây, hãy sử dụng mẫu sau để truyền ARFrame đến GARSession:

-(void)myOwnPersonalUpdateMethod {
        ARFrame *arFrame = arSession.currentFrame;
        NSError *error = nil;
        GARFrame *garFrame = [garSession update:arFrame error:&error];
        // your update code here
}

Lưu trữ một Cloud Anchor với tính ổn định

Trước khi ARCore v1.20, bạn chỉ có thể phân giải các neo trên đám mây trong tối đa 24 giờ sau khi lưu trữ lần đầu. Với Cloud Anchors cố định, giờ đây, bạn có thể sử dụng hostCloudAnchor:error: để tạo một Cloud Anchor có thời gian tồn tại (TTL) từ 1 đến 365 ngày. Bạn cũng có thể gia hạn thời gian của quảng cáo cố định sau khi được lưu trữ bằng API Quản lý quảng cáo cố định trên đám mây.

/**
* This creates a new Cloud Anchor with a given lifetime in days, using the transform
 * of the provided anchor.
 *
 * The cloud state of the returned anchor will be set to GARCloudAnchorStateTaskInProgress and the
 * initial transform will be set to the transform of the provided anchor. However, the returned
 * anchor and the original anchor are independent of one another, and their two transforms
 * may diverge over time.
 *
 * Hosting requires a working Internet connection and an active session where the tracking state
 * is ARTrackingStateNormal. If it is unable to establish a connection to the ARCore Cloud Anchor
 * service, ARCore will continue to silently retry in the background.
 *
 * @param anchor The ARAnchor with the desired transform to be used to create a hosted Cloud
 *     Anchor.
 * @param TTLDays The anchor’s lifetime in days. Must be a positive number. The maximum
 * allowed value is 1 if you are using an API key to authorize the Cloud Anchor API call.
 * Otherwise, the maximum allowed value is 365.
 * @param error Out parameter for an NSError. Possible errors include:
 *     GARSessionErrorCodeInvalidArgument - Invalid (nil) anchor or invalid TTL.
 *     GARSessionErrorCodeNotTracking - Bad current ARTrackingState.
 *     GARSessionErrorCodeResourceExhausted - ARCore tried to create too many Cloud Anchors.
 * @return The new GARAnchor, or nil if there is an error.
 */

- (GARAnchor *_Nullable)hostCloudAnchor:(ARAnchor *)anchor
                                TTLDays:(NSInteger)TTLDays
                                  error:(NSError **)error;

Ủy quyền

Ứng dụng của bạn phải được phép sử dụng API Cloud Anchors. Bạn có thể sử dụng mã thông báo Web JSON (JWT) đã ký hoặc uỷ quyền khoá API.

Mã thông báo (uỷ quyền JWT)

Sử dụng uỷ quyền Web JSON (JWT) đã ký để lưu trữ một Cloud Anchor trong tối đa 365 ngày. Sử dụng uỷ quyền khóa API để lưu trữ Cloud Anchor trong tối đa một ngày.

Hiện tại, loại mã thông báo được hỗ trợ duy nhất là JWT đã ký (tức là mã thông báo Web JSON được ký bằng tài khoản Dịch vụ của Google). Hãy xem trang web chính thức của JWT để biết thông tin giới thiệu về JWT. Để tạo Mã thông báo web JSON cho iOS, bạn phải có một điểm cuối trên máy chủ đáp ứng các yêu cầu sau:

  • Cơ chế ủy quyền của riêng bạn phải bảo vệ điểm cuối.

  • Mỗi điểm cuối phải tạo một mã thông báo mới, chẳng hạn như:

    • Mỗi người dùng sẽ nhận được một mã thông báo riêng.
    • Mã thông báo không hết hạn ngay lập tức.

Tạo tài khoản dịch vụ và khoá ký

Làm theo các bước sau để tạo một tài khoản Google Service và khóa ký:

  1. Trong trình đơn điều hướng của Bảng điều khiển Google Cloud Platform, hãy chuyển đến APIs & Services > Credentials.

  2. Chọn dự án mong muốn, sau đó nhấp vào Create Credentials > Service account.

  3. Trong Service account details, hãy nhập tên cho tài khoản mới, sau đó nhấp vào Create.

  4. Trên trang Service account permissions, hãy chuyển đến trình đơn thả xuống Select a role. Chọn Service Accounts > Service Account Token Creator, sau đó nhấp vào Continue.

  5. Trên trang Grant users access to this service account, hãy nhấp vào Done. Thao tác này sẽ đưa bạn trở lại APIs & Services > Credentials.

  6. Trên trang Credentials, hãy di chuyển xuống phần Service Accounts rồi nhấp vào tên của tài khoản bạn vừa tạo.

  7. Trên trang Service account details, hãy di chuyển xuống phần Keys rồi chọn Add Key > Create new key.

  8. Chọn JSON làm loại khoá và nhấp vào Create. Thao tác này sẽ tải tệp JSON chứa khoá riêng tư xuống máy của bạn. Lưu trữ tệp khoá JSON đã tải xuống ở một vị trí an toàn.

Tạo mã thông báo trên máy chủ của bạn

Để tạo mã thông báo mới (JWT) trên máy chủ, hãy sử dụng thư viện JWT tiêu chuẩn và tệp JSON mà bạn đã tải xuống một cách an toàn từ tài khoản dịch vụ mới.

Tạo mã thông báo trên máy phát triển của bạn

Để tạo JWT trên máy phát triển, hãy sử dụng lệnh oauth2l sau:

oauth2l fetch --jwt --json $KEYFILE $AUDIENCE --cache ""

Bạn cần chỉ định vị trí bộ nhớ đệm trống bằng cách sử dụng cờ --cache để đảm bảo mỗi lần tạo một mã thông báo khác. Hãy cắt bớt chuỗi kết quả vì dấu cách thừa hoặc ký tự dòng mới sẽ khiến ARCore chèn lại mã thông báo.

Ký mã thông báo

Bạn phải sử dụng thuật toán RS256 và các tuyên bố sau đây để ký JWT:

  • iss — Địa chỉ email của tài khoản dịch vụ.
  • sub — Địa chỉ email của tài khoản dịch vụ.
  • iat – Thời gian Unix khi mã thông báo được tạo, tính bằng giây.
  • expiat + 3600 (1 giờ). Thời gian Unix khi mã thông báo hết hạn, tính bằng giây.
  • aud – Khán giả. "Đối tượng"chính xác cho API ARCore là https://arcore.googleapis.com/.

Các thông báo xác nhận quyền sở hữu không chuẩn là không bắt buộc trong tải trọng JWT, mặc dù bạn có thể thấy các thông báo xác nhận quyền sở hữu uid hữu ích để xác định người dùng tương ứng.

Nếu bạn sử dụng một phương pháp khác để tạo JWT, chẳng hạn như sử dụng API Google trong môi trường do Google quản lý, hãy nhớ ký JWT bằng các thông báo xác nhận quyền sở hữu trong phần này. Trên hết, hãy đảm bảo rằng đối tượng của bạn là chính xác.

Chuyển mã thông báo vào phiên ARCore

Trước tiên, hãy tạo một phiên hoạt động bằng cách sử dụng sessionWithError::

NSError *error = nil;
GARSession *session = [GARSession sessionWithError:&error];

Khi bạn nhận được mã thông báo, hãy chuyển mã đó vào phiên bằng cách sử dụng setAuthToken:.

/**
 * Provide an auth token to authorize your app to use the ARCore Cloud Anchor API. If
 * you used an API key to create the session, ARCore will ignore the token and log an error.
 * Otherwise, it will use the most recent valid auth token that you passed in. Call this
 * method each time you refresh your token.
 *
 * @param authToken The token to use when authorizing your call to the ARCore Cloud Anchor API. This
 *                  must be a nonempty ASCII string with no spaces or control characters. ARCore
 *                  will use this until you pass in another token. Currently, JWTs are the only
 *                  supported token types.
 */
- (void)setAuthToken:(NSString *)authToken;

Vui lòng lưu ý những điều sau khi bạn chuyển một mã thông báo vào phiên hoạt động này:

  • Nếu không truyền mã thông báo hợp lệ trước khi cố gắng lưu trữ hoặc giải quyết một neo, bạn sẽ gặp lỗi uỷ quyền.

  • ARCore bỏ qua các mã thông báo chứa dấu cách hoặc ký tự đặc biệt. ARCore cũng bỏ qua tất cả mã thông báo nếu bạn tạo phiên hoạt động bằng một khoá API hợp lệ. Nếu trước đây bạn đã sử dụng khoá API và không cần khoá đó nữa, thì bạn nên xoá khoá đó trong Google Developers Console và xoá khoá đó khỏi ứng dụng sau khi chuyển người dùng sang phiên bản mới nhất.

  • Mã thông báo thường hết hạn sau một giờ. Nếu có khả năng mã thông báo của bạn có thể hết hạn trong khi sử dụng, hãy lấy mã thông báo mới và chuyển mã đó đến API.

Ủy quyền khóa API

Sử dụng tùy chọn uỷ quyền khóa API để lưu trữ Cloud Anchor trong tối đa một ngày.

Hãy làm theo các bước sau để lấy và thêm khoá API vào dự án:

  1. Hãy xem Trung tâm trợ giúp của Bảng điều khiển Google Cloud Platform để lấy khoá API.

  2. Trong Xcode, hãy chuyển khoá API mới vào sessionWithAPIKey:bundleIdentifier:error: để thêm khoá đó vào dự án:

    NSError *error = nil;
    GARSession *session = [GARSession sessionWithAPIKey:@"your-api-key" bundleIdentifier:nil error:&error];
    

Chất lượng ánh xạ

API chất lượng ánh xạ ước tính chất lượng của các điểm tính năng trực quan mà ARCore nhìn thấy trong vài giây trước đó và hiển thị từ quá trình biến đổi máy ảnh đã cung cấp. Cloud Anchors lưu trữ bằng cách sử dụng các tính năng chất lượng cao hơn thường sẽ giúp quá trình chuyển đổi Cloud Anchor trở nên dễ dàng và chính xác hơn. Nếu không thể ước tính chất lượng bản đồ tính năng cho một phép biến đổi nhất định, ARCore sẽ ghi lại một thông báo cảnh báo và trả về GARFeatureMapQualityInsufficient. Trạng thái này cho biết ARCore có thể sẽ gặp khó khăn hơn khi phân giải Cloud Anchor. Khuyến khích người dùng di chuyển thiết bị để vị trí mong muốn của Cloud Anchor được lưu trữ sẽ được xem từ nhiều góc độ.

/**
 * @param transform The camera transform to use to estimate the mapping quality.
 * @param error Out parameter for an `NSError`. Possible errors:
 *        GARSessionErrorCodeNotTracking - Bad current ARTrackingState.
 * @return The estimated quality of the visual feature points seen
 *        by ARCore in the preceding few seconds and visible from the provided camera
 *        transform.
 */

- (GARFeatureMapQuality)estimateFeatureMapQualityForHosting:(simd_float4x4)transform
                                                      error:(NSError **)error;

Hạn mức API

API ARCore có các hạn mức sau đây cho băng thông yêu cầu:

Loại hạn mức Tối đa Thời lượng Áp dụng cho
Số lượng neo Vé loại không giới hạn Không áp dụng Dự án
Yêu cầu máy chủ cố định 30 phút Địa chỉ IP và dự án
Yêu cầu giải quyết neo 300 phút Địa chỉ IP và dự án

Các sự cố đã biết và cách giải quyết

Có một vài vấn đề đã biết khi làm việc với SDK ARCore cho iOS.

Chế độ cài đặt mặc định của giao thức gây ra sự cố ứng dụng gián đoạn

Các tuỳ chọn cài đặt Quy trình xác thực khung GPU và xác thực API kim loại được bật theo mặc định. Đôi khi, điều này có thể khiến ứng dụng gặp sự cố trong SDK.

Chẩn đoán sự cố ứng dụng

Bất cứ khi nào bạn nghi ngờ rằng đã xảy ra sự cố, hãy xem dấu vết ngăn xếp của mình. Nếu bạn thấy MTLDebugComputeCommandEncoder trong dấu vết ngăn xếp, thì có thể là do chế độ cài đặt lược đồ mặc định.

Giải pháp

  1. Chuyển đến Product > Scheme > Edit Scheme….

  2. Mở thẻ Run.

  3. Nhấp vào Options để xem chế độ cài đặt hiện tại của bạn.

  4. Đảm bảo rằng cả GPU Frame CaptureMetal API Validation đều đã tắt.

  5. Tạo bản dựng và chạy ứng dụng của bạn.

Hãy xem CocoaPods CHANGELOG để biết thêm các vấn đề đã biết.

Các điểm hạn chế

SDK ARCore cho iOS không hỗ trợ lệnh gọi phương thức ARKit setWorldOrigin(relativeTransform:).

Xem xét hiệu suất

Mức sử dụng bộ nhớ sẽ tăng lên khi bạn bật API ARCore. Tỷ lệ sử dụng pin của thiết bị sẽ tăng lên do mức sử dụng mạng và mức sử dụng CPU cao hơn.

Các bước tiếp theo