Delen via


Ankers maken en lokaliseren met behulp van Azure Spatial Anchors in Swift

Met Azure Spatial Anchors kunt u ankers delen tussen verschillende apparaten. Er worden meerdere ontwikkelomgevingen ondersteund. In dit artikel gaan we dieper in op het gebruik van de Azure Spatial Anchors SDK in Swift om:

  • een Azure Spatial Anchors-sessie correct in te stellen en te beheren.
  • eigenschappen op lokale ankers te maken en in te stellen.
  • gegevens naar de cloud te uploaden.
  • ruimtelijke ankers in de cloud te vinden en verwijderen.

Vereisten

Om deze zelfstudie te voltooien, moet u ervoor zorgen dat u:

Cross Platform

De sessie initialiseren

Het belangrijkste invoerpunt voor de SDK is de klasse die uw sessie weergeeft. Normaal gesproken declareert u een veld in de klasse waarmee uw weergave en de systeemeigen AR-sessie worden beheerd.

Meer informatie over de klasse ASACloudSpatialAnchorSession.

    var _cloudSession : ASACloudSpatialAnchorSession? = nil
    // In your view handler
    _cloudSession = ASACloudSpatialAnchorSession()

Verificatie instellen

Voor toegang tot de service moet u een accountsleutel, toegangstoken of Microsoft Entra-verificatietoken opgeven. U kunt hierover meer lezen op de conceptpagina Verificatie.

Accountsleutels

Accountsleutels zijn een referentie waarmee uw toepassing kan worden geverifieerd bij de service Azure Spatial Anchors. Het beoogde doel van accountsleutels is om snel aan de slag te kunnen. Met name tijdens de ontwikkelingsfase van de integratie van uw toepassing met Azure Spatial Anchors. Zo kunt u accountsleutels gebruiken door ze tijdens het ontwikkelen in uw clienttoepassingen in te sluiten. Naarmate u verdergaat met ontwikkelen, wordt het ten zeerste aanbevolen om over te stappen naar een verificatiemechanisme dat op productieniveau wordt ondersteund door Toegangstokens of Microsoft Entra-gebruikersverificatie. Als u een accountsleutel voor ontwikkeling wilt ophalen, gaat u in uw Azure Spatial Anchors-account en naar het tabblad Sleutels.

Meer informatie over de klasse ASASessionConfiguration.

    _cloudSession!.configuration.accountKey = "MyAccountKey"

Toegangstokens

Toegangstokens zijn een meer robuuste methode om verificatie uit te voeren bij Azure Spatial Anchors. Met name wanneer u de toepassing voorbereidt voor een productie-implementatie. Samengevat: stel een back-endservice in waarmee uw clienttoepassing veilig kan worden geverifieerd. Uw back-endservice communiceert tijdens runtime met AAD en met de beveiligingstokenservice van Azure Spatial Anchors om een toegangstoken aan te vragen. Dit token wordt vervolgens afgeleverd aan de clienttoepassing en wordt in de SDK gebruikt om verificatie bij Azure Spatial Anchors uit te voeren.

    _cloudSession!.configuration.accessToken = "MyAccessToken"

Als er geen toegangstoken is ingesteld, moet u de TokenRequired gebeurtenis afhandelen of de methode tokenRequired implementeren op het gemachtigde protocol.

U kunt de gebeurtenis synchroon afhandelen door de eigenschap voor de gebeurtenisargumenten in te stellen.

Meer informatie over de protocolmethode tokenRequired.

    internal func tokenRequired(_ cloudSession:ASACloudSpatialAnchorSession!, _ args:ASATokenRequiredEventArgs!) {
        args.accessToken = "MyAccessToken"
    }

