Come creare e individuare ancoraggi usando Ancoraggi nello spazio di Azure in Objective-C

Ancoraggi nello spazio di Azure è un servizio che consente di condividere ancoraggi nel mondo tra dispositivi diversi. Supporta vari ambienti di sviluppo differenti. Questo articolo illustra nel dettaglio come usare l'SDK di Ancoraggi nello spazio di Azure, in Objective-C, per:

  • Configurare e gestire in modo corretto una sessione di Ancoraggi nello spazio di Azure.
  • Creare e impostare le proprietà sugli ancoraggi locali.
  • Caricarli nel cloud.
  • Trovare ed eliminare gli ancoraggi nello spazio nel cloud.

Prerequisiti

Per completare le procedure contenute in questa guida, verificare che siano soddisfatti i requisti seguenti:

Cross Platform

Inizializzare la sessione

Il punto di ingresso principale dell'SDK è la classe che rappresenta la sessione. In genere nella classe si dichiara un campo che gestisce la visualizzazione e la sessione AR nativa.

Altre informazioni sulla classe ASACloudSpatialAnchorSession.

    ASACloudSpatialAnchorSession *_cloudSession;
    // In your view handler
    _cloudSession = [[ASACloudSpatialAnchorSession alloc] init];

Configurazione dell'autenticazione

Per accedere al servizio, è necessario fornire una chiave dell'account, un token di accesso o un token di autenticazione di Microsoft Entra. Per altre informazioni, vedere la pagina relativa al concetto di autenticazione.

Chiavi dell'account

Le chiavi dell'account sono credenziali che consentono all'applicazione di eseguire l'autenticazione con il servizio degli ancoraggi nello spazio di Azure. Le chiavi dell'account consentono di essere subito operativi, soprattutto durante la fase di sviluppo dell'integrazione dell'applicazione con gli ancoraggi nello spazio di Azure. Di conseguenza, è possibile usare le chiavi dell'account incorporandole nelle applicazioni client durante lo sviluppo. Man mano che si procede oltre lo sviluppo, è consigliabile passare a un meccanismo di autenticazione a livello di produzione, supportato dai token di accesso o dall'autenticazione utente di Microsoft Entra. Per ottenere una chiave dell'account per lo sviluppo, visitare l'account ancoraggi nello spazio di Azure e passare alla scheda "Chiavi".

Altre informazioni sulla classe ASASessionConfiguration.

    _cloudSession.configuration.accountKey = @"MyAccountKey";

Token di accesso

I token di accesso sono un metodo più affidabile per l'autenticazione con gli ancoraggi nello spazio di Azure, soprattutto quando si prepara l'applicazione per una distribuzione di produzione. Il riepilogo di questo approccio consiste nel configurare un servizio back-end con cui l'applicazione client può eseguire l'autenticazione in modo sicuro. Il servizio back-end si interfaccia con AAD in fase di esecuzione e con il servizio token sicuro degli ancoraggi nello spazio di Azure per richiedere un token di accesso. Questo token viene quindi distribuito all'applicazione client e usato nell'SDK per eseguire l'autenticazione con gli ancoraggi nello spazio di Azure.

    _cloudSession.configuration.accessToken = @"MyAccessToken";

Se non è impostato alcun token di accesso, è necessario gestire l'evento TokenRequired oppure implementare il metodo tokenRequired per il protocollo delegato.

È possibile gestire l'evento in modo sincrono impostando la proprietà sugli argomenti dell'evento.

Altre informazioni sul metodo di protocollo tokenRequired.

    - (void)tokenRequired:(ASACloudSpatialAnchorSession *)cloudSession :(ASATokenRequiredEventArgs *)args {
        args.accessToken = @"MyAccessToken";
    }

