# iOS SDK

Installation

Appstent SDK on iOS is currently released for the SwiftUI based presentation layer, under the name AppstentUI. &#x20;

AppstentUI is distributed using Swift Package Manager under the path:

{% embed url="<https://github.com/Appversation/AppstentUIPackage>" %}

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:

```swift
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:

```swift
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:

```swift
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:

```swift
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:

```swift
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:

```swift
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:

```swift
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.

```swift
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`.

```swift
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.

```swift
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:

```swift
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:

```swift
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.

```swift
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
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://appversation.gitbook.io/appstent/integrations/ios-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