Als u asynchroon werk in uw handler wilt uitvoeren, kunt u het instellen van het token uitstellen door een deferral-object aan te vragen en het vervolgens te voltooien, zoals in het volgende voorbeeld.

    internal func tokenRequired(_ cloudSession:ASACloudSpatialAnchorSession!, _ args:ASATokenRequiredEventArgs!) {
        let deferral = args.getDeferral()
        myGetTokenAsync( withCompletionHandler: { (myToken: String?) in
            if (myToken != nil) {
                args.accessToken = myToken
            }
            deferral?.complete()
        })
    }

Microsoft Entra-verificatie

Met Azure Spatial Anchors kunnen toepassingen ook worden geverifieerd met Microsoft Entra ID-tokens (Active Directory). U kunt bijvoorbeeld Microsoft Entra-tokens gebruiken om te integreren met Azure Spatial Anchors. Als een Enterprise gebruikers onderhoudt in Microsoft Entra ID, kunt u een Microsoft Entra-token van een gebruiker opgeven in de Azure Spatial Anchors SDK. Hierdoor kunt u zich rechtstreeks verifiëren bij de Azure Spatial Anchors-service voor een account dat deel uitmaakt van dezelfde Microsoft Entra-tenant.

    _cloudSession!.configuration.authenticationToken = "MyAuthenticationToken"

Net als bij toegangstokens moet u, als een Microsoft Entra-token niet is ingesteld, de tokenRequired-gebeurtenis afhandelen of de methode tokenRequired implementeren in het gemachtigde protocol.

U kunt de gebeurtenis synchroon afhandelen door de eigenschap voor de gebeurtenisargumenten in te stellen.

    internal func tokenRequired(_ cloudSession:ASACloudSpatialAnchorSession!, _ args:ASATokenRequiredEventArgs!) {
        args.authenticationToken = "MyAuthenticationToken"
    }

Als u asynchroon werk in uw handler wilt uitvoeren, kunt u het instellen van het token uitstellen door een deferral-object aan te vragen en het vervolgens te voltooien, zoals in het volgende voorbeeld.

    internal func tokenRequired(_ cloudSession:ASACloudSpatialAnchorSession!, _ args:ASATokenRequiredEventArgs!) {
        let deferral = args.getDeferral()
        myGetTokenAsync( withCompletionHandler: { (myToken: String?) in
            if (myToken != nil) {
                args.authenticationToken = myToken
            }
            deferral?.complete()
        })
    }

De bibliotheek instellen

Start() aanroepen om uw sessie in staat te stellen omgevingsgegevens te verwerken.

Als u gebeurtenissen wilt afhandelen die door de sessie worden gegenereerd, stelt u de eigenschap delegate van uw sessie in op een object, zoals uw weergave. Dit object moet het SSCCloudSpatialAnchorSessionDelegate-protocol implementeren.

Meer informatie over de start-methode.

    _cloudSession!.session = self.sceneView.session;
    _cloudSession!.delegate = self;
    _cloudSession!.start()

De sessie voorzien van frames

De ruimtelijke-ankersessie werkt door de ruimte rond de gebruiker toe te wijzen. Zo kunt u bepalen waar de ankers zich moeten bevinden. Mobiele platformen (iOS en Android) vereisen een systeemeigen aanroep naar de camerafeed om frames van de AR-bibliotheek van uw platform te verkrijgen. Daarentegen wordt de omgeving voortdurend gescand door HoloLens, dus er is geen specifieke aanroep nodig, zoals bij mobiele platforms.

Meer informatie over de ProcessFrame-methode.

    _cloudSession?.processFrame(self.sceneView.session.currentFrame)

De gebruiker feedback geven