Se è necessario eseguire operazioni asincrone nel gestore, è possibile rinviare l'impostazione del token richiedendo un oggetto deferral e quindi completarlo, come nell'esempio seguente.

    - (void)tokenRequired:(ASACloudSpatialAnchorSession *)cloudSession :(ASATokenRequiredEventArgs *)args {
        ASACloudSpatialAnchorSessionDeferral *deferral = [args getDeferral];
        [myGetTokenAsync callback:^(NSString *myToken) {
            if (myToken) args.accessToken = myToken;
            [deferral complete];
        }];
    }

Autenticazione Microsoft Entra

Ancoraggi nello spazio di Azure consente anche alle applicazioni di eseguire l'autenticazione con token microsoft Entra ID (Active Directory). Ad esempio, è possibile usare i token Microsoft Entra per l'integrazione con Ancoraggi nello spazio di Azure. Se un'azienda gestisce gli utenti in Microsoft Entra ID, è possibile fornire un token Microsoft Entra utente in Azure Spatial Anchors SDK. In questo modo è possibile eseguire l'autenticazione direttamente nel servizio Ancoraggi nello spazio di Azure per un account che fa parte dello stesso tenant di Microsoft Entra.

    _cloudSession.configuration.authenticationToken = @"MyAuthenticationToken";

Analogamente ai token di accesso, se non è impostato un token Microsoft Entra, è necessario gestire l'evento TokenRequired o implementare il metodo tokenRequired nel protocollo delegato.

È possibile gestire l'evento in modo sincrono impostando la proprietà sugli argomenti dell'evento.

    - (void)tokenRequired:(ASACloudSpatialAnchorSession *)cloudSession :(ASATokenRequiredEventArgs *)args {
        args.authenticationToken = @"MyAuthenticationToken";
    }

Se è necessario eseguire operazioni asincrone nel gestore, è possibile rinviare l'impostazione del token richiedendo un oggetto deferral e quindi completarlo, come nell'esempio seguente.

    - (void)tokenRequired:(ASACloudSpatialAnchorSession *)cloudSession :(ASATokenRequiredEventArgs *)args {
        ASACloudSpatialAnchorSessionDeferral *deferral = [args getDeferral];
        [myGetTokenAsync callback:^(NSString *myToken) {
            if (myToken) args.authenticationToken = myToken;
            [deferral complete];
        }];
    }

Configurazione della libreria

Richiamare Start() per consentire alla sessione di elaborare i dati dell'ambiente.

Per gestire gli eventi generati dalla sessione, impostare la proprietà delegate della sessione su un oggetto, ad esempio la visualizzazione. L'oggetto deve implementare il protocollo SSCCloudSpatialAnchorSessionDelegate.

Altre informazioni sul metodo start.

    _cloudSession.session = self.sceneView.session;
    _cloudSession.delegate = self;
    [_cloudSession start];

Fornire fotogrammi alla sessione

Durante la sessione di ancoraggio nello spazio viene eseguito il mapping dello spazio intorno all'utente. Questa operazione consente di determinare dove si trovano gli ancoraggi. Le piattaforme per dispositivi mobili (iOS e Android) richiedono una chiamata nativa al feed della fotocamera per ottenere i fotogrammi dalla libreria AR della piattaforma. Al contrario, HoloLens analizza continuamente l'ambiente e, di conseguenza, non è necessario eseguire una chiamata specifica come avviene nelle piattaforme per dispositivi mobili.

Altre informazioni sul metodo processFrame.

    [_cloudSession processFrame:_sceneView.session.currentFrame];

Fornire feedback all'utente

È possibile scrivere codice per gestire l'evento di aggiornamento della sessione. Questo evento viene generato ogni volta che la sessione migliora il riconoscimento dell'ambiente circostante. In questo modo è possibile:

  • Usare la classe UserFeedback per fornire feedback all'utente quando il dispositivo viene spostato e la sessione aggiorna il riconoscimento dell'ambiente. A tale scopo, seguire questa procedura:
  • Determinare in quale punto sono disponibili dati spaziali rilevati sufficienti per creare ancoraggi nello spazio. Per questa operazione si usa ReadyForCreateProgress o RecommendedForCreateProgress. Quando il valore di ReadyForCreateProgress è maggiore di 1, i dati disponibili sono sufficienti per salvare un ancoraggio nello spazio cloud, anche se è consigliabile attendere fino a quando il valore di RecommendedForCreateProgress non diventa maggiore di 1.

