iOS SDK
Integration Help for iOS Platform
Installation
Appstent SDK on iOS is currently released for the SwiftUI based presentation layer, under the name AppstentUI.
AppstentUI is distributed using Swift Package Manager under the path:
Please check Apple's documentation for instructions on adding SPM dependencies from: https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app
Once the SDK package is added to the project AppstentUI SDK can by using the import statement as follows:
import AppstentUI
Usage Guide
Connecting the SDK with an account
Each Account is access controlled through an API key. When initializing the SDK, the API key can be set by using a static property apiKey
of the class ViewContent, as below:
ViewContent.apiKey = "<API Key>"
Load the View Document Content
Loading the View Content requires the complete path to the content document, to create a ViewContent object, like below:
let viewContent = ViewContent(from: "<content doc path>")
The ViewContent object is loaded from the content path by making a network request and therefore it is recommended to make this call in a background thread.
Load the Content View
Once the view content object is loaded, the Appstent Content View which is of the View type, can be loaded using the view content object in the initializer as follows:
let contentView = AppstentView(from: viewContent)
The contentView is now ready to be used as a SwiftUI View!!
Complete Sample Code to Initialize and Load a Content View
Here is a sample code to initialize and load content view:
import SwiftUI
import AppstentUI
@main
struct LandmarksApp: App {
@StateObject private var modelData = ModelData()
var body: some Scene {
WindowGroup {
LandmarksApp.contentViewFrom(source: "LandmarksApp/TabBars", rendering: LandmarksAppContentViewProvider())
.environmentObject(modelData)
}
}
@MainActor public static func contentViewFrom(source: String,
using customDataProvider: AppstentUI.CustomContentDataProvider? = nil,
rendering customViewProvider:AppstentUI.CustomContentViewProvider? = nil) -> some View {
let viewContent = ViewContent(from: source)
ViewContent.apiKey = "<API Key>"
var mainView = AppstentUI.AppstentView.init(from: viewContent)
AppstentUI.AppstentView.customViewProvider = customViewProvider
mainView.customDataProvider = customDataProvider
return AnyView(mainView)
}
}
In the sample code above a content document named LandmarksApp/TabBars
is getting loaded as the main view of the App.
Advanced Usage
Custom Views
While Appstent can be used to build content based views, if you want to also manage the placement of the existing/custom application views with in a content view, you can provide a view provider to Appstent SDK by implementing the protocol CustomContentViewProvider
and implement the following method:
func customView(from viewName: String) -> AnyView
AppstentUI SDK will call this method to get a view from your App, with the custom view's name it finds in the content JSON.
To make sure that AppstentUI SDK calls the customView method though, you need to provide the object of the class/struct implementing the CustomContentViewProvider
protocol to a static member of Appstent struct like this:
AppstentUI.AppstentView.customViewProvider = LandmarksAppContentViewProvider()
Here is a sample implementation of the customView
method from Apple's Landmarks Sample App that is converted to show Appstent SDK integration techniques.
func customView(from viewName: String) -> AnyView {
guard !viewName.isEmpty else {
return AnyView(EmptyView())
}
switch viewName {
case "category_home": return AnyView(CategoryHome())
case "landmark_list": return AnyView(LandmarkList())
default: return AnyView(EmptyView())
}
return AnyView(EmptyView())
}
Visibility Control
Appstent views' visibility can be controlled with the visibility rules. Some of these pre-defined rules can written as part of view content JSON, however, App developers can also provide their custom visibility rule by implementing the following method of CustomContentViewProvider
.
func visibility(from ruleName: String, ruleValue: String) -> Bool
AppstentUI SDK will call this method for each of the visibility rules defined for a view content. Here is a sample implementation of using custom visibility rules to control view's visibility.
func visibility(from ruleName: String, ruleValue: String) -> Bool {
switch ruleName {
case "userState":
return ruleValue == "loggedIn" && userIsLoggedIn()
default: return true
}
}
In the above example, a custom visibility rule of userState
is being used to show content view only when the user authenticated state is detected to be Logged In.
Custom Data
When you want to control the layout of the views with Appstent CMS but need to render your App's data with in those content views, you can provide your data provider to Appstent SDK to plug your data fields as part of content views, by implementing the protocol CustomContentDataProvider
and implement the following method:
func string(for fieldName: String) -> String
AppstentUI SDK will call this method to get the data value from your App, with the custom view's field name it finds in the content JSON.
To make sure that AppstentUI SDK calls the customView method though, you need to provide the object of the class/struct implementing the CustomContentViewProvider
protocol to a static member of Appstent struct like this:
contentView.customDataProvider = LandmarkDataProvider(landmark: landmark)
In the sample code line above, LandmarkDataProvider
is a struct from a sample App that implements CustomContentDataProvider
protocol.
Also note that unlike CustomContentViewProvider
, CustomContentDataProvider
is not a static property and can be set to each AppstentView object separately, based on the type of the data that particular view needs.
Here is a sample implementation of the string(for:)
method from Apple's Landmarks Sample App that is converted to show Appstent SDK integration techniques.
struct LandmarkDataProvider: AppstentUI.CustomContentDataProvider {
var landmark: Landmark
func string(for fieldName: String) -> String {
var fieldVal = ""
switch fieldName {
case "landmarkName": fieldVal = landmark.name
case "landmarkPark": fieldVal = landmark.park
case "landmarkState": fieldVal = landmark.state
case "landmarkDescription": fieldVal = landmark.description
case "landmarkImageName": fieldVal = landmark.imageName
case "landmarkFeaturedImageName": fieldVal = landmark.featuredImageName
default:
break
}
return fieldVal
}
}
Last updated