U kunt code schrijven voor het verwerken van de actuele sessiegebeurtenis. Deze gebeurtenis wordt geactiveerd wanneer het begrip van uw omgeving door de sessie worden verbeterd. Hierdoor kunt u het volgende doen:

  • Klasse UserFeedback gebruiken om feedback te geven aan de gebruiker terwijl het apparaat beweegt en het begrip van de omgeving wordt bijgewerkt. Dit wilt doen
  • Bepaal op welk moment er voldoende getraceerde ruimtelijke gegevens zijn om ruimtelijke ankers te maken. U kunt dit vaststellen met ReadyForCreateProgress of RecommendedForCreateProgress. Als ReadyForCreateProgress meer is dan 1, zijn er voldoende gegevens om een ruimtelijk anker in de cloud op te slaan. Het is echter raadzaam te wachten tot RecommendedForCreateProgress groter is dan 1.

Meer informatie over de protocolmethode sessionUpdated.

    internal func sessionUpdated(_ cloudSession:ASACloudSpatialAnchorSession!, _ args:ASASessionUpdatedEventArgs!) {
        let status = args.status!
        if (status.userFeedback.isEmpty) {
            return
        }
        _feedback = "Feedback: \(FeedbackToString(userFeedback:status.userFeedback)) - Recommend Create=\(status.recommendedForCreateProgress * 100)"
    }

Een ruimtelijk anker in de cloud maken

Als u een ruimtelijk anker in de Cloud wilt maken, maakt u eerst een anker in het AR-systeem van uw platform en maakt u vervolgens een equivalent in de cloud. U gebruikt de CreateAnchorAsync()-methode.

