# Link SDK for iOS In this guide we will walk you through the steps to integrate the Link SDK for iOS into your app. ## Set up your Xcode project Open up Xcode and create a new iOS project for iOS 16+. ### Import the LinkKit framework There are three alternative approaches to importing the LinkKit framework: #### A. Using Swift Package Manager SwiftPM requirements: Using our Swift package requires Xcode 15+. In Project navigator on the left, select your project and then select the corresponding entry under "PROJECT" in the area to the right. Open "Package Dependencies" tab and click `+` at the bottom left of the "Packages" section: ![Packages section](https://developers.enode.com/images/link-sdks/enode-link_sdk-ios-0-1.png) In the modal, paste `https://github.com/enode/enode-link-ios` in the search field at the top right and then select `enode-link-ios` entry in the table of the middle of the screen. Click `Add Package` at the bottom right: ![Importing the LinkKit framework](https://developers.enode.com/images/link-sdks/enode-link_sdk-ios-0-2.png) Click `Add Package` again at the bottom right of the new modal: ![Confirming the action](https://developers.enode.com/images/link-sdks/enode-link_sdk-ios-0-3.png) `enode-link-ios` should now be among items in the "Packages" section: ![Completed](https://developers.enode.com/images/link-sdks/enode-link_sdk-ios-0-4.png) #### B. Using a local SDK bundle First, [download the LinkKit framework](https://enode.notion.site/Latest-LinkKit-xcframework-3b331d8779344d25b80b028d04416ad8). Extract the zip archive and keep the folder `LinkKit.xcframework` somewhere convenient. Under your build target, open the **General** tab, import the framework by dragging the `LinkKit.xcframework` folder into the **Framework, Libraries and Embedded Content** section: ![Adding the LinkKit framework to Xcode](https://developers.enode.com/images/link-sdks/enode-link_sdk-ios-1.png) #### C. Using CocoaPods Useful for Flutter projects or apps already using CocoaPods. 1. Add to your `Podfile`, replacing `VERSION` with the desired version (e.g. `1.0.9`): ```ruby pod 'EnodeLinkKit', :git => 'https://github.com/enode/enode-link-ios.git', :tag => 'VERSION' ``` 2. Run `pod install` 3. Open the `.xcworkspace` file (not `.xcodeproj`) in Xcode 4. Import the module: ```swift import LinkKit ``` Module name: The pod name is `EnodeLinkKit` but the module is imported as `LinkKit`. ### Configuring Bluetooth access Bluetooth access: When integrating the Link SDK for device linking, Bluetooth access is required for seamless communication with certain energy assets. To enable this functionality, you’ll need to add an `NSBluetoothAlwaysUsageDescription` entry to your application's Info.plist file with a clear and informative description. This description is crucial as it informs the user why your app needs Bluetooth access. Without this string, iOS will deny Bluetooth access and may cause your application to crash. Start by heading to the **Info** tab and add a **Custom iOS Target Property** by clicking on the `+` icon in the list of key value pairs. Use the following values. | Key | Value | | --- | --- | | **Key** | `NSBluetoothAlwaysUsageDescription` | | **Type** | String | | **Value** | “Our app requires Bluetooth to connect with energy devices, enabling efficient device management and enhanced user experience.” | ![Bluetooth settings in Xcode](https://developers.enode.com/images/link-sdks/enode-link_sdk-ios-2.png) Use the iOS target properties to inform the user about the required bluetooth access. ## Integrating the SDK Existing integrations: If your app already opens Link UI (e.g., in an in-app browser), follow these steps at the same place in your code. You should replace your old Link UI mechanism with a call to our SDK. In your application section where you want to open LinkKit, import the SDK: ```swift import LinkKit ``` Ensure you have `linkToken` from the previous step and pass it into the handler: ```swift private var handler: Handler? self.handler = Handler(linkToken: linkToken) { linkResult in switch linkResult { case .success: // Handle success case .failure(let error): // Handle error } } self.handler?.present(from: self) // self is a UIViewController ``` Here’s how an alternative approach for SwiftUI (using `linkKitSheet`) can be used, but the code above would also work. ```swift import SwiftUI import LinkKit struct ContentView: View { // ... @State private var isPresented = false var body: some View { Button(action: { self.isPresented = true }) { Text("Open LinkKit") } .linkKitSheet(isPresented: $isPresented, linkToken: linkToken) { linkResult in switch linkResult { case .success: // Handle success case .failure(let error): // Handle error } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } ``` Once run, Link UI will open in your application and guide your user through the process of linking. When successful, the "Complete" button will dismiss the modal and return users to the previous screen. If a user did not complete Link UI or dismisses the window, you will receive a `LinkResult` with a `failure` and one of the errors below. ## Full screen support If you prefer a full screen modal for the Link UI, you can provide an optional `presentationStyle` argument to the `Handler` class: ```swift self.handler = Handler(linkToken: linkToken, presentationStyle: .fullScreen) {...} ``` Or use `linkKitFullscreen` instead of `linkKitSheet` ![Modal presentation style](https://developers.enode.com/images/link-sdks/enode-link_sdk-ios-style.png) ## Theming the SDK You can customize the color which is used for all interactive elements in the top bar (cancel and refresh buttons) and bottom bar (the back and forwards buttons) that wraps Link UI. To do so, you can set the tintColor property of the containing window that presents the Link SDK. Below is an example of how to set the `tintColor` to green in the `AppDelegate.swift` or `SceneDelegate.swift` file. ```swift ... self.window?.tintColor = .systemGreen ``` ## API Reference ### `LinkResult` & `LinkError` For details on errors the SDK provides, see details below. ```swift public enum LinkResult { case success case failure(LinkError) } public typealias HumanReadableMessage = String public enum LinkError : Error { // Unknown error occurred case unknown // Required linkToken parameter was not found case missingLinkToken // Supplied linkToken was malformed case malformedLinkToken(LinkKit.MalformedLinkTokenError) // Link UI was dismissed by you (e.g., by calling `dismiss()`) case dismissedViaDismissFunction // Link UI was dismissed by the user (e.g., tapping "Close") case cancelledByUser // Enode was unable to complete linking due to a service error case backendError(LinkKit.HumanReadableMessage) // Link UI itself initiated the closing of the modal case earlyExitRequestedFromFrontend(LinkKit.HumanReadableMessage?) } public enum MalformedLinkTokenError : Error { case couldNotCreateDataFromTheToken case couldNotParseJsonFromTheToken case jsonDeserializationError(LinkKit.HumanReadableMessage) case couldNotParseLinkUrlAndRedirectUriFromTheToken case couldNotCreateURLFromLinkUrl case couldNotFindHostFromLinkURL case hostOfLinkURLIsNotEnodecomOrEnodeio } ``` ## Other ways to integrate [Link SDK for Android](https://developers.enode.com/docs/link-sdks/android) [React Native](https://developers.enode.com/docs/link-sdks/react-native)