Skip to content

Commit c208246

Browse files
author
deepone
committed
Add Documentation
1 parent 5799cf2 commit c208246

File tree

5 files changed

+116
-4
lines changed

5 files changed

+116
-4
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# OS X
22
.DS_Store
3+
__MACOSX
34
# Xcode
45
#
56
build/
@@ -32,4 +33,4 @@ Pods/
3233
Podfile.lock
3334

3435
# SwiftPM
35-
.build
36+
.build

DeepOneSDK/DeepOne.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,24 @@ import UIKit
77
import Cocoa
88
#endif
99

10+
/// DeepOne provides comprehensive deep linking and deferred deep linking capabilities for iOS and macOS applications.
11+
/// This modern SDK offers attribution tracking, link generation, and seamless user experience management.
1012
@objcMembers
1113
public class DeepOne: NSObject {
1214

15+
// MARK: - Attribution Parameters
16+
/// Parameter keys for routing and attribution information (Objective-C compatible)
1317
@objc public static let AttributionParameterOriginURL = "origin_url"
1418
@objc public static let AttributionParameterRoutePath = "route_path"
1519
@objc public static let AttributionParameterQueryParameters = "query_params"
1620
@objc public static let AttributionParameterIsFirstSession = "is_first_session"
1721
@objc public static let AttributionParameterAttributionData = "attribution_data"
1822

23+
// MARK: - Error Constants
24+
/// Error domain for DeepOne operations
1925
@objc public static let DeepOneErrorDomain = "DeepOneErrorDomain"
2026

27+
/// Error codes for DeepOne operations
2128
@objc public enum DeepOneErrorCode: Int {
2229
case invalidConfiguration = 1001
2330
case networkError = 1002
@@ -26,20 +33,26 @@ public class DeepOne: NSObject {
2633
case missingCredentials = 1005
2734
}
2835

36+
// MARK: - Type Aliases
37+
/// Handler for processing incoming deep link attribution with type-safe data model
2938
public typealias AttributionHandler = (_ attributionData: DeepOneAttributionData?, _ error: NSError?) -> Void
3039

40+
// MARK: - Singleton Instance
3141
public static let shared = DeepOne()
3242

43+
// MARK: - Properties
3344
private var isDevelopmentMode = false
3445
private var attributionHandler: AttributionHandler?
3546

47+
/// API credentials for link verification and generation
3648
private var apiKey: String? {
3749
guard
3850
let keys = Bundle.main.object(forInfoDictionaryKey: "DeepOne.keys") as? [String: Any],
3951
let key = keys[isDevelopmentMode ? "test" : "live"] as? String else { return nil }
4052
return key
4153
}
4254

55+
/// Tracks if this is the first session ever (persists across reinstalls via keychain)
4356
private var isFirstSession: Bool {
4457
didSet {
4558
if !isFirstSession {
@@ -59,19 +72,36 @@ public class DeepOne: NSObject {
5972
}
6073

6174
#if canImport(UIKit)
75+
/// Configures the DeepOne SDK with application launch context and attribution handling.
76+
///
77+
/// - Parameters:
78+
/// - launchOptions: The launch options from the application delegate
79+
/// - developmentMode: Enable development mode for testing. Default is `false`.
80+
/// - attributionHandler: Closure to handle incoming attribution data
6281
public func configure(launchOptions: [UIApplication.LaunchOptionsKey: Any]?,
6382
developmentMode: Bool = false,
6483
attributionHandler: AttributionHandler?) {
6584
_configure(developmentMode: developmentMode, attributionHandler: attributionHandler)
6685
}
6786
#elseif canImport(Cocoa)
87+
/// Configures the DeepOne SDK with macOS application context and attribution handling.
88+
///
89+
/// - Parameters:
90+
/// - notification: The application launch notification
91+
/// - developmentMode: Enable development mode for testing. Default is `false`.
92+
/// - attributionHandler: Closure to handle incoming attribution data
6893
public func configure(notification: Notification,
6994
developmentMode: Bool = false,
7095
attributionHandler: AttributionHandler?) {
7196
_configure(developmentMode: developmentMode, attributionHandler: attributionHandler)
7297
}
7398
#endif
7499

100+
/// Creates a new attributed link with the specified configuration
101+
///
102+
/// - Parameters:
103+
/// - configuration: Link configuration containing routing and attribution parameters
104+
/// - completion: Completion handler with the generated URL or error
75105
@objc public func createAttributedLink(configuration: DeepOneCreateLinkBuilder, completion: @escaping (URL?, NSError?) -> Void) {
76106
guard let parameters = configuration.buildParameters() else {
77107
let error = NSError(domain: DeepOne.DeepOneErrorDomain,
@@ -110,6 +140,10 @@ public class DeepOne: NSObject {
110140
}
111141
}
112142

143+
/// Processes universal link user activity for attribution
144+
///
145+
/// - Parameter activity: The NSUserActivity from universal link handling
146+
/// - Returns: Boolean indicating successful attribution processing
113147
@objc(continueUserActivity:)
114148
@discardableResult public func processUniversalLink(_ activity: NSUserActivity) -> Bool {
115149
guard
@@ -118,10 +152,15 @@ public class DeepOne: NSObject {
118152
return processAttributionData(from: url)
119153
}
120154

155+
/// Clears all persisted attribution data (resets first session tracking)
121156
@objc public func clearAttributionData() {
122157
DeepOneCoreAPI.deleteKeychainData(key: "first_session_marker")
123158
}
124159

160+
/// Processes an incoming URL for attribution tracking
161+
///
162+
/// - Parameter url: The URL to process for attribution
163+
/// - Returns: Boolean indicating successful processing
125164
@objc @discardableResult
126165
public func trackAttributionURL(_ url: URL) -> Bool {
127166
return processAttributionData(from: url)
@@ -181,6 +220,7 @@ public class DeepOne: NSObject {
181220
}
182221
}
183222

223+
/// Extracts marketing attribution parameters from query parameters
184224
private func extractMarketingAttribution(from queryParams: [String: Any]) -> [String: Any] {
185225
var marketingData = [String: Any]()
186226

@@ -205,9 +245,12 @@ public class DeepOne: NSObject {
205245
}
206246
}
207247

248+
// MARK: - Swift Convenience Methods
249+
208250
#if swift(>=5.5)
209251
extension DeepOne {
210252

253+
/// Swift-specific link creation with Result type and async/await
211254
@available(iOS 13.0, macOS 10.15, *)
212255
public func createAttributedLink(configuration: DeepOneCreateLinkBuilder) async -> Result<URL, DeepOneSwiftError> {
213256
return await withCheckedContinuation { continuation in
@@ -224,6 +267,7 @@ extension DeepOne {
224267
}
225268
}
226269

270+
/// Swift-specific error enum for modern error handling
227271
public enum DeepOneSwiftError: Error, LocalizedError {
228272
case invalidConfiguration
229273
case networkError(Error)

DeepOneSDK/DeepOneAttributionData.swift

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,66 @@
11
import Foundation
22

3+
/// Attribution data model providing type-safe access to attribution information
34
@objcMembers
45
public class DeepOneAttributionData: NSObject {
56

7+
// MARK: - Core Attribution Properties
8+
9+
/// The original URL that triggered the attribution
610
public let originURL: String?
711

12+
/// The path component of the attribution URL
813
public let routePath: String?
914

15+
/// Whether this is the user's first session ever (persists across app reinstalls)
1016
public let isFirstSession: Bool
1117

18+
/// All query parameters from the attribution URL
1219
public let queryParameters: [String: String]
1320

21+
// MARK: - Marketing Attribution Properties
22+
23+
/// UTM source parameter
1424
public let marketingSource: String?
1525

26+
/// UTM medium parameter
1627
public let marketingMedium: String?
1728

29+
/// UTM campaign parameter
1830
public let marketingCampaign: String?
1931

32+
/// UTM term parameter
2033
public let marketingTerm: String?
2134

35+
/// UTM content parameter
2236
public let marketingContent: String?
2337

38+
/// Custom referrer parameter
2439
public let referrer: String?
2540

41+
/// Campaign identifier
2642
public let campaignIdentifier: String?
27-
43+
44+
// MARK: - Additional Properties
45+
46+
/// Raw attribution data dictionary (for custom parameters)
2847
public let rawData: [String: Any]
29-
48+
49+
// MARK: - Initialization
50+
51+
/// Internal initializer from dictionary data
3052
internal init(from dictionary: [String: Any]) {
3153
self.rawData = dictionary
3254

55+
// Core attribution data
3356
self.originURL = dictionary[DeepOne.AttributionParameterOriginURL] as? String
3457
self.routePath = dictionary[DeepOne.AttributionParameterRoutePath] as? String
3558
self.isFirstSession = (dictionary[DeepOne.AttributionParameterIsFirstSession] as? Bool) ?? false
3659

60+
// Query parameters
3761
self.queryParameters = (dictionary[DeepOne.AttributionParameterQueryParameters] as? [String: String]) ?? [:]
3862

63+
// Marketing attribution data
3964
let marketingData = dictionary[DeepOne.AttributionParameterAttributionData] as? [String: Any] ?? [:]
4065

4166
self.marketingSource = marketingData["utm_source"] as? String
@@ -49,22 +74,29 @@ public class DeepOneAttributionData: NSObject {
4974
super.init()
5075
}
5176

77+
// MARK: - Convenience Methods
78+
79+
/// Checks if this attribution contains marketing data
5280
@objc public var hasMarketingData: Bool {
5381
return marketingSource != nil || marketingMedium != nil || marketingCampaign != nil
5482
}
5583

84+
/// Checks if this attribution contains UTM parameters
5685
@objc public var hasUTMParameters: Bool {
5786
return marketingSource != nil || marketingMedium != nil || marketingCampaign != nil || marketingTerm != nil || marketingContent != nil
5887
}
5988

89+
/// Gets a custom parameter value
6090
@objc public func customParameter(for key: String) -> Any? {
6191
return rawData[key]
6292
}
6393

94+
/// Gets a custom string parameter
6495
@objc public func customStringParameter(for key: String) -> String? {
6596
return rawData[key] as? String
6697
}
6798

99+
/// Gets all UTM parameters as a dictionary
68100
@objc public var utmParameters: [String: String] {
69101
var utm: [String: String] = [:]
70102
if let source = marketingSource { utm["utm_source"] = source }
@@ -75,6 +107,8 @@ public class DeepOneAttributionData: NSObject {
75107
return utm
76108
}
77109

110+
// MARK: - Debug Description
111+
78112
public override var description: String {
79113
var components: [String] = []
80114

@@ -99,22 +133,28 @@ public class DeepOneAttributionData: NSObject {
99133
}
100134
}
101135

136+
// MARK: - Swift Convenience Extensions
137+
102138
#if swift(>=5.5)
103139
extension DeepOneAttributionData {
104140

141+
/// URL of the attributed link
105142
public var url: URL? {
106143
guard let originURL = originURL else { return nil }
107144
return URL(string: originURL)
108145
}
109146

147+
/// Checks if the attribution indicates a specific route
110148
public func matches(route: String) -> Bool {
111149
return routePath == route
112150
}
113151

152+
/// Checks if the attribution has a route with a specific prefix
114153
public func hasRoute(withPrefix prefix: String) -> Bool {
115154
return routePath?.hasPrefix(prefix) ?? false
116155
}
117156

157+
/// Extracts an ID from a route path (e.g., "/product/123" -> "123")
118158
public func extractID(fromRoute routePrefix: String) -> String? {
119159
guard let path = routePath, path.hasPrefix(routePrefix) else { return nil }
120160
let idStartIndex = path.index(path.startIndex, offsetBy: routePrefix.count)

DeepOneSDK/DeepOneCreateLinkBuilder.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Foundation
22

3+
/// Configuration builder for creating attributed deep links with marketing parameters
34
@objcMembers
45
public class DeepOneCreateLinkBuilder: NSObject {
56
// MARK: - Core Properties
@@ -19,14 +20,20 @@ public class DeepOneCreateLinkBuilder: NSObject {
1920
var marketingTerm: String?
2021
var marketingContent: String?
2122

23+
// MARK: - Custom Parameters
2224
private var customParameters: [String: Any] = [:]
2325

26+
/// Creates a link builder with basic routing information
27+
/// - Parameters:
28+
/// - destinationPath: The deep link path for routing
29+
/// - linkIdentifier: Unique identifier for this link
2430
public init(destinationPath: String, linkIdentifier: String) {
2531
self.destinationPath = destinationPath
2632
self.linkIdentifier = linkIdentifier
2733
super.init()
2834
}
2935

36+
/// Creates a link builder with comprehensive configuration
3037
public init(destinationPath: String,
3138
linkIdentifier: String,
3239
linkDescription: String? = nil,
@@ -53,13 +60,21 @@ public class DeepOneCreateLinkBuilder: NSObject {
5360
}
5461
}
5562

63+
// MARK: - Builder Methods
64+
5665
extension DeepOneCreateLinkBuilder {
66+
/// Adds a custom parameter to the link configuration
67+
/// - Parameters:
68+
/// - key: Parameter key
69+
/// - value: Parameter value
70+
/// - Returns: Self for method chaining
5771
@objc @discardableResult
5872
public func addCustomParameter(key: String, value: Any) -> Self {
5973
customParameters[key] = value
6074
return self
6175
}
6276

77+
/// Sets social media preview content
6378
@objc @discardableResult
6479
public func setSocialPreview(title: String, description: String, imageURL: String?) -> Self {
6580
socialTitle = title
@@ -68,12 +83,15 @@ extension DeepOneCreateLinkBuilder {
6883
return self
6984
}
7085

86+
/// Sets social media preview content (Objective-C convenience method)
7187
@objc @discardableResult
7288
public func setSocialPreviewWithTitle(_ title: String, description: String) -> Self {
7389
return setSocialPreview(title: title, description: description, imageURL: nil)
7490
}
7591
}
7692

93+
// MARK: - Parameter Building
94+
7795
extension DeepOneCreateLinkBuilder: Encodable {
7896
enum CodingKeys: String, CodingKey {
7997
case destinationPath = "path"
@@ -89,6 +107,8 @@ extension DeepOneCreateLinkBuilder: Encodable {
89107
case marketingContent = "utmContent"
90108
}
91109

110+
/// Builds the parameter dictionary for API submission
111+
/// - Returns: Dictionary containing all link parameters, or nil if invalid
92112
@objc public func buildParameters() -> [String: Any]? {
93113
guard let data = try? JSONEncoder().encode(self) else { return nil }
94114
guard var parameters = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else { return nil }
@@ -101,6 +121,7 @@ extension DeepOneCreateLinkBuilder: Encodable {
101121
return parameters
102122
}
103123

124+
/// Legacy method for backward compatibility
104125
@objc public func toDic() -> [String: Any]? {
105126
return buildParameters()
106127
}

0 commit comments

Comments
 (0)