> For the complete documentation index, see [llms.txt](https://fendai.gitbook.io/fendvpn-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://fendai.gitbook.io/fendvpn-docs/apple-ios-sdk.md).

# Apple iOS SDK

## 1. Preparing

Before integrating Apple provisioning profiles for Application and Network Extension target should be created.

To do this visit Apple developer portal->Certificates, Identifiers & Profiles->Identifiers and add new identifier for your application target and enable next capabilities:

* App Groups
* Keychain sharing
* Network Extensions
* Personal VPN

Create another identifier for Network Extension target using the same capabilities as for Application.

## 2. Integration

### 2.1. Linking

* **Application**

To integrate SDK to application target, copy **FendSDK.framework** to desired location in your project folder, then add it to **Frameworks, Libraries, and Embedded content** application project section and make sure that Embed option is set to **Embed & Sign**

* *Network Extension*

For extension, target perform the same steps as for **Application** target with **FendTunnelProvider.framework**

### 2.2. Configuring capabilities

For both targets *Signing capabilities* should be configured:

### 2.3. App Groups

Create group name started with *group.* and use the same name for Application and Network extension target (ex. *group.fend.testapp*)

### 2.4. Keychain sharing

Create keychain group name and use the same and for Application and Network extension target.

### 2.5. Network extension

Select **Packet Tunnel** option for both targets.

### 2.6. Personal VPN

Make sure that Personal VPN capability is added.

### 2.7. Setup Network Extension target

Change `NSExtensionPrincipalClass` value to **FDTunnelProvider** in `NSExtension` dictionary of Network Extension target `Info.plist`

## 3. Start using FendSDK

### 3.1. Configure FendSDK

To start using the SDK, you need to import `import FendSDK` to your class under the application target.

Initialize FendSDK with `Configuration`:

```
import FendSDK    

    let configuration = Configuration(project: ##Project Name##,
                                          url: ##URL##,
                                      groupID: ##Group ID that you used in Integration step##,
                             providerBundleID: ##Bundle identifier for Network Extension target##,
                            isOnDemandEnabled: true)

    let sdk = FendSDK(configuration: configuration)
```

After SDK is initialized, you need to login to be able to start VPN. Login example with anonymous authorization:

```
import FendSDK
// ...

let sdk: FendSDK
// ...

       sdk.signIn(method: .anonymous()) { user, error in
            print("user = \(user)")
        }
```

### 3.2. Connecting VPN and obtaining status

To establish a VPN connection you need to select location to which you want to connect or pass `nil` and VPN location will be automatically selected.

```
import FendSDK
// ...

let sdk: FendSDK
// ...

        sdk.locations { locations, error in
            if let errror = error {
                print("Error has occured during loading locations: \(error)")
            } else {
                self.location = locations?.first
            }
        }
```

After choosing location use function `connect(to location:completion:)` to start VPN.

```
import FendSDK
// ...

let sdk: FendSDK
// ...

        sdk.connect(to: selectedLocation) { [unowned self] _, error in
            print(error ?? sdk.lastError)
        }
```

When VPN is started or an error occurred, completion handler will be called.

To get notifications about actual VPN state, subscribe to `NEVPNStatusDidChange` and get actual state from `FendSDK.state` variable.

```
import FendSDK
// ...

let sdk: FendSDK
private var stateCancellable: AnyCancellable?
// ...
        stateCancellable = NotificationCenter.default.publisher(for: .NEVPNStatusDidChange)
            .map { _ in () }
            .sink { [unowned self] in
                print("state = \(sdk.state)")
            }
```

### 3.3. Using On Demand mode

SDK provides functionality to restore VPN connection after:

* Changing Wi-Fi/Celluar network
* Wake up after sleep or reboot

Set parameter `isOnDemandEnabled` of `Configuration` to `true` to enable On Demand mode.

### 3.4. Tunnel provider delegate

To get vpn state callbacks in tunnel provider you need to create class with any name that conforms to `FendTunnelProviderDelegate` protocol and inherits from `NSObject`:

```
import FendSDK    
// ...

@objc
class ProviderDelegate: NSObject, FendTunnelProviderDelegate {
    func vpnWillStart() {
        print("vpnWillStart")
    }

    func vpnDidStart() {
        print("vpnDidStart")
    }

    func vpnWillStop() {
        print("vpnWillStop")
    }

    func didReceive(error: Error) {
        print("didReceive: \(error)")
    }
}
///
```

### 3.5. Error Handling

Most of the `FendSDK` calls are accepting completion blocks with errors. If an error occurs, you will receive non-nil `Error` object with an explanation.
