> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bit2connect.com/llms.txt
> Use this file to discover all available pages before exploring further.

# iOS SDK

> Integrate Bit2Connect dynamic links into your iOS applications

## Installation

### CocoaPods (Recommended)

Add the Bit2Connect iOS SDK to your `Podfile`:

```ruby theme={null}
platform :ios, '13.0'

target 'YourApp' do
  use_frameworks!
  pod 'Bit2ConnectSDK', '~> 1.0.0'
end
```

Then run:

```bash theme={null}
pod install
```

After installation, open the generated `.xcworkspace` file instead of the `.xcodeproj` file.

### Swift Package Manager

#### Option 1: Using Xcode (Recommended)

1. In Xcode, go to **File** → **Add Package Dependencies**
2. Enter the repository URL: `https://github.com/bit2connect/bit2connect-ios-sdk.git`
3. Select **Up to Next Major Version** with **1.0.0**
4. Click **Add Package**
5. Select your target and click **Add Package**

#### Option 2: Using Package.swift

Add the following to your `Package.swift` file:

```swift theme={null}
dependencies: [
    .package(url: "https://github.com/bit2connect/bit2connect-ios-sdk.git", from: "1.0.0")
],
targets: [
    .target(
        name: "YourTarget",
        dependencies: [.product(name: "Bit2ConnectSDK", package: "bit2connect-ios-sdk")]
    )
]
```

#### Option 3: Command Line

```bash theme={null}
swift package init
# Add dependency to Package.swift as shown above
swift package resolve
swift build
```

## Requirements

* iOS 13.0+
* Xcode 12.0+
* Swift 5.0+

## Setup

### 1. Initialize the SDK

Initialize the SDK in your AppDelegate:

```swift theme={null}
import Bit2ConnectSDK

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        // Initialize Bit2Connect SDK
        Bit2ConnectSDK.shared.initialize(
            baseURL: "https://api.bit2connect.com",
            apiKey: "your-api-key-here",
            debugMode: true
        )

        return true
    }
}
```

### 2. Configure Deep Link Handling

Add deep link handling to your AppDelegate:

```swift theme={null}
import Bit2ConnectSDK

class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        // Initialize Bit2Connect SDK
        Bit2ConnectSDK.shared.initialize(
            baseURL: "https://api.bit2connect.com",
            apiKey: "your-api-key-here",
            debugMode: true
        )

        // Handle deferred deep link on app launch
        Bit2ConnectSDK.shared.handleDeferredDeepLink { result in
            switch result {
            case .success(let linkData):
                print("Deferred deep link found: \(linkData.originalUrl)")
                self.handleLinkData(linkData)
            case .noLink:
                print("No deferred deep link found")
            case .error(let message):
                print("Error getting deferred deep link: \(message)")
            }
        }

        return true
    }

    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        // Handle direct deep link
        Bit2ConnectSDK.shared.handleDirectDeepLink(url: url) { result in
            switch result {
            case .success(let linkData):
                print("Direct deep link handled: \(linkData.originalUrl)")
                self.handleLinkData(linkData)
            case .error(let message):
                print("Error handling direct deep link: \(message)")
            }
        }

        return true
    }

    private func handleLinkData(_ linkData: LinkData) {
        // Process the link data
        print("Processing link data:")
        print("- Original URL: \(linkData.originalUrl)")
        print("- Path: \(linkData.path)")
        print("- Campaign: \(linkData.campaign ?? "None")")
        print("- Source: \(linkData.source ?? "None")")
        print("- Medium: \(linkData.medium ?? "None")")
        print("- Parameters: \(linkData.parameters)")

        // Navigate to appropriate screen based on link data
        if let campaign = linkData.campaign {
            navigateToContent(campaign: campaign, parameters: linkData.parameters)
        }
    }

    private func navigateToContent(campaign: String, parameters: [String: String]) {
        // Implement your navigation logic here
        // Example: Navigate to a specific product page
        if let productId = parameters["product_id"] {
            NotificationCenter.default.post(
                name: NSNotification.Name("NavigateToProduct"),
                object: nil,
                userInfo: ["productId": productId]
            )
        }
    }
}
```

### 3. Configure URL Schemes