Altre informazioni sul metodo di protocollo sessionUpdated.

    - (void)sessionUpdated:(ASACloudSpatialAnchorSession *)cloudSession :(ASASessionUpdatedEventArgs *)args {
        ASASessionStatus *status = [args status];
        if (status.userFeedback == ASASessionUserFeedbackNone) return;
        _feedback = [NSString
            stringWithFormat:@"Feedback: %@ - Recommend Create=%.0f%%",
            FeedbackToString(status.userFeedback),
            status.recommendedForCreateProgress * 100.f];
    }

Creare un ancoraggio nello spazio cloud

Per creare un ancoraggio nello spazio cloud, creare prima un ancoraggio nel sistema AR della piattaforma e quindi una controparte cloud. A questo scopo, usare il metodo CreateAnchorAsync().

Altre informazioni sulla classe ASACloudSpatialAnchor.

    // Create a local anchor, perhaps by hit-testing and creating an ARAnchor
    NSArray<ARHitTestResult *> *hits = [_sceneView.session.currentFrame hitTest:CGPointMake(0.5, 0.5) types:ARHitTestResultTypeEstimatedHorizontalPlane];
    if ([hits count] == 0) return;
    // The hitTest method sorts the resulting list by increasing distance from the camera
    // The first hit result will usually be the most relevant when responding to user input
    ARAnchor *localAnchor = [[ARAnchor alloc] initWithTransform:hits[0].worldTransform];
    [_sceneView.session addAnchor:localAnchor];

    // If the user is placing some application content in their environment,
    // you might show content at this anchor for a while, then save when
    // the user confirms placement.
    ASACloudSpatialAnchor *cloudAnchor = [[ASACloudSpatialAnchor alloc] init];
    cloudAnchor.localAnchor = localAnchor;
    [_cloudSession createAnchor:cloudAnchor withCompletionHandler:^(NSError *error) {
        if (error) {
            _feedback = [NSString stringWithFormat:@"Save Failed:%@", error.localizedDescription];
            return;
        }
        _feedback = [NSString stringWithFormat:@"Created a cloud anchor with ID=%@", cloudAnchor.identifier];
    }];

Come descritto in precedenza, è necessario acquisire dati di ambiente sufficienti prima di provare a creare un nuovo ancoraggio nello spazio cloud. Questo significa che il valore di ReadyForCreateProgress deve essere maggiore di 1, anche se è consigliabile attendere fino a quando il valore di RecommendedForCreateProgress non diventa maggiore di 1.

Altre informazioni sul metodo getSessionStatusWithCompletionHandler.

    [_cloudSession getSessionStatusWithCompletionHandler:^(ASASessionStatus *value, NSError *error) {
        if (error) {
            _feedback = [NSString stringWithFormat:@"Session status error:%@", error.localizedDescription];
            return;
        }
        if (value.recommendedForCreateProgress < 1.0f) return;
        // Issue the creation request ...
    }];

Impostare le proprietà

Quando si salvano gli ancoraggi nello spazio cloud, è possibile scegliere di aggiungere alcune proprietà, ad esempio il tipo di oggetto da salvare oppure proprietà di base relative all'abilitazione per l'interazione. Questa operazione può essere utile al momento dell'individuazione. È infatti possibile eseguire immediatamente il rendering dell'oggetto per l'utente, ad esempio un fotogramma immagine con contenuto vuoto. Con un download diverso in background si ottengono quindi altri dettagli sullo stato, ad esempio l'immagine da visualizzare nel fotogramma.

Altre informazioni sulla proprietà appProperties.

    ASACloudSpatialAnchor *cloudAnchor = [[ASACloudSpatialAnchor alloc] init];
    cloudAnchor.localAnchor = localAnchor;
    cloudAnchor.appProperties = @{ @"model-type" : @"frame", @"label" : @"my latest picture" };
    [_cloudSession createAnchor:cloudAnchor withCompletionHandler:^(NSError *error) {
        // ...
    });