Meer informatie over de klasse ASACloudSpatialAnchor.

    // Create a local anchor, perhaps by hit-testing and creating an ARAnchor
    var localAnchor : ARAnchor? = nil
    let hits = self.sceneView.session.currentFrame?.hitTest(CGPoint(x:0.5, y:0.5), types: ARHitTestResult.ResultType.estimatedHorizontalPlane)
    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
    localAnchor = ARAnchor(transform:hits![0].worldTransform)
    self.sceneView.session.add(anchor: _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.
    var cloudAnchor : ASACloudSpatialAnchor? = nil
    cloudAnchor = ASACloudSpatialAnchor()
    cloudAnchor!.localAnchor = localAnchor
    _cloudSession?.createAnchor(cloudAnchor!, withCompletionHandler: { (error: Error?) in
        if (error != nil) {
            _feedback = "Save Failed:\(error!.localizedDescription)"
            return
        }
        _feedback = "Created a cloud anchor with ID=\(cloudAnchor!.identifier!)"
    })

Zoals eerder beschreven, hebt u voldoende omgevingsgegevens nodig voor het maken van een nieuw ruimtelijk anker voor de cloud. Dit betekent dat ReadyForCreateProgress hoger dan 1 moet zijn, maar we raden u aan om te wachten tot RecommendedForCreateProgress hoger dan 1 is.

Meer informatie over de methode getStatusWithCompletionHandler.

    _cloudSession?.getStatusWithCompletionHandler( { (value:ASASessionStatus, error:Error?) in
        if (error != nil) {
            _feedback = "Session status error:\(error!.localizedDescription)"
            return
        }
        if (value!.recommendedForCreateProgress <> 1.0) {
            return
        }
        // Issue the creation request ...
    })

Eigenschappen instellen

U kunt ervoor kiezen bepaalde eigenschappen toe te voegen bij het opslaan van ruimtelijke ankers in de cloud. Zoals het type object dat wordt opgeslagen of basiseigenschappen, bijvoorbeeld of het voor interactie moet worden ingeschakeld. Dit kan handig zijn bij detectie: u kunt het object direct voor de gebruiker weergeven, bijvoorbeeld een afbeeldingskader met lege inhoud. Vervolgens krijgt een andere downloadactie op de achtergrond aanvullende statusdetails, bijvoorbeeld de afbeelding die in het kader moet worden weergegeven.

Meer informatie over de eigenschap appProperties.

    var cloudAnchor : ASACloudSpatialAnchor? = nil
    cloudAnchor = ASACloudSpatialAnchor()
    cloudAnchor!.localAnchor = localAnchor
    cloudAnchor!.appProperties = [ "model-type" : "frame", "label" : "my latest picture" ]
    _cloudSession?.createAnchor(cloudAnchor!, withCompletionHandler: { (error: Error?) in
        // ...
    })

Eigenschappen bijwerken

Als u de eigenschappen van een anker wilt bijwerken, gebruikt u methode UpdateAnchorProperties(). Als twee of meer apparaten de eigenschappen van hetzelfde anker op hetzelfde moment proberen bij te werken, wordt een model voor optimistische gelijktijdigheid gebruikt. Dit betekent dat de eerste schrijfbewerking wint. Bij alle andere schrijfbewerkingen wordt een gelijktijdigheidsfout weergeven: vernieuw de eigenschappen voordat u het opnieuw probeert.

Meer informatie over de methode updateAnchorProperties.

    var anchor : ASACloudSpatialAnchor? = /* locate your anchor */;
    anchor!.appProperties["last-user-access"] = "just now"
    _cloudSession?.updateAnchorProperties(anchor!, withCompletionHandler: { (error:Error?) in
        if (error != nil) {
            _feedback = "Updating Properties Failed:\(error!.localizedDescription)"
        }
    })

U kunt de locatie van een anker niet bijwerken wanneer het is gemaakt voor de service. U moet een nieuw anker maken en het oude verwijderen om een nieuwe positie bij te houden.

Als u geen anker hoeft te lokaliseren om de eigenschappen ervan bij te werken, kunt u methode GetAnchorPropertiesAsync() gebruiken, waarmee een CloudSpatialAnchor-object met eigenschappen wordt geretourneerd.

Meer informatie over de methode getAnchorProperties.

    _cloudSession?.getAnchorProperties("anchorId", withCompletionHandler: { (anchor:SCCCloudSpatialAnchor?, error:Error?) in
        if (error != nil) {
            _feedback = "Getting Properties Failed:\(error!.localizedDescription)"
        }
        if (anchor != nil) {
            anchor!.appProperties["last-user-access"] = "just now"
            _cloudSession?.updateAnchorProperties(anchor!, withCompletionHandler: { (error:Error?) in
                // ...
            })
        }
    })

Vervaldatum instellen

Het is ook mogelijk uw anker zodanig te configureren dat deze op een bepaalde datum verloopt. Wanneer een anker verloopt, kan het niet meer worden gelokaliseerd of bijgewerkt. De vervaldatum kan alleen worden ingesteld wanneer het anker wordt gemaakt, voordat het in de cloud wordt opgeslagen. Het is niet mogelijk de vervaldatum daarna nog bij te werken. Als er geen verloopdatum is ingesteld tijdens het maken van het anker, verloopt het anker alleen wanneer het handmatig wordt verwijderd.

Meer informatie over de eigenschap expiration.

    let secondsInAWeek = 60.0 * 60.0 * 24.0 * 7.0
    let oneWeekFromNow = Date(timeIntervalSinceNow: secondsInAWeek)
    cloudAnchor!.expiration = oneWeekFromNow

Een ruimtelijk anker in de cloud lokaliseren

Een van de belangrijkste redenen om Azure Spatial Anchors te gebruiken, is dat u een eerder opgeslagen ruimtelijk anker in de cloud kunt lokaliseren. Hiervoor gebruiken we Watchers. U kunt slechts één Watcher tegelijk gebruiken; meerdere Watchers worden niet ondersteund. Een Watcher kan op verschillende manieren (ook wel 'Anchor Locate Strategies' genoemd) een ruimtelijk anker in de cloud vinden. Voor een watcher kunt u één strategie per keer gebruiken.

  • Lokaliseer ankers op id.
  • Lokaliseer ankers die zijn verbonden met een eerder gelokaliseerd anker. U vindt hier informatie over ankerrelaties.
  • Lokaliseer een anker met grove herlokalisatie.

Notitie

Telkens wanneer u een anker lokaliseert, probeert Azure Spatial Anchors de omgevingsgegevens te gebruiken die zijn verzameld om de visuele informatie op het anker te verbeteren. Als u problemen ondervindt bij het lokaliseren van een anker, kan het nuttig zijn om een anker te maken en deze vervolgens meerdere keren vanuit verschillende hoeken en lichtomstandigheden te lokaliseren.

Als u ruimtelijke ankers voor de cloud op id zoekt, kunt u de ruimtelijke anker-id van de cloud opslaan in de back-endservice van uw toepassing en toegankelijk maken voor alle apparaten die er goed bij kunnen worden geverifieerd. Zie zelfstudie: Spatial Anchors delen op verschillende apparaten voor een voorbeeld hiervan.

Instantieer een AnchorLocateCriteria-object, stel de id's in die u zoekt en roep de CreateWatcher-methode voor de sessie aan door uw AnchorLocateCriteria op te geven.

Meer informatie over de createWatcherCreateWatcher-methode.

    let criteria = ASAAnchorLocateCriteria()!
    criteria.identifiers = [ "id1", "id2", "id3" ]
    _cloudSession!.createWatcher(criteria)

Nadat de watcher is gemaakt, wordt de AnchorLocated-gebeurtenis voor elk aangevraagd anker geactiveerd. Deze gebeurtenis wordt geactiveerd wanneer er een anker wordt gelokaliseerd of als het anker niet kan worden gelokaliseerd. Als deze situatie zich voordoet, wordt de reden aangegeven in de status. Nadat alle ankers voor een watcher zijn verwerkt, gevonden of niet gevonden, wordt de LocateAnchorsCompleted-gebeurtenis geactiveerd. Er geldt een limiet van 35 id's per watcher.

Meer informatie over de protocolmethode anchorLocated.

    internal func anchorLocated(_ cloudSession: ASACloudSpatialAnchorSession!, _ args: ASAAnchorLocatedEventArgs!) {
        let status = args.status
        switch (status) {
        case ASALocateAnchorStatus.located:
            let foundAnchor = args.anchor
            // Go add your anchor to the scene...
            break
        case ASALocateAnchorStatus.alreadyTracked:
            // This anchor has already been reported and is being tracked
            break
        case ASALocateAnchorStatus.notLocatedAnchorDoesNotExist:
            // 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 ASALocateAnchorStatus.notLocated:
            // 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
        }
    }

Ankers verwijderen

Het verwijderen van ankers wanneer deze niet meer wordt gebruikt, is een goede gewoonte om in uw ontwikkelingsproces en -procedures vroegtijdig op te nemen om uw Azure-resources te laten opschonen.

Meer informatie over de methode delete.

    _cloudSession?.delete(cloudAnchor!, withCompletionHandler: { (error: Error?) in
        // Perform any processing you may want when delete finishes
    })

De sessie onderbreken, opnieuw instellen of stoppen

Als u de sessie tijdelijk wilt stoppen, kunt u Stop() aanroepen. Als u dit doet, worden alle watchers en de omgevingsverwerking gestopt, zelfs als u ProcessFrame() aanroept. Vervolgens kunt u Start() aanroepen om de verwerking te hervatten. Bij het hervatten blijven de omgevingsgegevens die al in de sessie zijn vastgelegd, behouden.

Meer informatie over de stop-methode.

    _cloudSession!.stop()

Als u de omgevingsgegevens die in uw sessie zijn vastgelegd opnieuw wilt instellen, kunt u Reset()aanroepen.

Meer informatie over de reset-methode.

    _cloudSession!.reset()

Op de juiste manier opschonen nadat een sessie alle verwijzingen heeft uitgebracht.

    _cloudSession = nil

Volgende stappen

In deze handleiding hebt u geleerd hoe u ankers kunt maken en vinden met behulp van Azure Spatial Anchors SDK. Ga verder met de volgende handleiding voor meer informatie over ankerrelaties.