Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
MarcoEidinger
Product and Topic Expert
Product and Topic Expert
In this blog post, I share code snippets and examples from my YouTube session "Build beautiful, native mobile applications with SAP Fiori for iOS" as part of SAP's Devtoberfest 2022.

https://youtu.be/tW6-T3hLR1c

The session's highlight is leveraging the live preview capabilities within Xcode to explore and configure UI components without running the iOS app.

Here is the code for the ViewController extension to use a view controller in a SwiftUI preview.
#if canImport(SwiftUI) && DEBUG
extension UIViewController {

private struct Preview: UIViewControllerRepresentable {
let viewController: UIViewController

func makeUIViewController(context: Context) -> UIViewController {
viewController
}

func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}

public var preview: some View {
return Preview(viewController: self)
}
}
#endif

I explained how to configure the new Object Card View that is available since SAP BTP SDK for iOS version 8.0
import Foundation
import SAPFiori

#if canImport(SwiftUI) && DEBUG
import SwiftUI

class ObjectCardDemoViewController: FUIFormTableViewController {

override func viewDidLoad() {
super.viewDidLoad()

self.tableView.register(FUIObjectCardTableViewCell.self, forCellReuseIdentifier: FUIObjectCardTableViewCell.reuseIdentifier)
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: FUIObjectCardTableViewCell.reuseIdentifier, for: indexPath as IndexPath) as! FUIObjectCardTableViewCell

cell.detailImageView.image = UIImage(named: "swiftui")
cell.title.text = "SwiftUI Demo"
cell.subtitle.text = "Devtoberfest"
cell.footnote.text = "Pretty cool"
cell.status.text = "Live Session in Progress"
cell.status.textColor = UIColor.preferredFioriColor(forStyle: .positiveLabel)
cell.primaryAction.isHidden = false
cell.primaryAction.setTitle("Learn More", for: .default)
cell.secondaryAction.isHidden = false
cell.secondaryAction.setTitle("Cancel", for: .default)
cell.overflowAction.isHidden = false

return cell

}

}

struct ObjectCardDemoViewController_Previews: PreviewProvider {
static var previews: some View {
UINavigationController(rootViewController: ObjectCardDemoViewController()).preview
}
}
#endif

Then I showed a more complex example of using FUIWhatsNewViewController as an OnboardingStep.
import Foundation
import SAPFiori
import SAPFioriFlows

class WhatsNewOnboardingStep: OnboardingStep {
let whatsNewDataSource = WhatsNewDemoDataSource()
let whatsNewDelegate = WhatsNewDemoDelegate()

func onboard(context: SAPFioriFlows.OnboardingContext, completionHandler: @escaping (SAPFioriFlows.OnboardingResult) -> Void) {

whatsNewDelegate.onboardingCompletionHandler = completionHandler
whatsNewDelegate.onboardingContext = context

let whatsNewController = FUIWhatsNewViewController()
whatsNewController.dataSource = whatsNewDataSource
whatsNewController.delegate = whatsNewDelegate

let navController = UINavigationController(rootViewController: whatsNewController)
context.presentationDelegate.present(navController) { optionalError in
()
}

}

func restore(context: SAPFioriFlows.OnboardingContext, completionHandler: @escaping (SAPFioriFlows.OnboardingResult) -> Void) {
()
}

func reset(context: SAPFioriFlows.OnboardingContext, completionHandler: @escaping () -> Void) {
()
}
}

class WhatsNewDemoDelegate: FUIWhatsNewViewControllerDelegate {

var onboardingContext: SAPFioriFlows.OnboardingContext! = nil
var onboardingCompletionHandler: ((SAPFioriFlows.OnboardingResult) -> Void)?

func whatsNewViewController(_ whatsNewViewController: SAPFiori.FUIWhatsNewViewController, willTransitionTo pendingViewControllerIndex: Int) {}

func whatsNewViewController(_ whatsNewViewController: SAPFiori.FUIWhatsNewViewController, didFinishAnimating finished: Bool, previousViewControllerIndex: Int, transitionCompleted completed: Bool) {}

func didFinishFlow(_ whatsNewViewController: SAPFiori.FUIWhatsNewViewController) {

onboardingContext.presentationDelegate.dismiss { [weak self] optionalError in
self?.onboardingCompletionHandler?(.success(self!.onboardingContext))
}
}
}

class WhatsNewDemoDataSource: FUIWhatsNewViewControllerDataSource {

var pages: [FUIWhatsNewDetailPageController] = []

init() {
let page1 = FUIWhatsNewDetailPageController()
page1.imageView.image = UIImage(systemName: "icloud.slash")
page1.titleLabel.text = "Offline Access"
page1.descriptionTextView.text = "All business data is available in offline. Data can be edited and be synced with backend once network connectivity is available for the device."
pages.append(page1)

let page2 = FUIWhatsNewDetailPageController()
page2.imageView.image = UIImage(systemName: "faceid")
page2.titleLabel.text = "Biometric Authentication"
page2.descriptionTextView.text = "Use Apple's FaceID for easy onboarding"
pages.append(page2)
}

func presentationViewControllers(for whatsNewViewController: FUIWhatsNewViewController) -> [UIViewController] {
return pages
}

func presentationIndex(for whatsNewViewController: FUIWhatsNewViewController) -> Int {
return 0
}
}

#if canImport(SwiftUI) && DEBUG
import SwiftUI

struct FUIWhatsNewViewControllerPreview: PreviewProvider {

static let whatsNewDataSource = WhatsNewDemoDataSource()
static let whatsNewDelegate = WhatsNewDemoDelegate()

static var controller: SAPFiori.FUIWhatsNewViewController {
let whatsNewController = FUIWhatsNewViewController()
whatsNewController.dataSource = whatsNewDataSource
whatsNewController.delegate = whatsNewDelegate
return whatsNewController
}

static var previews: some View {
UINavigationController(rootViewController: controller).preview
}
}

#endif

I hope you find the examples helpful.