Aggiornare le proprietà

Per aggiornare le proprietà di un ancoraggio, si usa il metodo UpdateAnchorProperties(). Se due o più dispositivi provano ad aggiornare le proprietà per lo stesso ancoraggio nello stesso momento, viene usato un modello di concorrenza ottimistica, in base al quale prevale la prima operazione di scrittura eseguita. Per tutte le altre operazioni di scrittura verrà restituito un errore di "concorrenza" e sarà necessario aggiornare le proprietà prima di riprovare.

Altre informazioni sul metodo updateAnchorProperties.

    ASACloudSpatialAnchor *anchor = /* locate your anchor */;
    [anchor.appProperties setValue:@"just now" forKey:@"last-user-access"];
    [_cloudSession updateAnchorProperties:anchor withCompletionHandler:^(NSError *error) {
        if (error) _feedback = [NSString stringWithFormat:@"Updating Properties Failed:%@", error.localizedDescription];
    }];

Non è possibile aggiornare la posizione di un ancoraggio dopo che è stata creato nel servizio, ma è necessario creare un nuovo ancoraggio ed eliminare quello precedente per tenere traccia di una nuova posizione.

Se non è necessario individuare un ancoraggio per aggiornarne le proprietà, è possibile usare il metodo GetAnchorPropertiesAsync(), che restituisce un oggetto CloudSpatialAnchor con le proprietà.

Altre informazioni sul metodo getAnchorProperties.

    [_cloudSession getAnchorProperties:@"anchorId" withCompletionHandler:^(SCCCloudSpatialAnchor *anchor, NSError *error) {
        if (error) {
            _feedback = [NSString stringWithFormat:@"Getting Properties Failed:%@", error.localizedDescription];
            return;
        }
        if (anchor) {
            [anchor.appProperties setValue:@"just now" forKey:@"last-user-access"];
            [_cloudSession updateAnchorProperties:anchor withCompletionHandler:^(NSError *error) {
                // ...
            }];
        }
    }];

Imposta scadenza

È anche possibile configurare l'ancoraggio in modo che scada automaticamente in una data specifica in futuro. Un ancoraggio scaduto non viene più individuato né aggiornato. La scadenza può essere impostata solo quando viene creato l'ancoraggio, prima di salvarlo nel cloud. e non può essere aggiornata in un secondo momento. Se non viene impostata alcuna scadenza durante la creazione dell'ancoraggio, l'ancoraggio scadrà solo quando viene eliminato manualmente.

Altre informazioni sulla proprietà expiration.

    int secondsInAWeek = 60 * 60 * 24 * 7;
    NSDate *oneWeekFromNow = [[NSDate alloc] initWithTimeIntervalSinceNow: (NSTimeInterval) secondsInAWeek];
    cloudAnchor.expiration = oneWeekFromNow;

Individuare un ancoraggio nello spazio cloud

La possibilità di individuare un ancoraggio nello spazio cloud salvato in precedenza è uno dei motivi principali per usare gli ancoraggi nello spazio di Azure. Per questo motivo, usiamo "Watchers". È possibile usare un solo Watcher alla volta; più watcher non sono supportati. Esistono diversi modi (noti anche come strategie di individuazione ancoraggio) che un Watcher può individuare un ancoraggio nello spazio cloud. È possibile usare una strategia in un watcher alla volta.

  • Individuare gli ancoraggi in base all'identificatore.
  • Individuare gli ancoraggi connessi a un ancoraggio individuato in precedenza. Per altre informazioni sulle relazioni tra ancoraggi, vedere qui.
  • Individuare un ancoraggio tramite la rilocalizzazione grossolana.

Nota

