Skip to content

Core Remote Camera Remote Shutter

Mr.P edited this page Aug 25, 2026 · 2 revisions

Handle Remote Shutter

Receive remote-shutter events through DeviceDelegate, perform the corresponding app-camera action, and synchronize the result to the device.

Prerequisites

  • The device is connected and conforms to DeviceRemoteShutterAPI.
  • The app has an NSCameraUsageDescription entry and requests camera authorization.
  • The app owns an AVCaptureSession and photo-capture implementation.

API Reference

Protocol

Swift

/// The protocol for device remote shutter API.
protocol DeviceRemoteShutterAPI: DeviceAPI {
    /// Syncs the app’s real-time remote-shutter response state to the device after the device triggers remote shutter.
    /// - Parameters:
    ///   - state: The real-time remote-shutter response state to sync to the device.
    ///   - completion: A closure that is called when the operation completes.
    ///     - success: `true` if the operation was successful; otherwise `false`.
    ///     - error: An `NSError` object that describes the error that occurred, or `nil` if the operation was successful.
    func syncRemoteShutterStateToDevice(
        _ state: RemoteShutterState,
        completion: AIBudsCompletionHandler?
    )
}

Objective-C

/// The protocol for device remote shutter API.
@protocol AIBudsDeviceRemoteShutterAPI <AIBudsDeviceAPI>
    /// Syncs the app’s real-time remote-shutter response state to the device after the device triggers remote shutter.
    /// - Parameters:
    ///   - state: The real-time remote-shutter response state to sync to the device.
    ///   - completion: A closure that is called when the operation completes.
    ///     - success: `true` if the operation was successful; otherwise `false`.
    ///     - error: An `NSError` object that describes the error that occurred, or `nil` if the operation was successful.
    - (void)syncRemoteShutterStateToDevice:(enum AIBudsRemoteShutterState)state
        completion:(AIBudsCompletionHandler _Nullable)completion;
@end

See syncRemoteShutterStateToDevice in the API Reference.

Delegate Callback

Swift

/// Callback when remote shutter event received
/// - Parameters:
///   - device: the device
///   - event: the remote shutter event
optional func device(
    _ device: DeviceConvertible,
    didReceiveRemoteShutterEvent event: RemoteShutterEvent
)

Objective-C

/// Callback when remote shutter event received
/// - Parameters:
///   - device: the device
///   - event: the remote shutter event
- (void)device:(id<AIBudsDeviceConvertible> _Nonnull)device
        didReceiveRemoteShutterEvent:(enum AIBudsRemoteShutterEvent)event;

Usage Examples

The example delegates app-camera details to local methods so the SDK event flow remains clear.

Swift

func device(
    _ device: DeviceConvertible,
    didReceiveRemoteShutterEvent event: RemoteShutterEvent
) {
    guard let remoteShutter = device as? DeviceRemoteShutterAPI else { return }

    switch event {
    case .enter:
        prepareAppCamera { ready in
            let state: RemoteShutterState = ready
                ? .enteredPhotoMode
                : .exitedOrUnableToEnter
            remoteShutter.syncRemoteShutterStateToDevice(state, completion: nil)
        }
    case .capture:
        captureAppPhoto { success in
            remoteShutter.syncRemoteShutterStateToDevice(
                success ? .photoSuccess : .photoFailed,
                completion: nil
            )
        }
    case .exit:
        stopAppCamera()
        remoteShutter.syncRemoteShutterStateToDevice(
            .exitedOrUnableToEnter,
            completion: nil
        )
    case .unknown:
        break
    }
}

Objective-C

- (void)device:(id<AIBudsDeviceConvertible>)device
    didReceiveRemoteShutterEvent:(AIBudsRemoteShutterEvent)event {
    id<AIBudsDeviceRemoteShutterAPI> remoteShutter =
        (id<AIBudsDeviceRemoteShutterAPI>)device;
    if (![remoteShutter conformsToProtocol:@protocol(AIBudsDeviceRemoteShutterAPI)]) return;

    switch (event) {
        case AIBudsRemoteShutterEventEnter:
            [self prepareAppCameraWithCompletion:^(BOOL ready) {
                AIBudsRemoteShutterState state = ready
                    ? AIBudsRemoteShutterStateEnteredPhotoMode
                    : AIBudsRemoteShutterStateExitedOrUnableToEnter;
                [remoteShutter syncRemoteShutterStateToDevice:state completion:nil];
            }];
            break;
        case AIBudsRemoteShutterEventCapture:
            [self captureAppPhotoWithCompletion:^(BOOL success) {
                AIBudsRemoteShutterState state = success
                    ? AIBudsRemoteShutterStatePhotoSuccess
                    : AIBudsRemoteShutterStatePhotoFailed;
                [remoteShutter syncRemoteShutterStateToDevice:state completion:nil];
            }];
            break;
        case AIBudsRemoteShutterEventExit:
            [self stopAppCamera];
            [remoteShutter syncRemoteShutterStateToDevice:AIBudsRemoteShutterStateExitedOrUnableToEnter completion:nil];
            break;
        default:
            break;
    }
}

Error Handling

Report .photoFailed when capture fails because permission is denied, storage is unavailable, or the app camera cannot capture. Report .exitedOrUnableToEnter when the app cannot enter photo mode or has left it.

AIBuds SDK iOS Wiki

Clone this wiki locally