Skip to content
121 changes: 105 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@

This project helps developers understand how to:

- Set up and use `ShortIOSDK`
- Generate short URLs with customizable parameters
- Integrate and handle Universal Links in SwiftUI and UIKit
- Handle deep links via Universal Links
- Track conversions
- Use secure (encrypted) short links

## 📦 Requirements

- iOS 13.0+
- Xcode 13.0+
- Swift 5+
- A valid [Short.io](https://short.io/) account
- A valid `enterprises` [Short.io](https://short.io/) account

## 🚀 Getting Started

Expand All @@ -35,24 +36,37 @@ Open `ShortIOApp.xcodeproj` or `ShortIOApp.xcworkspace` in Xcode, depending on t

## 🛠 Setup Instructions

### 🔑 1. Add Your API Key
### Initialize the SDK

Open the appropriate file:
Before using any functionality, you must initialize the SDK using your API key and domain in `AppDelegate` as part of application(launchOptions) for a UIKit app, or the @main initialization logic for a SwiftUI app.

- **SwiftUI:** `ContentView.swift`
- **UIKit:** `ViewController.swift`
Replace the placeholder with your **Short.io Public API Key:**

```bash
let apiKey = "your_api_key"

```swift
...
import ShortIOSDK
...

class AppDelegate: UIResponder, UIApplicationDelegate {
...
func application(...) {
...
let sdk = ShortIOSDK.shared

sdk.initialize(apiKey: "your_apiKey_here", domain: "your_domain_here")
...
}
...
}
```

**Note:** Both `apiKey` and `domain` are the required parameters.

🔗 **Need help finding your API key?**

Follow this guide in the [ShortIOSDK README](https://github.com/Short-io/ios-sdk?tab=readme-ov-file#step-1-get-public-api-key-from-shortio).



### 🌐 2. Set Short Link Parameters

In the same file (`ContentView.swift` or `ViewController.swift`), provide your **Short.io domain** and the **original URL** you want to shorten:
Expand All @@ -74,11 +88,11 @@ The app demonstrates:
Using your domain and original URL, you can generate a short link like this:

```swift
let sdk = ShortIOSDK()
let sdk = ShortIOSDK.shared

let parameters = ShortIOParameters(
domain: "your_domain",
originalURL: "https://yourdomain.com"
originalURL: "https://{your_domain}"
)

let apiKey = "your_api_key"
Expand All @@ -98,6 +112,58 @@ Task {
}
```

**⚠️ Note**: Both `apiKey` and `domain` parameters is deprecated. Use the instance's configured API key instead. Call initialize(apiKey:domain:) before using this method

### 🔐 Secure Short Links (Encrypted)

If you want to encrypt the original URL, the SDK provides a `createSecure` function that uses AES-GCM encryption.

#### 🔧 Example

```swift
let sdk = ShortIOSDK.shared

Task {
do {
let result = try sdk.createSecure(originalURL: "your_originalURL_here")
print("result", result.securedOriginalURL, result.securedShortUrl)
} catch {
print("Failed to create secure URL: \(error)")
}
}
```
#### 🧾 Output Format

- **`securedOriginalURL:`** An encrypted URL like `shortsecure://<Base64EncodedData>?<Base64IV>`

- **`securedShortUrl:`** A Base64-encoded decryption key to be appended as a fragment (e.g. `#<key>`)

### 🔄 Conversion Tracking

Track conversions for your short links to measure campaign effectiveness. The SDK provides a simple method to record conversions.

```swift
import ShortIOSDK

let sdk = ShortIOSDK.shared

Task {
do {
let result = try await sdk.trackConversion(
domain: "your_domain", // ⚠️ Deprecated (optional):
clid: "your_clid", // ⚠️ Deprecated (optional):
conversionId: "your_conversionID" (optional)
)
print("result", result)
} catch {
print("Failed to track conversion: \(error)")
}
}
```

**⚠️ Note:** All three parameters — `domain`, `clid`, and `conversionId` — are optional.
- `domain` and `clid` are deprecated and may be removed in future versions.

## 🌐 Handling Universal Links

### SwiftUI Implementation
Expand All @@ -106,8 +172,20 @@ Use the `.onOpenURL` modifier to process incoming links:

```swift
.onOpenURL { url in
print("url", url)
sdk.handleOpen(url) { result in
print("Navigated to path: \(result?.path ?? "")")
switch result {
case .success(let result):
// Handle successful URL processing
print(
"Original URL: \(result.url)",
"Host: \(result.host), Path: \(result.path)",
"QueryParams: \(result.queryItems)"
)
case .failure(let error):
// Handle error with proper error type
print("Error: \(error.localizedDescription)")
}
}
}
```
Expand All @@ -123,8 +201,19 @@ func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
print("Invalid universal link or URL components")
return
}
sdk.handleOpen(incomingURL) { result in
print("Host: \(result?.host), Path: \(result?.path)")
sdk.handleOpen(incomingURL) { result in
switch result {
case .success(let result):
// Handle successful URL processing
print(
"Original URL: \(result.url)",
"Host: \(result.host), Path: \(result.path)",
"QueryParams: \(result.queryItems)"
)
case .failure(let error):
// Handle error with proper error type
print("Error: \(error.localizedDescription)")
}
}
}
```
Expand Down
6 changes: 6 additions & 0 deletions StoryboardProject/ShortIOApp/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import UIKit
import ShortIOSDK

@main
class AppDelegate: UIResponder, UIApplicationDelegate {



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

let sdk = ShortIOSDK.shared

sdk.initialize(apiKey: "your_api_key_here", domain: "your_domain_here")

// Override point for customization after application launch.
return true
}
Expand Down
13 changes: 10 additions & 3 deletions StoryboardProject/ShortIOApp/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import ShortIOSDK
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?
private let sdk = ShortIOSDK()
private let sdk = ShortIOSDK.shared


func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
Expand All @@ -21,7 +21,14 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
return
}
sdk.handleOpen(incomingURL) { result in
print("Host: \(result?.host), Path: \(result?.path)")
switch result {
case .success(let result):
// Handle successful URL processing
print("result", result, "Host: \(result.host), Path: \(result.path)", "QueryParams: \(result.queryItems)")
case .failure(let error):
// Handle error with proper error type
print("Error: \(error.localizedDescription)")
}
}
}

Expand Down
Loading