Ogni volta che si individua un ancoraggio, Ancoraggi nello spazio di Azure proverà a usare i dati dell'ambiente raccolti per incrementare le informazioni che visualizza. Se si verificano problemi durante l'individuazione di un ancoraggio, può essere utile creare un ancoraggio, quindi individuarlo più volte da varie angolazioni e con condizioni di illuminazione diverse.

Se si individuano ancoraggi nello spazio cloud in base all'identificatore, è possibile archiviare l'identificatore di ancoraggio nello spazio cloud nel servizio back-end dell'applicazione e renderlo accessibile a tutti i dispositivi che possono eseguire correttamente l'autenticazione. Per un esempio, vedere Esercitazione: Condividere ancoraggi nello spazio tra dispositivi.

Creare un'istanza dell'oggetto AnchorLocateCriteria, impostare gli identificatori da cercare e richiamare il metodo CreateWatcher nella sessione specificando AnchorLocateCriteria.

Altre informazioni sul metodo createWatcher.

    ASAAnchorLocateCriteria *criteria = [ASAAnchorLocateCriteria new];
    criteria.identifiers = @[ @"id1", @"id2", @"id3" ];
    [_cloudSession createWatcher:criteria];

Dopo la creazione del Watcher, l'evento AnchorLocated viene attivato per ogni ancoraggio richiesto. Questo evento viene generato quando viene individuato un ancoraggio o se non è possibile individuarlo. Se si verifica questa situazione, il motivo verrà indicato nello stato. Dopo che tutti gli ancoraggi per un Watcher vengono elaborati, che siano stati trovati o no, viene generato l'evento LocateAnchorsCompleted. È previsto un limite di 35 identificatori per Watcher.

Altre informazioni sul metodo di protocollo anchorLocated.

    - (void)anchorLocated:(ASACloudSpatialAnchorSession *)cloudSession :(ASAAnchorLocatedEventArgs *)args {
        ASALocateAnchorStatus status = [args status];
        switch (status) {
        case ASALocateAnchorStatusLocated: {
            ASACloudSpatialAnchor *foundAnchor = [args anchor];
            // Go add your anchor to the scene...
        }
            break;
        case ASALocateAnchorStatusAlreadyTracked:
            // This anchor has already been reported and is being tracked
            break;
        case ASALocateAnchorStatusNotLocatedAnchorDoesNotExist:
            // The anchor was deleted or never existed in the first place
            // Drop it, or show UI to ask user to anchor the content anew
            break;
        case ASALocateAnchorStatusNotLocated:
            // The anchor hasn't been found given the location data
            // The user might in the wrong location, or maybe more data will help
            // Show UI to tell user to keep looking around
            break;
    }

Eliminare gli ancoraggi

L'eliminazione di ancoraggi quando non sono più in uso è una prassi valida da includere nelle prime fasi del processo e delle procedure di sviluppo, per mantenere pulite le risorse di Azure.

Altre informazioni sul metodo deleteAnchor.

    [_cloudSession deleteAnchor:cloudAnchor withCompletionHandler:^(NSError *error) {
        // Perform any processing you may want when delete finishes
    }];

Sospendere, reimpostare o arrestare la sessione

Per arrestare temporaneamente la sessione, è possibile richiamare Stop(). In questo modo verranno arrestati tutti i watcher oltre all'elaborazione dell'ambiente, anche se si richiama ProcessFrame(). È quindi possibile richiamare Start() per riprendere l'elaborazione. Quando si riprende l'elaborazione, i dati dell'ambiente già acquisiti nella sessione vengono mantenuti.

Altre informazioni sul metodo stop.

    [_cloudSession stop];

Per reimpostare i dati dell'ambiente acquisiti nella sessione, è possibile richiamare Reset().

Altre informazioni sul metodo reset.

    [_cloudSession reset];

Per eseguire la corretta pulizia dopo una sessione, rilasciare tutti i riferimenti.

    _cloudSession = NULL;

Passaggi successivi

In questa guida si è appreso come creare e individuare ancoraggi usando Azure Spatial Anchors SDK. Per altre informazioni sulle relazioni tra ancoraggi, passare alla guida successiva.