Skip to Content
Technical Articles
Author's profile photo Kevin Muessig

Create an AR Experience within your App

The FioriAR Swift Package Version 2.0

In December 2021, the 2.0 Release for the FioriAR Swift package got pushed to GitHub. This latest release introduced SAP Mobile Services integration APIs which can be utilized within your app. The service integration brings you the possibility to upload AR Scene experiences directly to SAP Mobile Services in order for easier maintenance and on-the-fly changes of the scene. Within your app, you can fetch a specific scene from SAP Mobile Services directly into your app and display it with the FioriAR APIs. That gives you high flexibility on how you manage your AR experiences without the need for shipping an update for your app because the changes get infused during runtime.

What is a SceneAuthoringView?

The SceneAuthoringView, is a SwiftUI view responsible for creating an AR Scene from within your app. You can choose to display this view in order to allow your users to create AR Scenes on their own without the need of involving Reality Composer. You can even add an Image Anchor at any time.

This allows you to have a simple way for creating AR scenes on-the-fly and directly publishing them to SAP Mobile Services. Through delegation you get a callback about the successful creation of the AR scene on SAP Mobile Services. SAP Mobile Services returns an ID to you which you can store in your database entity or within the cache of your app in case you want to retrieve the created scene at a later point. This is really powerful because you can not only create AR scenes but also change them during runtime of your app without the need of shipping an update.

The view itself is invoked really easy and can even be initialized and put on the navigation stack with UIKit.

For the full example, please clone the FioriAR GitHub repository and refer to the Example App.

SwiftUI Example

import FioriAR
import SAPFoundation
import SwiftUI

struct ARCardAuthoringContentView: View {
    private var sapURLSession = SAPURLSession.createOAuthURLSession(
        clientID: IntegrationTest.System.clientID,
        authURL: IntegrationTest.System.authURL,
        redirectURL: IntegrationTest.System.redirectURL,
        tokenURL: IntegrationTest.System.tokenURL
    )

    var body: some View {
        SceneAuthoringView(title: "Annotations",
                           serviceURL: URL(string: IntegrationTest.System.redirectURL)!,
                           sapURLSession: sapURLSession,
                           sceneIdentifier: SceneIdentifyingAttribute.id(IntegrationTest.TestData.sceneId)) // Alternative Scene: 20110993
            .onSceneEdit { sceneEdit in
                switch sceneEdit {
                case .created(card: let card):
                    print("Created: \(card.title_)")
                case .updated(card: let card):
                    print("Updated: \(card.title_)")
                case .deleted(card: let card):
                    print("Deleted: \(card.title_)")
                case .published(sceneID: let sceneID):
                    print("From SceneEdit:", sceneID)
                }
            }
    }
}

UIKit Example

import FioriAR
import SAPFoundation
import SwiftUI
import UIKit

struct SceneAuthoringWithUIKitView: View {
    var body: some View {
        SceneAuthoringControllerContainer()
            .navigationBarTitle("Using UIKit")
    }
}

// Implemented just to present SceneAuthoringController in Test App which is SwiftUI based
struct SceneAuthoringControllerContainer: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> ARCardsAuthoringControllerVC {
        ARCardsAuthoringControllerVC()
    }
    
    func updateUIViewController(_ uiViewController: ARCardsAuthoringControllerVC, context: Context) {}
}

class ARCardsAuthoringControllerVC: UIViewController {
    var presentSceneAuthoring: UIButton!
    
    private var sapURLSession = SAPURLSession.createOAuthURLSession(
        clientID: IntegrationTest.System.clientID,
        authURL: IntegrationTest.System.authURL,
        redirectURL: IntegrationTest.System.redirectURL,
        tokenURL: IntegrationTest.System.tokenURL
    )
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.presentSceneAuthoring = UIButton()
        self.presentSceneAuthoring.setTitle("Present Scene Authoring", for: .normal)
        self.presentSceneAuthoring.setTitleColor(.white, for: .normal)
        self.presentSceneAuthoring.layer.cornerRadius = 10
        self.presentSceneAuthoring.backgroundColor = .systemBlue
        