Add the following to your `Info.plist`:

```xml theme={null}
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>com.yourapp.bit2connect</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>yourapp</string>
        </array>
    </dict>
    <dict>
        <key>CFBundleURLName</key>
        <string>com.yourapp.https</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>https</string>
        </array>
    </dict>
</array>
```

### 4. Handle Navigation in View Controllers

Set up navigation handling in your view controllers:

```swift theme={null}
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Listen for navigation notifications
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleNavigation(_:)),
            name: NSNotification.Name("NavigateToProduct"),
            object: nil
        )
    }

    @objc private func handleNavigation(_ notification: Notification) {
        if let userInfo = notification.userInfo,
           let productId = userInfo["productId"] as? String {

            // Navigate to product page
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            if let productVC = storyboard.instantiateViewController(withIdentifier: "ProductViewController") as? ProductViewController {
                productVC.productId = productId
                navigationController?.pushViewController(productVC, animated: true)
            }
        }
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}
```

## API Reference

### Bit2ConnectSDK

The main SDK class for handling dynamic links and deferred deep linking.

#### Methods

##### `initialize(baseURL: String, apiKey: String, debugMode: Bool)`

Initialize the Bit2Connect SDK with your API credentials.

**Parameters:**

* `baseURL` (String): The Bit2Connect API base URL
* `apiKey` (String): Your Bit2Connect API key
* `debugMode` (Bool): Enable debug logging

**Example:**

```swift theme={null}
Bit2ConnectSDK.shared.initialize(
    baseURL: "https://api.bit2connect.com",
    apiKey: "your-api-key-here",
    debugMode: true
)
```

##### `handleDeferredDeepLink(completion: @escaping (DeferredLinkResult) -> Void)`

Handle deferred deep links when the app is launched.

**Parameters:**

* `completion` (Closure): Completion handler with result

**Example:**

```swift theme={null}
Bit2ConnectSDK.shared.handleDeferredDeepLink { result in
    switch result {
    case .success(let linkData):
        // Process deferred deep link
    case .noLink:
        // No deferred link found
    case .error(let message):
        // Handle error
    }
}
```

##### `handleDirectDeepLink(url: URL, completion: @escaping (DirectLinkResult) -> Void)`

Handle direct deep links when the app is already installed.

**Parameters:**

* `url` (URL): The deep link URL to process
* `completion` (Closure): Completion handler with result

**Example:**

```swift theme={null}
Bit2ConnectSDK.shared.handleDirectDeepLink(url: url) { result in
    switch result {
    case .success(let linkData):
        // Process direct deep link
    case .error(let message):
        // Handle error
    }
}
```

##### `createDynamicLink(data: DynamicLinkData, completion: @escaping (DynamicLinkResult) -> Void)`

Create a new dynamic link with custom parameters.

**Parameters:**

* `data` (DynamicLinkData): The link data to create
* `completion` (Closure): Completion handler with result

**Example:**

```swift theme={null}
let linkData = DynamicLinkData(
    deepLink: "https://yourapp.com/product/123",
    campaign: "summer_sale",
    source: "email",
    medium: "newsletter"
)

Bit2ConnectSDK.shared.createDynamicLink(data: linkData) { result in
    switch result {
    case .success(let response):
        print("Link created: \(response.shortLink)")
    case .error(let message):
        print("Error: \(message)")
    }
}
```

### LinkData

Represents the data from a processed link.

#### Properties

* `originalUrl` (String): The original URL that was processed
* `path` (String): The path component of the URL
* `campaign` (String?): The campaign parameter
* `source` (String?): The source parameter
* `medium` (String?): The medium parameter
* `content` (String?): The content parameter
* `term` (String?): The term parameter
* `parameters` (\[String: String]): Additional custom parameters

## Advanced Configuration

### Custom Link Handling

You can customize how links are processed by implementing a custom link handler:

```swift theme={null}
class CustomLinkHandler: LinkHandler {
    func handleLink(_ linkData: DynamicLinkData) -> Bool {
        // Custom link processing logic
        if let type = linkData.payload?["type"] as? String {
            switch type {
            case "product":
                // Handle product links
                return true
            case "category":
                // Handle category links
                return true
            default:
                // Let the SDK handle default processing
                return false
            }
        }
        return false
    }
}

// Register the custom handler
Bit2ConnectSDK.setLinkHandler(CustomLinkHandler())
```

