@@ -10,21 +10,83 @@ import Foundation
1010// MARK: - ConnectivityMethod
1111
1212public extension NetworkConnectivityKit {
13+ /// Represents a method for testing network connectivity to a specific endpoint.
14+ ///
15+ /// A connectivity method encapsulates:
16+ /// - The target URL request
17+ /// - Validation logic for determining success
18+ /// - Configuration settings for the network request
19+ ///
20+ /// ## Example
21+ /// ```swift
22+ /// // Create a custom connectivity method
23+ /// let method = ConnectivityMethod(
24+ /// url: URL(string: "https://example.com/ping")!,
25+ /// validation: .generate200Validation
26+ /// )
27+ /// ```
1328 struct ConnectivityMethod : Sendable {
29+ /// The URL request to be performed for connectivity testing.
1430 public let urlRequest : URLRequest
31+
32+ /// The validation logic used to determine if the response indicates successful connectivity.
1533 public let validation : ConnectivityValidation
34+
35+ /// The configuration settings for the underlying URLSession.
1636 public let configuration : ConnectivityConfiguration
1737
38+ /// Creates a connectivity method with a custom URL request.
39+ ///
40+ /// - Parameters:
41+ /// - urlRequest: The URL request to perform
42+ /// - validation: The validation logic for the response
43+ /// - configuration: The URLSession configuration (defaults to `.default`)
1844 public init ( urlRequest: URLRequest , validation: ConnectivityValidation , configuration: ConnectivityConfiguration = . default) {
1945 self . urlRequest = urlRequest
2046 self . validation = validation
2147 self . configuration = configuration
2248 }
2349
50+ /// Creates a connectivity method with a URL.
51+ ///
52+ /// - Parameters:
53+ /// - url: The target URL for connectivity testing
54+ /// - validation: The validation logic for the response
55+ /// - configuration: The URLSession configuration (defaults to `.default`)
2456 public init ( url: URL , validation: ConnectivityValidation , configuration: ConnectivityConfiguration = . default) {
2557 self . init ( urlRequest: URLRequest ( url: url, configuration: configuration) , validation: validation, configuration: configuration)
2658 }
2759
60+ /// Creates a connectivity method with a static URL string.
61+ ///
62+ /// This initializer is designed for compile-time URL strings that are guaranteed to be valid.
63+ /// It provides better safety and eliminates the need for optional handling when working with
64+ /// hardcoded URLs like built-in connectivity endpoints.
65+ ///
66+ /// - Parameters:
67+ /// - staticURLString: The static URL string for connectivity testing (must be valid at compile time)
68+ /// - validation: The validation logic for the response
69+ /// - configuration: The URLSession configuration (defaults to `.default`)
70+ ///
71+ /// ## Example
72+ /// ```swift
73+ /// let method = ConnectivityMethod(
74+ /// staticURLString: "http://www.gstatic.com/generate_204",
75+ /// validation: .generate204Validation
76+ /// )
77+ /// ```
78+ public init ( staticURLString: StaticString , validation: ConnectivityValidation , configuration: ConnectivityConfiguration = . default) {
79+ let url = URL ( staticString: staticURLString)
80+ self . init ( url: url, validation: validation, configuration: configuration)
81+ }
82+
83+ /// Creates a connectivity method with a URL string.
84+ ///
85+ /// - Parameters:
86+ /// - urlString: The target URL string for connectivity testing
87+ /// - validation: The validation logic for the response
88+ /// - configuration: The URLSession configuration (defaults to `.default`)
89+ /// - Returns: A new connectivity method, or `nil` if the URL string is invalid
2890 public init ? ( urlString: String , validation: ConnectivityValidation , configuration: ConnectivityConfiguration = . default) {
2991 guard let url = URL ( string: urlString) else {
3092 return nil
@@ -39,24 +101,79 @@ public extension NetworkConnectivityKit {
39101// refer: https://en.wikipedia.org/wiki/Captive_portal
40102
41103public extension NetworkConnectivityKit . ConnectivityMethod {
42- static let appleCaptive = Self ( urlString: " http://captive.apple.com " , validation: . generate200Validation)
43-
44- static let appleLibrary = Self ( urlString: " http://www.apple.com/library/test/success.html " , validation: . generate200Validation)
45-
46- static let googleGstatic = Self ( urlString: " http://www.gstatic.com/generate_204 " , validation: . generate204Validation)
47-
48- static let cloudflare = Self ( urlString: " http://cp.cloudflare.com/generate_204 " , validation: . generate204Validation)
49-
50- static let microsoft = Self ( urlString: " http://www.msftconnecttest.com/connecttest.txt " , validation: . generate200Validation)
51-
52- static let vivoWifi = Self ( urlString: " http://wifi.vivo.com.cn/generate_204 " , validation: . generate204Validation)
53-
54- static let miuiConnect = Self ( urlString: " http://connect.rom.miui.com/generate_204 " , validation: . generate204Validation)
104+ /// Apple's captive portal detection endpoint.
105+ ///
106+ /// This endpoint is used by Apple devices to detect captive portals and network connectivity.
107+ /// It expects a 200 status code with specific content for successful connectivity.
108+ ///
109+ /// **URL**: `http://captive.apple.com`
110+ /// **Expected Response**: HTTP 200 with "Success" content
111+ static let appleCaptive = Self ( staticURLString: " http://captive.apple.com " , validation: . generate200Validation)
112+
113+ /// Apple's library test endpoint for connectivity verification.
114+ ///
115+ /// This is an alternative Apple endpoint that provides a reliable connectivity test
116+ /// with a simple success page response.
117+ ///
118+ /// **URL**: `http://www.apple.com/library/test/success.html`
119+ /// **Expected Response**: HTTP 200 status code
120+ static let appleLibrary = Self ( staticURLString: " http://www.apple.com/library/test/success.html " , validation: . generate200Validation)
121+
122+ /// Google's lightweight connectivity check endpoint.
123+ ///
124+ /// This endpoint returns a 204 (No Content) status code for successful connectivity
125+ /// and is widely used for network connectivity testing due to its minimal response size.
126+ ///
127+ /// **URL**: `http://www.gstatic.com/generate_204`
128+ /// **Expected Response**: HTTP 204 (No Content)
129+ static let googleGstatic = Self ( staticURLString: " http://www.gstatic.com/generate_204 " , validation: . generate204Validation)
130+
131+ /// Cloudflare's connectivity check endpoint.
132+ ///
133+ /// Cloudflare provides this endpoint specifically for captive portal detection
134+ /// and connectivity verification with a 204 response.
135+ ///
136+ /// **URL**: `http://cp.cloudflare.com/generate_204`
137+ /// **Expected Response**: HTTP 204 (No Content)
138+ static let cloudflare = Self ( staticURLString: " http://cp.cloudflare.com/generate_204 " , validation: . generate204Validation)
139+
140+ /// Microsoft's connectivity test endpoint.
141+ ///
142+ /// This endpoint is used by Microsoft systems for network connectivity verification
143+ /// and returns a simple text response.
144+ ///
145+ /// **URL**: `http://www.msftconnecttest.com/connecttest.txt`
146+ /// **Expected Response**: HTTP 200 status code
147+ static let microsoft = Self ( staticURLString: " http://www.msftconnecttest.com/connecttest.txt " , validation: . generate200Validation)
148+
149+ /// Vivo WiFi connectivity check endpoint.
150+ ///
151+ /// This endpoint is commonly used in networks with Vivo devices and provides
152+ /// reliable connectivity testing in those environments.
153+ ///
154+ /// **URL**: `http://wifi.vivo.com.cn/generate_204`
155+ /// **Expected Response**: HTTP 204 (No Content)
156+ static let vivoWifi = Self ( staticURLString: " http://wifi.vivo.com.cn/generate_204 " , validation: . generate204Validation)
157+
158+ /// MIUI (Xiaomi) connectivity check endpoint.
159+ ///
160+ /// This endpoint is used by MIUI systems for network connectivity verification
161+ /// and captive portal detection.
162+ ///
163+ /// **URL**: `http://connect.rom.miui.com/generate_204`
164+ /// **Expected Response**: HTTP 204 (No Content)
165+ static let miuiConnect = Self ( staticURLString: " http://connect.rom.miui.com/generate_204 " , validation: . generate204Validation)
55166}
56167
57168// MARK: - Perform Request
58169
59170extension NetworkConnectivityKit . ConnectivityMethod {
171+ /// Performs the connectivity check request and validates the response.
172+ ///
173+ /// This method executes the network request using the configured URLSession
174+ /// and applies the validation logic to determine connectivity success.
175+ ///
176+ /// - Returns: `true` if the request succeeds and passes validation, `false` otherwise
60177 func performRequest( ) async -> Bool {
61178 do {
62179 let response = try await configuration. urlSession. data ( for: urlRequest)
@@ -82,6 +199,8 @@ extension NetworkConnectivityKit.ConnectivityMethod: Hashable, Equatable {
82199 }
83200}
84201
202+ // MARK: - URLRequest Extension
203+
85204private extension URLRequest {
86205 init ( url: URL , configuration: NetworkConnectivityKit . ConnectivityConfiguration ) {
87206 let configuration = configuration. urlSession. configuration
@@ -92,3 +211,21 @@ private extension URLRequest {
92211 self = request
93212 }
94213}
214+
215+ // MARK: - URL Extension for StaticString
216+
217+ extension URL {
218+ /// Creates a URL from a static string, providing compile-time safety for hardcoded URLs.
219+ ///
220+ /// This initializer is designed for cases where the URL string is known at compile time
221+ /// and should always be valid. If the static string cannot be converted to a valid URL,
222+ /// the application will terminate with a fatal error, helping catch invalid URLs early.
223+ ///
224+ /// - Parameter staticString: A static string containing a valid URL
225+ init ( staticString: StaticString ) {
226+ guard let url = Self ( string: " \( staticString) " ) else {
227+ fatalError ( " Invalid static URL string: \( staticString) " )
228+ }
229+ self = url
230+ }
231+ }
0 commit comments