        view.addSubview(self.presentSceneAuthoring)
        self.presentSceneAuthoring.translatesAutoresizingMaskIntoConstraints = false
        self.presentSceneAuthoring.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        self.presentSceneAuthoring.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -100).isActive = true
        self.presentSceneAuthoring.widthAnchor.constraint(equalToConstant: 250).isActive = true
        self.presentSceneAuthoring.heightAnchor.constraint(equalToConstant: 60).isActive = true
        self.presentSceneAuthoring.addTarget(self, action: #selector(self.presentSceneAuthoringAction), for: .touchUpInside)
    }
    
    // Use navigationController?.pushViewController()
    // Modal presenting not supported
    @objc func presentSceneAuthoringAction(sender: UIButton) {
        let sceneAuthoringController = SceneAuthoringController(title: "Annotations",
                                                                serviceURL: URL(string: IntegrationTest.System.redirectURL)!,
                                                                sapURLSession: self.sapURLSession,
                                                                sceneIdentifier: SceneIdentifyingAttribute.id(IntegrationTest.TestData.sceneId),
                                                                onSceneEdit: self.onSceneEdit)
        self.navigationController?.pushViewController(sceneAuthoringController, animated: true)
    }
    
    func onSceneEdit(sceneEdit: SceneEditing) {
        switch sceneEdit {
        case .created(card: let card):
            print("Created: \(card.title_)")
        case .updated(card: let card):
            print("Updated: \(card.title_)")
        case .deleted(card: let card):
            print("Deleted: \(card.title_)")
        case .published(sceneID: let sceneID):
            print("From SceneEdit:", sceneID)
        }
    }
}

How can SAP Mobile Services help me change my apps AR experience?

As previously mentioned, SAP Mobile Services stores published AR Scenes and allows you to manage them in an easy manner. The only thing you need to do is add the Mobile Augmented Reality feature to your native mobile app definition.

SAP%20Mobile%20Services%20-%20Mobile%20Augmented%20Reality%20Feature

SAP Mobile Services – Mobile Augmented Reality Feature

If you open the Mobile Augmented Reality feature, you can see a list of published AR scenes and their corresponding IDs. With these IDs you can fetch the AR Scene from within your app using the asynchronous service strategy provided by the FioriAR API.

@StateObject var asyncStrategy = ServiceStrategy<CodableCardItem>(
        serviceURL: URL(string: IntegrationTest.System.redirectURL)!,
        sapURLSession: SAPURLSession.createOAuthURLSession(
            clientID: IntegrationTest.System.clientID,
            authURL: IntegrationTest.System.authURL,
            redirectURL: IntegrationTest.System.redirectURL,
            tokenURL: IntegrationTest.System.tokenURL
        ),
        sceneIdentifier: SceneIdentifyingAttribute.id(1234455)
    )

 

Edit an AR Scene with SAP Mobile Services

If you click on the Pencil icon for a specific AR Scene, SAP Mobile Services allows you to make changes to the properties of that scene. It also allows you to change the Image Anchor!

SAP%20Mobile%20Services%20-%20Edit%20AR%20Scene

SAP Mobile Services – Edit AR Scene

Next time you fetch that specific AR scene from within your app, all changes made apply directly.

Add additional Locales to your AR Scene

To make your app accessible throughout the world, localization is key. Luckily, you don’t need to create 20 different reality scenes to support localization, instead you can add additional languages through the Mobile Augmented Reality feature on SAP Mobile Services.

By clicking the icon on an AR Scene you can start the process.

SAP%20Mobile%20Services%20-%20Add%20additional%20Languages

SAP Mobile Services – Add additional Languages

Ressources

This blog post is just an introduction to the power of the FioriAR 2.0 release, if you are interest in trying it out yourself see the list of resources down below.

And as always: Keep Coding!

Assigned Tags

      1 Comment
      You must be Logged on to comment or reply to a post.
      Author's profile photo Florian Pfeffer
      Florian Pfeffer

      Hey Kevin,

      thanks for sharing.

      Do you know if something similar is on the road for Android (based on ARCore)?

      Thx,

      Florian