### Analytics Integration

Track link performance and user engagement:

```swift theme={null}
class AnalyticsLinkHandler: LinkHandler {
    func handleLink(_ linkData: DynamicLinkData) -> Bool {
        // Track link click
        Analytics.track("dynamic_link_clicked", parameters: [
            "link_id": linkData.id,
            "original_url": linkData.originalUrl
        ])

        return false // Let default handler process the link
    }
}
```

## Testing

### Test Dynamic Links

You can test your integration using the Bit2Connect dashboard or API:

```swift theme={null}
// Test with a sample dynamic link
let testLink = URL(string: "https://b2co.link/abc12345")!
Bit2ConnectSDK.validateLink(testLink) { isValid, linkData in
    if isValid {
        print("Link is valid: \(linkData?.shortUrl ?? "")")
    } else {
        print("Link is invalid")
    }
}
```

### Debug Mode

Enable debug logging to troubleshoot issues:

```swift theme={null}
Bit2ConnectSDK.shared.initialize(
    baseURL: "https://api.bit2connect.com",
    apiKey: "your-api-key-here",
    debugMode: true // Enable debug logging
)
```

## Best Practices

<CardGroup cols={2}>
  <Card title="Error Handling" icon="exclamation-triangle">
    Always handle potential errors when processing dynamic links
  </Card>

  <Card title="User Experience" icon="user">
    Provide fallback navigation for invalid or expired links
  </Card>

  <Card title="Security" icon="shield">
    Validate link data before processing to ensure security
  </Card>

  <Card title="Performance" icon="bolt">
    Cache link data when appropriate to improve app performance
  </Card>
</CardGroup>

## Choosing Between CocoaPods and Swift Package Manager

### When to Use CocoaPods

* **Legacy Projects**: If your project already uses CocoaPods
* **Team Preference**: If your team is more familiar with CocoaPods
* **Complex Dependencies**: When you need fine-grained control over dependency versions
* **CI/CD Integration**: If your build pipeline is already configured for CocoaPods

### When to Use Swift Package Manager

* **New Projects**: For new iOS projects starting fresh
* **Apple Ecosystem**: When you want to use Apple's native package manager
* **Xcode Integration**: For seamless integration with Xcode's built-in package management
* **Cross-Platform**: When building for multiple Apple platforms (iOS, macOS, watchOS, tvOS)
* **Modern Development**: For projects using the latest Swift and Xcode features

### Migration Guide

If you're migrating from CocoaPods to Swift Package Manager:

1. **Remove CocoaPods**:

   ```bash theme={null}
   # Remove Podfile and Podfile.lock
   rm Podfile Podfile.lock
   # Remove Pods directory
   rm -rf Pods
   # Remove .xcworkspace file
   rm YourApp.xcworkspace
   ```

2. **Add Swift Package Manager**:

   * In Xcode: File → Add Package Dependencies
   * Enter: `https://github.com/bit2connect/bit2connect-ios-sdk.git`
   * Select version and add to target

3. **Update Import Statements**:

   ```swift theme={null}
   // No changes needed - import remains the same
   import Bit2ConnectSDK
   ```

4. **Test Your Integration**:
   * Build and run your project
   * Test deep link functionality
   * Verify all features work as expected

## Troubleshooting

### Common Issues

<AccordionGroup>
  <Accordion title="Links not being received">
    **Solution:** Ensure your app is properly configured for deep linking and
    the SDK is initialized before handling links.
  </Accordion>

  <Accordion title="iOS links not working">
    **Solution:** Verify that your iOS app's URL scheme is correctly configured in
    Info.plist and that the app is properly signed.
  </Accordion>

  {" "}

  <Accordion title="App not opening from links">
    **Solution:** Check that your app is properly configured as a URL scheme
    handler and that the links are correctly formatted.
  </Accordion>

  {" "}

  <Accordion title="Swift Package Manager import errors">
    **Solution:** Ensure you're using the correct import syntax and that the
    package is properly added to your target. For Package.swift, use: `swift
          dependencies: [.product(name: "Bit2ConnectSDK", package:
          "bit2connect-ios-sdk")] `
  </Accordion>

  <Accordion title="Build errors with SPM">
    **Solution:** Make sure your project's iOS deployment target is 13.0 or higher,
    and that you're using Swift 5.0+. Try cleaning your build folder and rebuilding.
  </Accordion>
</AccordionGroup>

### Debug Tips

1. Enable debug mode to see detailed logging
2. Test with the Bit2Connect dashboard link tester
3. Verify your app's deep link configuration
4. Check that your API key has the correct permissions
5. Use Safari to test deep links by typing the URL directly
6. For SPM issues: Check Package.swift syntax and target dependencies
7. For build errors: Ensure iOS 13.0+ deployment target and Swift 5.0+

## Creating Dynamic Links

You can create dynamic links programmatically using the SDK:

```swift theme={null}
import Bit2ConnectSDK

class LinkCreationViewController: UIViewController {

    @IBAction func createDynamicLinkTapped(_ sender: UIButton) {
        let linkData = DynamicLinkData(
            deepLink: "https://yourapp.com/product/123",
            campaign: "summer_sale",
            source: "email",
            medium: "newsletter",
            content: "banner_ad",
            term: "discount",
            customParameters: [
                "user_id": "12345",
                "feature": "premium"
            ],
            socialTitle: "Check out this amazing product!",
            socialDescription: "Get 50% off on all items",
            socialImageUrl: "https://yourapp.com/images/product.jpg",
            androidPackageName: "com.yourapp.app",
            iosBundleId: "com.yourapp.app",
            fallbackUrl: "https://yourapp.com/download"
        )

        Bit2ConnectSDK.shared.createDynamicLink(data: linkData) { result in
            DispatchQueue.main.async {
                switch result {
                case .success(let response):
                    print("Dynamic Link Created:")
                    print("Short Link: \(response.shortLink)")
                    print("Preview: \(response.previewLink)")
                    print("QR Code: \(response.qrCodeUrl)")

                    // Share the link or use it as needed
                    self.shareLink(response.shortLink)

                case .error(let message):
                    print("Error creating dynamic link: \(message)")
                    self.showAlert(title: "Error", message: message)
                }
            }
        }
    }

    private func shareLink(_ link: String) {
        let activityViewController = UIActivityViewController(
            activityItems: [link],
            applicationActivities: nil
        )
        present(activityViewController, animated: true)
    }

    private func showAlert(title: String, message: String) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
    }
}
```

## Examples

### E-commerce App

```swift theme={null}
private func handleLinkData(_ linkData: LinkData) {
    // Process the link data based on campaign and parameters
    if let campaign = linkData.campaign {
        switch campaign {
        case "product":
            if let productId = linkData.parameters["product_id"] {
                navigateToProduct(productId)
            }
        case "category":
            if let categoryId = linkData.parameters["category_id"] {
                navigateToCategory(categoryId)
            }
        case "promotion":
            if let promoCode = linkData.parameters["promo_code"] {
                navigateToPromotion(promoCode)
            }
        default:
            break
        }
    }
}

private func navigateToProduct(_ productId: String) {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    if let productVC = storyboard.instantiateViewController(withIdentifier: "ProductViewController") as? ProductViewController {
        productVC.productId = productId
        navigationController?.pushViewController(productVC, animated: true)
    }
}
```

### Social Media App

```swift theme={null}
private func handleLinkData(_ linkData: LinkData) {
    // Process the link data based on campaign and parameters
    if let campaign = linkData.campaign {
        switch campaign {
        case "post":
            if let postId = linkData.parameters["post_id"] {
                navigateToPost(postId)
            }
        case "profile":
            if let userId = linkData.parameters["user_id"] {
                navigateToProfile(userId)
            }
        default:
            break
        }
    }
}

private func navigateToPost(_ postId: String) {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    if let postVC = storyboard.instantiateViewController(withIdentifier: "PostViewController") as? PostViewController {
        postVC.postId = postId
        navigationController?.pushViewController(postVC, animated: true)
    }
}
```
